diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config.h index 4d74313c..82788ddc 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi --extra-cflags='--target=arm-linux-androideabi24' --extra-ldflags='--target=arm-linux-androideabi24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/arm-linux-androideabi --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-neon --extra-cflags='-mtune=generic-armv7-a' --extra-cflags='-mfloat-abi=softfp' --extra-cflags='-mfpu=neon' --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi --extra-cflags='--target=arm-linux-androideabi24' --extra-ldflags='--target=arm-linux-androideabi24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/arm-linux-androideabi --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-neon --extra-cflags='-mtune=generic-armv7-a' --extra-cflags='-mfloat-abi=softfp' --extra-cflags='-mfpu=neon' --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config_components.h index c9dd92c2..8909e9e5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config.h index 335e3e75..e01ac5fb 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android --extra-cflags='--target=aarch64-linux-android24' --extra-ldflags='--target=aarch64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android --extra-cflags='--target=aarch64-linux-android24' --extra-ldflags='--target=aarch64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config_components.h index c9dd92c2..8909e9e5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config.h index 1e6528e4..8a69a5f7 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android --extra-cflags='--target=i686-linux-android24' --extra-ldflags='--target=i686-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/i686-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --disable-x86asm --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android --extra-cflags='--target=i686-linux-android24' --extra-ldflags='--target=i686-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/i686-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --disable-x86asm --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config_components.h index c9dd92c2..8909e9e5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.asm index 513890ea..ad7e53a1 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 0 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 0 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.h index f1bd26d7..43da3605 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/x86_64-linux-android --extra-cflags='--target=x86_64-linux-android24' --extra-ldflags='--target=x86_64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/x86_64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=x86_64 --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/x86_64-linux-android --extra-cflags='--target=x86_64-linux-android24' --extra-ldflags='--target=x86_64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/x86_64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=x86_64 --enable-demuxer=aac --enable-parser=aac --enable-decoder=aac" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config_components.h index c9dd92c2..8909e9e5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/android/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config.h new file mode 100644 index 00000000..08c0435e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config.h @@ -0,0 +1,749 @@ +/* Automatically generated by configure - do not modify! */ +#ifndef FFMPEG_CONFIG_H +#define FFMPEG_CONFIG_H +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +#define FFMPEG_LICENSE "LGPL version 2.1 or later" +#define CONFIG_THIS_YEAR 2023 +#define FFMPEG_DATADIR "/usr/local/share/ffmpeg" +#define AVCONV_DATADIR "/usr/local/share/ffmpeg" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" +#define OS_NAME darwin +#define av_restrict restrict +#define EXTERN_PREFIX "_" +#define EXTERN_ASM _ +#define BUILDSUF "" +#define SLIBSUF ".dylib" +#define HAVE_MMX2 HAVE_MMXEXT +#define SWS_MAX_FILTER_SIZE 256 +#define ARCH_AARCH64 1 +#define ARCH_ALPHA 0 +#define ARCH_ARM 0 +#define ARCH_AVR32 0 +#define ARCH_AVR32_AP 0 +#define ARCH_AVR32_UC 0 +#define ARCH_BFIN 0 +#define ARCH_IA64 0 +#define ARCH_LOONGARCH 0 +#define ARCH_LOONGARCH32 0 +#define ARCH_LOONGARCH64 0 +#define ARCH_M68K 0 +#define ARCH_MIPS 0 +#define ARCH_MIPS64 0 +#define ARCH_PARISC 0 +#define ARCH_PPC 0 +#define ARCH_PPC64 0 +#define ARCH_RISCV 0 +#define ARCH_S390 0 +#define ARCH_SH4 0 +#define ARCH_SPARC 0 +#define ARCH_SPARC64 0 +#define ARCH_TILEGX 0 +#define ARCH_TILEPRO 0 +#define ARCH_TOMI 0 +#define ARCH_X86 0 +#define ARCH_X86_32 0 +#define ARCH_X86_64 0 +#define HAVE_ARMV5TE 0 +#define HAVE_ARMV6 0 +#define HAVE_ARMV6T2 0 +#define HAVE_ARMV8 1 +#define HAVE_NEON 1 +#define HAVE_VFP 1 +#define HAVE_VFPV3 0 +#define HAVE_SETEND 0 +#define HAVE_ALTIVEC 0 +#define HAVE_DCBZL 0 +#define HAVE_LDBRX 0 +#define HAVE_POWER8 0 +#define HAVE_PPC4XX 0 +#define HAVE_VSX 0 +#define HAVE_RVV 0 +#define HAVE_AESNI 0 +#define HAVE_AMD3DNOW 0 +#define HAVE_AMD3DNOWEXT 0 +#define HAVE_AVX 0 +#define HAVE_AVX2 0 +#define HAVE_AVX512 0 +#define HAVE_AVX512ICL 0 +#define HAVE_FMA3 0 +#define HAVE_FMA4 0 +#define HAVE_MMX 0 +#define HAVE_MMXEXT 0 +#define HAVE_SSE 0 +#define HAVE_SSE2 0 +#define HAVE_SSE3 0 +#define HAVE_SSE4 0 +#define HAVE_SSE42 0 +#define HAVE_SSSE3 0 +#define HAVE_XOP 0 +#define HAVE_CPUNOP 0 +#define HAVE_I686 0 +#define HAVE_MIPSFPU 0 +#define HAVE_MIPS32R2 0 +#define HAVE_MIPS32R5 0 +#define HAVE_MIPS64R2 0 +#define HAVE_MIPS32R6 0 +#define HAVE_MIPS64R6 0 +#define HAVE_MIPSDSP 0 +#define HAVE_MIPSDSPR2 0 +#define HAVE_MSA 0 +#define HAVE_LOONGSON2 0 +#define HAVE_LOONGSON3 0 +#define HAVE_MMI 0 +#define HAVE_LSX 0 +#define HAVE_LASX 0 +#define HAVE_ARMV5TE_EXTERNAL 0 +#define HAVE_ARMV6_EXTERNAL 0 +#define HAVE_ARMV6T2_EXTERNAL 0 +#define HAVE_ARMV8_EXTERNAL 1 +#define HAVE_NEON_EXTERNAL 1 +#define HAVE_VFP_EXTERNAL 1 +#define HAVE_VFPV3_EXTERNAL 0 +#define HAVE_SETEND_EXTERNAL 0 +#define HAVE_ALTIVEC_EXTERNAL 0 +#define HAVE_DCBZL_EXTERNAL 0 +#define HAVE_LDBRX_EXTERNAL 0 +#define HAVE_POWER8_EXTERNAL 0 +#define HAVE_PPC4XX_EXTERNAL 0 +#define HAVE_VSX_EXTERNAL 0 +#define HAVE_RVV_EXTERNAL 0 +#define HAVE_AESNI_EXTERNAL 0 +#define HAVE_AMD3DNOW_EXTERNAL 0 +#define HAVE_AMD3DNOWEXT_EXTERNAL 0 +#define HAVE_AVX_EXTERNAL 0 +#define HAVE_AVX2_EXTERNAL 0 +#define HAVE_AVX512_EXTERNAL 0 +#define HAVE_AVX512ICL_EXTERNAL 0 +#define HAVE_FMA3_EXTERNAL 0 +#define HAVE_FMA4_EXTERNAL 0 +#define HAVE_MMX_EXTERNAL 0 +#define HAVE_MMXEXT_EXTERNAL 0 +#define HAVE_SSE_EXTERNAL 0 +#define HAVE_SSE2_EXTERNAL 0 +#define HAVE_SSE3_EXTERNAL 0 +#define HAVE_SSE4_EXTERNAL 0 +#define HAVE_SSE42_EXTERNAL 0 +#define HAVE_SSSE3_EXTERNAL 0 +#define HAVE_XOP_EXTERNAL 0 +#define HAVE_CPUNOP_EXTERNAL 0 +#define HAVE_I686_EXTERNAL 0 +#define HAVE_MIPSFPU_EXTERNAL 0 +#define HAVE_MIPS32R2_EXTERNAL 0 +#define HAVE_MIPS32R5_EXTERNAL 0 +#define HAVE_MIPS64R2_EXTERNAL 0 +#define HAVE_MIPS32R6_EXTERNAL 0 +#define HAVE_MIPS64R6_EXTERNAL 0 +#define HAVE_MIPSDSP_EXTERNAL 0 +#define HAVE_MIPSDSPR2_EXTERNAL 0 +#define HAVE_MSA_EXTERNAL 0 +#define HAVE_LOONGSON2_EXTERNAL 0 +#define HAVE_LOONGSON3_EXTERNAL 0 +#define HAVE_MMI_EXTERNAL 0 +#define HAVE_LSX_EXTERNAL 0 +#define HAVE_LASX_EXTERNAL 0 +#define HAVE_ARMV5TE_INLINE 0 +#define HAVE_ARMV6_INLINE 0 +#define HAVE_ARMV6T2_INLINE 0 +#define HAVE_ARMV8_INLINE 1 +#define HAVE_NEON_INLINE 1 +#define HAVE_VFP_INLINE 1 +#define HAVE_VFPV3_INLINE 0 +#define HAVE_SETEND_INLINE 0 +#define HAVE_ALTIVEC_INLINE 0 +#define HAVE_DCBZL_INLINE 0 +#define HAVE_LDBRX_INLINE 0 +#define HAVE_POWER8_INLINE 0 +#define HAVE_PPC4XX_INLINE 0 +#define HAVE_VSX_INLINE 0 +#define HAVE_RVV_INLINE 0 +#define HAVE_AESNI_INLINE 0 +#define HAVE_AMD3DNOW_INLINE 0 +#define HAVE_AMD3DNOWEXT_INLINE 0 +#define HAVE_AVX_INLINE 0 +#define HAVE_AVX2_INLINE 0 +#define HAVE_AVX512_INLINE 0 +#define HAVE_AVX512ICL_INLINE 0 +#define HAVE_FMA3_INLINE 0 +#define HAVE_FMA4_INLINE 0 +#define HAVE_MMX_INLINE 0 +#define HAVE_MMXEXT_INLINE 0 +#define HAVE_SSE_INLINE 0 +#define HAVE_SSE2_INLINE 0 +#define HAVE_SSE3_INLINE 0 +#define HAVE_SSE4_INLINE 0 +#define HAVE_SSE42_INLINE 0 +#define HAVE_SSSE3_INLINE 0 +#define HAVE_XOP_INLINE 0 +#define HAVE_CPUNOP_INLINE 0 +#define HAVE_I686_INLINE 0 +#define HAVE_MIPSFPU_INLINE 0 +#define HAVE_MIPS32R2_INLINE 0 +#define HAVE_MIPS32R5_INLINE 0 +#define HAVE_MIPS64R2_INLINE 0 +#define HAVE_MIPS32R6_INLINE 0 +#define HAVE_MIPS64R6_INLINE 0 +#define HAVE_MIPSDSP_INLINE 0 +#define HAVE_MIPSDSPR2_INLINE 0 +#define HAVE_MSA_INLINE 0 +#define HAVE_LOONGSON2_INLINE 0 +#define HAVE_LOONGSON3_INLINE 0 +#define HAVE_MMI_INLINE 0 +#define HAVE_LSX_INLINE 0 +#define HAVE_LASX_INLINE 0 +#define HAVE_ALIGNED_STACK 1 +#define HAVE_FAST_64BIT 1 +#define HAVE_FAST_CLZ 1 +#define HAVE_FAST_CMOV 0 +#define HAVE_FAST_FLOAT16 1 +#define HAVE_LOCAL_ALIGNED 0 +#define HAVE_SIMD_ALIGN_16 1 +#define HAVE_SIMD_ALIGN_32 0 +#define HAVE_SIMD_ALIGN_64 0 +#define HAVE_ATOMIC_CAS_PTR 0 +#define HAVE_MACHINE_RW_BARRIER 0 +#define HAVE_MEMORYBARRIER 0 +#define HAVE_MM_EMPTY 0 +#define HAVE_RDTSC 0 +#define HAVE_SEM_TIMEDWAIT 0 +#define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 +#define HAVE_INLINE_ASM 1 +#define HAVE_SYMVER 0 +#define HAVE_X86ASM 0 +#define HAVE_BIGENDIAN 0 +#define HAVE_FAST_UNALIGNED 1 +#define HAVE_ARPA_INET_H 0 +#define HAVE_ASM_TYPES_H 0 +#define HAVE_CDIO_PARANOIA_H 0 +#define HAVE_CDIO_PARANOIA_PARANOIA_H 0 +#define HAVE_CUDA_H 0 +#define HAVE_DISPATCH_DISPATCH_H 1 +#define HAVE_DEV_BKTR_IOCTL_BT848_H 0 +#define HAVE_DEV_BKTR_IOCTL_METEOR_H 0 +#define HAVE_DEV_IC_BT8XX_H 0 +#define HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H 0 +#define HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H 0 +#define HAVE_DIRECT_H 0 +#define HAVE_DIRENT_H 1 +#define HAVE_DXGIDEBUG_H 0 +#define HAVE_DXVA_H 0 +#define HAVE_ES2_GL_H 0 +#define HAVE_GSM_H 0 +#define HAVE_IO_H 0 +#define HAVE_LINUX_DMA_BUF_H 0 +#define HAVE_LINUX_PERF_EVENT_H 0 +#define HAVE_MACHINE_IOCTL_BT848_H 0 +#define HAVE_MACHINE_IOCTL_METEOR_H 0 +#define HAVE_MALLOC_H 0 +#define HAVE_OPENCV2_CORE_CORE_C_H 0 +#define HAVE_OPENGL_GL3_H 0 +#define HAVE_POLL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_RESOURCE_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_SOUNDCARD_H 0 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_UN_H 1 +#define HAVE_SYS_VIDEOIO_H 0 +#define HAVE_TERMIOS_H 1 +#define HAVE_UDPLITE_H 0 +#define HAVE_UNISTD_H 1 +#define HAVE_VALGRIND_VALGRIND_H 0 /* #define HAVE_VALGRIND_VALGRIND_H 0 -- forced to 0. See https://crbug.com/590440 */ +#define HAVE_WINDOWS_H 0 +#define HAVE_WINSOCK2_H 0 +#define HAVE_INTRINSICS_NEON 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CBRT 1 +#define HAVE_CBRTF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_ERF 1 +#define HAVE_EXP2 1 +#define HAVE_EXP2F 1 +#define HAVE_EXPF 1 +#define HAVE_HYPOT 1 +#define HAVE_ISFINITE 1 +#define HAVE_ISINF 1 +#define HAVE_ISNAN 1 +#define HAVE_LDEXPF 1 +#define HAVE_LLRINT 1 +#define HAVE_LLRINTF 1 +#define HAVE_LOG2 1 +#define HAVE_LOG2F 1 +#define HAVE_LOG10F 1 +#define HAVE_LRINT 1 +#define HAVE_LRINTF 1 +#define HAVE_POWF 1 +#define HAVE_RINT 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SINF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_DOS_PATHS 0 +#define HAVE_LIBC_MSVCRT 0 +#define HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS 0 +#define HAVE_SECTION_DATA_REL_RO 0 +#define HAVE_THREADS 1 +#define HAVE_UWP 0 +#define HAVE_WINRT 0 +#define HAVE_ACCESS 1 +#define HAVE_ALIGNED_MALLOC 0 +#define HAVE_ARC4RANDOM 1 +#define HAVE_CLOCK_GETTIME 0 +#define HAVE_CLOSESOCKET 0 +#define HAVE_COMMANDLINETOARGVW 0 +#define HAVE_FCNTL 1 +#define HAVE_GETADDRINFO 0 +#define HAVE_GETAUXVAL 0 +#define HAVE_GETENV 1 +#define HAVE_GETHRTIME 0 +#define HAVE_GETOPT 1 +#define HAVE_GETMODULEHANDLE 0 +#define HAVE_GETPROCESSAFFINITYMASK 0 +#define HAVE_GETPROCESSMEMORYINFO 0 +#define HAVE_GETPROCESSTIMES 0 +#define HAVE_GETRUSAGE 1 +#define HAVE_GETSTDHANDLE 0 +#define HAVE_GETSYSTEMTIMEASFILETIME 0 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GLOB 1 +#define HAVE_GLXGETPROCADDRESS 0 +#define HAVE_GMTIME_R 1 +#define HAVE_INET_ATON 0 +#define HAVE_ISATTY 1 +#define HAVE_KBHIT 0 +#define HAVE_LOCALTIME_R 1 +#define HAVE_LSTAT 1 +#define HAVE_LZO1X_999_COMPRESS 0 +#define HAVE_MACH_ABSOLUTE_TIME 1 +#define HAVE_MAPVIEWOFFILE 0 +#define HAVE_MEMALIGN 0 +#define HAVE_MKSTEMP 1 +#define HAVE_MMAP 1 +#define HAVE_MPROTECT 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_PEEKNAMEDPIPE 0 +#define HAVE_POSIX_MEMALIGN 1 +#define HAVE_PRCTL 0 +#define HAVE_PTHREAD_CANCEL 1 +#define HAVE_SCHED_GETAFFINITY 0 +#define HAVE_SECITEMIMPORT 0 +#define HAVE_SETCONSOLETEXTATTRIBUTE 0 +#define HAVE_SETCONSOLECTRLHANDLER 0 +#define HAVE_SETDLLDIRECTORY 0 +#define HAVE_SETMODE 0 +#define HAVE_SETRLIMIT 1 +#define HAVE_SLEEP 0 +#define HAVE_STRERROR_R 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTL 1 +#define HAVE_USLEEP 1 +#define HAVE_UTGETOSTYPEFROMSTRING 0 +#define HAVE_VIRTUALALLOC 0 +#define HAVE_WGLGETPROCADDRESS 0 +#define HAVE_BCRYPT 0 +#define HAVE_VAAPI_DRM 0 +#define HAVE_VAAPI_X11 0 +#define HAVE_VDPAU_X11 0 +#define HAVE_PTHREADS 1 +#define HAVE_OS2THREADS 0 +#define HAVE_W32THREADS 0 +#define HAVE_AS_ARCH_DIRECTIVE 0 +#define HAVE_AS_DN_DIRECTIVE 0 +#define HAVE_AS_FPU_DIRECTIVE 0 +#define HAVE_AS_FUNC 0 +#define HAVE_AS_OBJECT_ARCH 0 +#define HAVE_ASM_MOD_Q 0 +#define HAVE_BLOCKS_EXTENSION 1 +#define HAVE_EBP_AVAILABLE 0 +#define HAVE_EBX_AVAILABLE 0 +#define HAVE_GNU_AS 0 +#define HAVE_GNU_WINDRES 0 +#define HAVE_IBM_ASM 0 +#define HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS 0 +#define HAVE_INLINE_ASM_LABELS 1 +#define HAVE_INLINE_ASM_NONLOCAL_LABELS 1 +#define HAVE_PRAGMA_DEPRECATED 1 +#define HAVE_RSYNC_CONTIMEOUT 1 +#define HAVE_SYMVER_ASM_LABEL 0 +#define HAVE_SYMVER_GNU_ASM 0 +/* #define HAVE_VFP_ARGS 0 -- softfp/hardfp selection is done by the chrome build */ +#define HAVE_XFORM_ASM 0 +#define HAVE_XMM_CLOBBERS 0 +#define HAVE_DPI_AWARENESS_CONTEXT 0 +#define HAVE_IDXGIOUTPUT5 0 +#define HAVE_KCMVIDEOCODECTYPE_HEVC 0 +#define HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA 0 +#define HAVE_KCMVIDEOCODECTYPE_VP9 0 +#define HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR 0 +#define HAVE_KCVIMAGEBUFFERYCBCRMATRIX_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERCOLORPRIMARIES_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_428_1 0 +#define HAVE_SOCKLEN_T 0 +#define HAVE_STRUCT_ADDRINFO 0 +#define HAVE_STRUCT_GROUP_SOURCE_REQ 0 +#define HAVE_STRUCT_IP_MREQ_SOURCE 0 +#define HAVE_STRUCT_IPV6_MREQ 0 +#define HAVE_STRUCT_MSGHDR_MSG_FLAGS 0 +#define HAVE_STRUCT_POLLFD 0 +#define HAVE_STRUCT_RUSAGE_RU_MAXRSS 1 +#define HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE 0 +#define HAVE_STRUCT_SOCKADDR_IN6 0 +#define HAVE_STRUCT_SOCKADDR_SA_LEN 0 +#define HAVE_STRUCT_SOCKADDR_STORAGE 0 +#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 0 +#define HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE 0 +#define HAVE_GZIP 1 +#define HAVE_LIBDRM_GETFB2 0 +#define HAVE_MAKEINFO 0 +#define HAVE_MAKEINFO_HTML 0 +#define HAVE_OPENCL_D3D11 0 +#define HAVE_OPENCL_DRM_ARM 0 +#define HAVE_OPENCL_DRM_BEIGNET 0 +#define HAVE_OPENCL_DXVA2 0 +#define HAVE_OPENCL_VAAPI_BEIGNET 0 +#define HAVE_OPENCL_VAAPI_INTEL_MEDIA 0 +#define HAVE_PERL 1 +#define HAVE_POD2MAN 1 +#define HAVE_TEXI2HTML 0 +#define HAVE_XMLLINT 1 +#define HAVE_ZLIB_GZIP 0 +#define CONFIG_DOC 0 +#define CONFIG_HTMLPAGES 0 +#define CONFIG_MANPAGES 0 +#define CONFIG_PODPAGES 0 +#define CONFIG_TXTPAGES 0 +#define CONFIG_AVIO_LIST_DIR_EXAMPLE 1 +#define CONFIG_AVIO_READING_EXAMPLE 1 +#define CONFIG_DECODE_AUDIO_EXAMPLE 1 +#define CONFIG_DECODE_VIDEO_EXAMPLE 1 +#define CONFIG_DEMUXING_DECODING_EXAMPLE 1 +#define CONFIG_ENCODE_AUDIO_EXAMPLE 1 +#define CONFIG_ENCODE_VIDEO_EXAMPLE 1 +#define CONFIG_EXTRACT_MVS_EXAMPLE 1 +#define CONFIG_FILTER_AUDIO_EXAMPLE 0 +#define CONFIG_FILTERING_AUDIO_EXAMPLE 0 +#define CONFIG_FILTERING_VIDEO_EXAMPLE 0 +#define CONFIG_HTTP_MULTICLIENT_EXAMPLE 1 +#define CONFIG_HW_DECODE_EXAMPLE 1 +#define CONFIG_METADATA_EXAMPLE 1 +#define CONFIG_MUXING_EXAMPLE 0 +#define CONFIG_QSVDEC_EXAMPLE 0 +#define CONFIG_REMUXING_EXAMPLE 1 +#define CONFIG_RESAMPLING_AUDIO_EXAMPLE 0 +#define CONFIG_SCALING_VIDEO_EXAMPLE 0 +#define CONFIG_TRANSCODE_AAC_EXAMPLE 0 +#define CONFIG_TRANSCODING_EXAMPLE 0 +#define CONFIG_VAAPI_ENCODE_EXAMPLE 0 +#define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 +#define CONFIG_AVISYNTH 0 +#define CONFIG_FREI0R 0 +#define CONFIG_LIBCDIO 0 +#define CONFIG_LIBDAVS2 0 +#define CONFIG_LIBRUBBERBAND 0 +#define CONFIG_LIBVIDSTAB 0 +#define CONFIG_LIBX264 0 +#define CONFIG_LIBX265 0 +#define CONFIG_LIBXAVS 0 +#define CONFIG_LIBXAVS2 0 +#define CONFIG_LIBXVID 0 +#define CONFIG_DECKLINK 0 +#define CONFIG_LIBFDK_AAC 0 +#define CONFIG_LIBTLS 0 +#define CONFIG_GMP 0 +#define CONFIG_LIBARIBB24 0 +#define CONFIG_LIBLENSFUN 0 +#define CONFIG_LIBOPENCORE_AMRNB 0 +#define CONFIG_LIBOPENCORE_AMRWB 0 +#define CONFIG_LIBVO_AMRWBENC 0 +#define CONFIG_MBEDTLS 0 +#define CONFIG_RKMPP 0 +#define CONFIG_LIBSMBCLIENT 0 +#define CONFIG_CHROMAPRINT 0 +#define CONFIG_GCRYPT 0 +#define CONFIG_GNUTLS 0 +#define CONFIG_JNI 0 +#define CONFIG_LADSPA 0 +#define CONFIG_LCMS2 0 +#define CONFIG_LIBAOM 0 +#define CONFIG_LIBASS 0 +#define CONFIG_LIBBLURAY 0 +#define CONFIG_LIBBS2B 0 +#define CONFIG_LIBCACA 0 +#define CONFIG_LIBCELT 0 +#define CONFIG_LIBCODEC2 0 +#define CONFIG_LIBDAV1D 0 +#define CONFIG_LIBDC1394 0 +#define CONFIG_LIBDRM 0 +#define CONFIG_LIBFLITE 0 +#define CONFIG_LIBFONTCONFIG 0 +#define CONFIG_LIBFREETYPE 0 +#define CONFIG_LIBFRIBIDI 0 +#define CONFIG_LIBGLSLANG 0 +#define CONFIG_LIBGME 0 +#define CONFIG_LIBGSM 0 +#define CONFIG_LIBIEC61883 0 +#define CONFIG_LIBILBC 0 +#define CONFIG_LIBJACK 0 +#define CONFIG_LIBJXL 0 +#define CONFIG_LIBKLVANC 0 +#define CONFIG_LIBKVAZAAR 0 +#define CONFIG_LIBMODPLUG 0 +#define CONFIG_LIBMP3LAME 0 +#define CONFIG_LIBMYSOFA 0 +#define CONFIG_LIBOPENCV 0 +#define CONFIG_LIBOPENH264 0 +#define CONFIG_LIBOPENJPEG 0 +#define CONFIG_LIBOPENMPT 0 +#define CONFIG_LIBOPENVINO 0 +#define CONFIG_LIBOPUS 1 +#define CONFIG_LIBPLACEBO 0 +#define CONFIG_LIBPULSE 0 +#define CONFIG_LIBRABBITMQ 0 +#define CONFIG_LIBRAV1E 0 +#define CONFIG_LIBRIST 0 +#define CONFIG_LIBRSVG 0 +#define CONFIG_LIBRTMP 0 +#define CONFIG_LIBSHADERC 0 +#define CONFIG_LIBSHINE 0 +#define CONFIG_LIBSMBCLIENT 0 +#define CONFIG_LIBSNAPPY 0 +#define CONFIG_LIBSOXR 0 +#define CONFIG_LIBSPEEX 0 +#define CONFIG_LIBSRT 0 +#define CONFIG_LIBSSH 0 +#define CONFIG_LIBSVTAV1 0 +#define CONFIG_LIBTENSORFLOW 0 +#define CONFIG_LIBTESSERACT 0 +#define CONFIG_LIBTHEORA 0 +#define CONFIG_LIBTWOLAME 0 +#define CONFIG_LIBUAVS3D 0 +#define CONFIG_LIBV4L2 0 +#define CONFIG_LIBVMAF 0 +#define CONFIG_LIBVORBIS 0 +#define CONFIG_LIBVPX 0 +#define CONFIG_LIBWEBP 0 +#define CONFIG_LIBXML2 0 +#define CONFIG_LIBZIMG 0 +#define CONFIG_LIBZMQ 0 +#define CONFIG_LIBZVBI 0 +#define CONFIG_LV2 0 +#define CONFIG_MEDIACODEC 0 +#define CONFIG_OPENAL 0 +#define CONFIG_OPENGL 0 +#define CONFIG_OPENSSL 0 +#define CONFIG_POCKETSPHINX 0 +#define CONFIG_VAPOURSYNTH 0 +#define CONFIG_ALSA 0 +#define CONFIG_APPKIT 0 +#define CONFIG_AVFOUNDATION 0 +#define CONFIG_BZLIB 0 +#define CONFIG_COREIMAGE 0 +#define CONFIG_ICONV 0 +#define CONFIG_LIBXCB 0 +#define CONFIG_LIBXCB_SHM 0 +#define CONFIG_LIBXCB_SHAPE 0 +#define CONFIG_LIBXCB_XFIXES 0 +#define CONFIG_LZMA 0 +#define CONFIG_MEDIAFOUNDATION 0 +#define CONFIG_METAL 0 +#define CONFIG_SCHANNEL 0 +#define CONFIG_SDL2 0 +#define CONFIG_SECURETRANSPORT 0 +#define CONFIG_SNDIO 0 +#define CONFIG_XLIB 0 +#define CONFIG_ZLIB 0 +#define CONFIG_CUDA_NVCC 0 +#define CONFIG_CUDA_SDK 0 +#define CONFIG_LIBNPP 0 +#define CONFIG_LIBMFX 0 +#define CONFIG_LIBVPL 0 +#define CONFIG_MMAL 0 +#define CONFIG_OMX 0 +#define CONFIG_OPENCL 0 +#define CONFIG_AMF 0 +#define CONFIG_AUDIOTOOLBOX 0 +#define CONFIG_CRYSTALHD 0 +#define CONFIG_CUDA 0 +#define CONFIG_CUDA_LLVM 0 +#define CONFIG_CUVID 0 +#define CONFIG_D3D11VA 0 +#define CONFIG_DXVA2 0 +#define CONFIG_FFNVCODEC 0 +#define CONFIG_NVDEC 0 +#define CONFIG_NVENC 0 +#define CONFIG_VAAPI 0 +#define CONFIG_VDPAU 0 +#define CONFIG_VIDEOTOOLBOX 0 +#define CONFIG_VULKAN 0 +#define CONFIG_V4L2_M2M 0 +#define CONFIG_FTRAPV 0 +#define CONFIG_GRAY 0 +#define CONFIG_HARDCODED_TABLES 0 +#define CONFIG_OMX_RPI 0 +#define CONFIG_RUNTIME_CPUDETECT 1 +#define CONFIG_SAFE_BITSTREAM_READER 1 +#define CONFIG_SHARED 0 +#define CONFIG_SMALL 0 +#define CONFIG_STATIC 1 +#define CONFIG_SWSCALE_ALPHA 1 +#define CONFIG_GPL 0 +#define CONFIG_NONFREE 0 +#define CONFIG_VERSION3 0 +#define CONFIG_AVDEVICE 0 +#define CONFIG_AVFILTER 0 +#define CONFIG_SWSCALE 0 +#define CONFIG_POSTPROC 0 +#define CONFIG_AVFORMAT 1 +#define CONFIG_AVCODEC 1 +#define CONFIG_SWRESAMPLE 0 +#define CONFIG_AVUTIL 1 +#define CONFIG_FFPLAY 0 +#define CONFIG_FFPROBE 0 +#define CONFIG_FFMPEG 0 +#define CONFIG_DCT 1 +#define CONFIG_DWT 0 +#define CONFIG_ERROR_RESILIENCE 0 +#define CONFIG_FAAN 0 +#define CONFIG_FAST_UNALIGNED 1 +#define CONFIG_FFT 1 +#define CONFIG_LSP 0 +#define CONFIG_MDCT 0 +#define CONFIG_PIXELUTILS 0 +#define CONFIG_NETWORK 0 +#define CONFIG_RDFT 1 +#define CONFIG_AUTODETECT 0 +#define CONFIG_FONTCONFIG 0 +#define CONFIG_LARGE_TESTS 1 +#define CONFIG_LINUX_PERF 0 +#define CONFIG_MACOS_KPERF 0 +#define CONFIG_MEMORY_POISONING 0 +#define CONFIG_NEON_CLOBBER_TEST 0 +#define CONFIG_OSSFUZZ 0 +#define CONFIG_PIC 1 +#define CONFIG_PTX_COMPRESSION 0 +#define CONFIG_THUMB 0 +#define CONFIG_VALGRIND_BACKTRACE 0 +#define CONFIG_XMM_CLOBBER_TEST 0 +#define CONFIG_BSFS 0 +#define CONFIG_DECODERS 1 +#define CONFIG_ENCODERS 0 +#define CONFIG_HWACCELS 0 +#define CONFIG_PARSERS 1 +#define CONFIG_INDEVS 0 +#define CONFIG_OUTDEVS 0 +#define CONFIG_FILTERS 0 +#define CONFIG_DEMUXERS 1 +#define CONFIG_MUXERS 0 +#define CONFIG_PROTOCOLS 0 +#define CONFIG_AANDCTTABLES 0 +#define CONFIG_AC3DSP 0 +#define CONFIG_ADTS_HEADER 1 +#define CONFIG_ATSC_A53 1 +#define CONFIG_AUDIO_FRAME_QUEUE 0 +#define CONFIG_AUDIODSP 0 +#define CONFIG_BLOCKDSP 0 +#define CONFIG_BSWAPDSP 1 +#define CONFIG_CABAC 1 +#define CONFIG_CBS 0 +#define CONFIG_CBS_AV1 0 +#define CONFIG_CBS_H264 0 +#define CONFIG_CBS_H265 0 +#define CONFIG_CBS_JPEG 0 +#define CONFIG_CBS_MPEG2 0 +#define CONFIG_CBS_VP9 0 +#define CONFIG_DEFLATE_WRAPPER 0 +#define CONFIG_DIRAC_PARSE 1 +#define CONFIG_DNN 0 +#define CONFIG_DOVI_RPU 1 +#define CONFIG_DVPROFILE 0 +#define CONFIG_EXIF 0 +#define CONFIG_FAANDCT 0 +#define CONFIG_FAANIDCT 0 +#define CONFIG_FDCTDSP 0 +#define CONFIG_FMTCONVERT 0 +#define CONFIG_FRAME_THREAD_ENCODER 0 +#define CONFIG_G722DSP 0 +#define CONFIG_GOLOMB 1 +#define CONFIG_GPLV3 0 +#define CONFIG_H263DSP 0 +#define CONFIG_H264CHROMA 1 +#define CONFIG_H264DSP 1 +#define CONFIG_H264PARSE 1 +#define CONFIG_H264PRED 1 +#define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 +#define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 +#define CONFIG_HPELDSP 1 +#define CONFIG_HUFFMAN 0 +#define CONFIG_HUFFYUVDSP 0 +#define CONFIG_HUFFYUVENCDSP 0 +#define CONFIG_IDCTDSP 0 +#define CONFIG_IIRFILTER 0 +#define CONFIG_INFLATE_WRAPPER 0 +#define CONFIG_INTRAX8 0 +#define CONFIG_ISO_MEDIA 1 +#define CONFIG_IVIDSP 0 +#define CONFIG_JPEGTABLES 0 +#define CONFIG_LGPLV3 0 +#define CONFIG_LIBX262 0 +#define CONFIG_LLAUDDSP 0 +#define CONFIG_LLVIDDSP 0 +#define CONFIG_LLVIDENCDSP 0 +#define CONFIG_LPC 0 +#define CONFIG_LZF 0 +#define CONFIG_ME_CMP 0 +#define CONFIG_MPEG_ER 0 +#define CONFIG_MPEGAUDIO 1 +#define CONFIG_MPEGAUDIODSP 1 +#define CONFIG_MPEGAUDIOHEADER 1 +#define CONFIG_MPEG4AUDIO 1 +#define CONFIG_MPEGVIDEO 0 +#define CONFIG_MPEGVIDEODEC 0 +#define CONFIG_MPEGVIDEOENC 0 +#define CONFIG_MSMPEG4DEC 0 +#define CONFIG_MSMPEG4ENC 0 +#define CONFIG_MSS34DSP 0 +#define CONFIG_PIXBLOCKDSP 0 +#define CONFIG_QPELDSP 0 +#define CONFIG_QSV 0 +#define CONFIG_QSVDEC 0 +#define CONFIG_QSVENC 0 +#define CONFIG_QSVVPP 0 +#define CONFIG_RANGECODER 0 +#define CONFIG_RIFFDEC 1 +#define CONFIG_RIFFENC 0 +#define CONFIG_RTPDEC 0 +#define CONFIG_RTPENC_CHAIN 0 +#define CONFIG_RV34DSP 0 +#define CONFIG_SCENE_SAD 0 +#define CONFIG_SINEWIN 1 +#define CONFIG_SNAPPY 0 +#define CONFIG_SRTP 0 +#define CONFIG_STARTCODE 1 +#define CONFIG_TEXTUREDSP 0 +#define CONFIG_TEXTUREDSPENC 0 +#define CONFIG_TPELDSP 0 +#define CONFIG_VAAPI_1 0 +#define CONFIG_VAAPI_ENCODE 0 +#define CONFIG_VC1DSP 0 +#define CONFIG_VIDEODSP 1 +#define CONFIG_VP3DSP 1 +#define CONFIG_VP56DSP 0 +#define CONFIG_VP8DSP 1 +#define CONFIG_WMA_FREQS 0 +#define CONFIG_WMV2DSP 0 +#endif /* FFMPEG_CONFIG_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config_components.h new file mode 100644 index 00000000..539cd1a5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/config_components.h @@ -0,0 +1,2146 @@ +/* Automatically generated by configure - do not modify! */ +#ifndef FFMPEG_CONFIG_COMPONENTS_H +#define FFMPEG_CONFIG_COMPONENTS_H +#define CONFIG_AAC_ADTSTOASC_BSF 0 +#define CONFIG_AV1_FRAME_MERGE_BSF 0 +#define CONFIG_AV1_FRAME_SPLIT_BSF 0 +#define CONFIG_AV1_METADATA_BSF 0 +#define CONFIG_CHOMP_BSF 0 +#define CONFIG_DUMP_EXTRADATA_BSF 0 +#define CONFIG_DCA_CORE_BSF 0 +#define CONFIG_DTS2PTS_BSF 0 +#define CONFIG_DV_ERROR_MARKER_BSF 0 +#define CONFIG_EAC3_CORE_BSF 0 +#define CONFIG_EXTRACT_EXTRADATA_BSF 0 +#define CONFIG_FILTER_UNITS_BSF 0 +#define CONFIG_H264_METADATA_BSF 0 +#define CONFIG_H264_MP4TOANNEXB_BSF 0 +#define CONFIG_H264_REDUNDANT_PPS_BSF 0 +#define CONFIG_HAPQA_EXTRACT_BSF 0 +#define CONFIG_HEVC_METADATA_BSF 0 +#define CONFIG_HEVC_MP4TOANNEXB_BSF 0 +#define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 +#define CONFIG_MJPEG2JPEG_BSF 0 +#define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 +#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 +#define CONFIG_MPEG2_METADATA_BSF 0 +#define CONFIG_MPEG4_UNPACK_BFRAMES_BSF 0 +#define CONFIG_MOV2TEXTSUB_BSF 0 +#define CONFIG_NOISE_BSF 0 +#define CONFIG_NULL_BSF 0 +#define CONFIG_OPUS_METADATA_BSF 0 +#define CONFIG_PCM_RECHUNK_BSF 0 +#define CONFIG_PGS_FRAME_MERGE_BSF 0 +#define CONFIG_PRORES_METADATA_BSF 0 +#define CONFIG_REMOVE_EXTRADATA_BSF 0 +#define CONFIG_SETTS_BSF 0 +#define CONFIG_TEXT2MOVSUB_BSF 0 +#define CONFIG_TRACE_HEADERS_BSF 0 +#define CONFIG_TRUEHD_CORE_BSF 0 +#define CONFIG_VP9_METADATA_BSF 0 +#define CONFIG_VP9_RAW_REORDER_BSF 0 +#define CONFIG_VP9_SUPERFRAME_BSF 0 +#define CONFIG_VP9_SUPERFRAME_SPLIT_BSF 0 +#define CONFIG_AASC_DECODER 0 +#define CONFIG_AIC_DECODER 0 +#define CONFIG_ALIAS_PIX_DECODER 0 +#define CONFIG_AGM_DECODER 0 +#define CONFIG_AMV_DECODER 0 +#define CONFIG_ANM_DECODER 0 +#define CONFIG_ANSI_DECODER 0 +#define CONFIG_APNG_DECODER 0 +#define CONFIG_ARBC_DECODER 0 +#define CONFIG_ARGO_DECODER 0 +#define CONFIG_ASV1_DECODER 0 +#define CONFIG_ASV2_DECODER 0 +#define CONFIG_AURA_DECODER 0 +#define CONFIG_AURA2_DECODER 0 +#define CONFIG_AVRP_DECODER 0 +#define CONFIG_AVRN_DECODER 0 +#define CONFIG_AVS_DECODER 0 +#define CONFIG_AVUI_DECODER 0 +#define CONFIG_AYUV_DECODER 0 +#define CONFIG_BETHSOFTVID_DECODER 0 +#define CONFIG_BFI_DECODER 0 +#define CONFIG_BINK_DECODER 0 +#define CONFIG_BITPACKED_DECODER 0 +#define CONFIG_BMP_DECODER 0 +#define CONFIG_BMV_VIDEO_DECODER 0 +#define CONFIG_BRENDER_PIX_DECODER 0 +#define CONFIG_C93_DECODER 0 +#define CONFIG_CAVS_DECODER 0 +#define CONFIG_CDGRAPHICS_DECODER 0 +#define CONFIG_CDTOONS_DECODER 0 +#define CONFIG_CDXL_DECODER 0 +#define CONFIG_CFHD_DECODER 0 +#define CONFIG_CINEPAK_DECODER 0 +#define CONFIG_CLEARVIDEO_DECODER 0 +#define CONFIG_CLJR_DECODER 0 +#define CONFIG_CLLC_DECODER 0 +#define CONFIG_COMFORTNOISE_DECODER 0 +#define CONFIG_CPIA_DECODER 0 +#define CONFIG_CRI_DECODER 0 +#define CONFIG_CSCD_DECODER 0 +#define CONFIG_CYUV_DECODER 0 +#define CONFIG_DDS_DECODER 0 +#define CONFIG_DFA_DECODER 0 +#define CONFIG_DIRAC_DECODER 0 +#define CONFIG_DNXHD_DECODER 0 +#define CONFIG_DPX_DECODER 0 +#define CONFIG_DSICINVIDEO_DECODER 0 +#define CONFIG_DVAUDIO_DECODER 0 +#define CONFIG_DVVIDEO_DECODER 0 +#define CONFIG_DXA_DECODER 0 +#define CONFIG_DXTORY_DECODER 0 +#define CONFIG_DXV_DECODER 0 +#define CONFIG_EACMV_DECODER 0 +#define CONFIG_EAMAD_DECODER 0 +#define CONFIG_EATGQ_DECODER 0 +#define CONFIG_EATGV_DECODER 0 +#define CONFIG_EATQI_DECODER 0 +#define CONFIG_EIGHTBPS_DECODER 0 +#define CONFIG_EIGHTSVX_EXP_DECODER 0 +#define CONFIG_EIGHTSVX_FIB_DECODER 0 +#define CONFIG_ESCAPE124_DECODER 0 +#define CONFIG_ESCAPE130_DECODER 0 +#define CONFIG_EXR_DECODER 0 +#define CONFIG_FFV1_DECODER 0 +#define CONFIG_FFVHUFF_DECODER 0 +#define CONFIG_FIC_DECODER 0 +#define CONFIG_FITS_DECODER 0 +#define CONFIG_FLASHSV_DECODER 0 +#define CONFIG_FLASHSV2_DECODER 0 +#define CONFIG_FLIC_DECODER 0 +#define CONFIG_FLV_DECODER 0 +#define CONFIG_FMVC_DECODER 0 +#define CONFIG_FOURXM_DECODER 0 +#define CONFIG_FRAPS_DECODER 0 +#define CONFIG_FRWU_DECODER 0 +#define CONFIG_G2M_DECODER 0 +#define CONFIG_GDV_DECODER 0 +#define CONFIG_GEM_DECODER 0 +#define CONFIG_GIF_DECODER 0 +#define CONFIG_H261_DECODER 0 +#define CONFIG_H263_DECODER 0 +#define CONFIG_H263I_DECODER 0 +#define CONFIG_H263P_DECODER 0 +#define CONFIG_H263_V4L2M2M_DECODER 0 +#define CONFIG_H264_DECODER 1 +#define CONFIG_H264_CRYSTALHD_DECODER 0 +#define CONFIG_H264_V4L2M2M_DECODER 0 +#define CONFIG_H264_MEDIACODEC_DECODER 0 +#define CONFIG_H264_MMAL_DECODER 0 +#define CONFIG_H264_QSV_DECODER 0 +#define CONFIG_H264_RKMPP_DECODER 0 +#define CONFIG_HAP_DECODER 0 +#define CONFIG_HEVC_DECODER 1 +#define CONFIG_HEVC_QSV_DECODER 0 +#define CONFIG_HEVC_RKMPP_DECODER 0 +#define CONFIG_HEVC_V4L2M2M_DECODER 0 +#define CONFIG_HNM4_VIDEO_DECODER 0 +#define CONFIG_HQ_HQA_DECODER 0 +#define CONFIG_HQX_DECODER 0 +#define CONFIG_HUFFYUV_DECODER 0 +#define CONFIG_HYMT_DECODER 0 +#define CONFIG_IDCIN_DECODER 0 +#define CONFIG_IFF_ILBM_DECODER 0 +#define CONFIG_IMM4_DECODER 0 +#define CONFIG_IMM5_DECODER 0 +#define CONFIG_INDEO2_DECODER 0 +#define CONFIG_INDEO3_DECODER 0 +#define CONFIG_INDEO4_DECODER 0 +#define CONFIG_INDEO5_DECODER 0 +#define CONFIG_INTERPLAY_VIDEO_DECODER 0 +#define CONFIG_IPU_DECODER 0 +#define CONFIG_JPEG2000_DECODER 0 +#define CONFIG_JPEGLS_DECODER 0 +#define CONFIG_JV_DECODER 0 +#define CONFIG_KGV1_DECODER 0 +#define CONFIG_KMVC_DECODER 0 +#define CONFIG_LAGARITH_DECODER 0 +#define CONFIG_LOCO_DECODER 0 +#define CONFIG_LSCR_DECODER 0 +#define CONFIG_M101_DECODER 0 +#define CONFIG_MAGICYUV_DECODER 0 +#define CONFIG_MDEC_DECODER 0 +#define CONFIG_MEDIA100_DECODER 0 +#define CONFIG_MIMIC_DECODER 0 +#define CONFIG_MJPEG_DECODER 0 +#define CONFIG_MJPEGB_DECODER 0 +#define CONFIG_MMVIDEO_DECODER 0 +#define CONFIG_MOBICLIP_DECODER 0 +#define CONFIG_MOTIONPIXELS_DECODER 0 +#define CONFIG_MPEG1VIDEO_DECODER 0 +#define CONFIG_MPEG2VIDEO_DECODER 0 +#define CONFIG_MPEG4_DECODER 0 +#define CONFIG_MPEG4_CRYSTALHD_DECODER 0 +#define CONFIG_MPEG4_V4L2M2M_DECODER 0 +#define CONFIG_MPEG4_MMAL_DECODER 0 +#define CONFIG_MPEGVIDEO_DECODER 0 +#define CONFIG_MPEG1_V4L2M2M_DECODER 0 +#define CONFIG_MPEG2_MMAL_DECODER 0 +#define CONFIG_MPEG2_CRYSTALHD_DECODER 0 +#define CONFIG_MPEG2_V4L2M2M_DECODER 0 +#define CONFIG_MPEG2_QSV_DECODER 0 +#define CONFIG_MPEG2_MEDIACODEC_DECODER 0 +#define CONFIG_MSA1_DECODER 0 +#define CONFIG_MSCC_DECODER 0 +#define CONFIG_MSMPEG4V1_DECODER 0 +#define CONFIG_MSMPEG4V2_DECODER 0 +#define CONFIG_MSMPEG4V3_DECODER 0 +#define CONFIG_MSMPEG4_CRYSTALHD_DECODER 0 +#define CONFIG_MSP2_DECODER 0 +#define CONFIG_MSRLE_DECODER 0 +#define CONFIG_MSS1_DECODER 0 +#define CONFIG_MSS2_DECODER 0 +#define CONFIG_MSVIDEO1_DECODER 0 +#define CONFIG_MSZH_DECODER 0 +#define CONFIG_MTS2_DECODER 0 +#define CONFIG_MV30_DECODER 0 +#define CONFIG_MVC1_DECODER 0 +#define CONFIG_MVC2_DECODER 0 +#define CONFIG_MVDV_DECODER 0 +#define CONFIG_MVHA_DECODER 0 +#define CONFIG_MWSC_DECODER 0 +#define CONFIG_MXPEG_DECODER 0 +#define CONFIG_NOTCHLC_DECODER 0 +#define CONFIG_NUV_DECODER 0 +#define CONFIG_PAF_VIDEO_DECODER 0 +#define CONFIG_PAM_DECODER 0 +#define CONFIG_PBM_DECODER 0 +#define CONFIG_PCX_DECODER 0 +#define CONFIG_PFM_DECODER 0 +#define CONFIG_PGM_DECODER 0 +#define CONFIG_PGMYUV_DECODER 0 +#define CONFIG_PGX_DECODER 0 +#define CONFIG_PHM_DECODER 0 +#define CONFIG_PHOTOCD_DECODER 0 +#define CONFIG_PICTOR_DECODER 0 +#define CONFIG_PIXLET_DECODER 0 +#define CONFIG_PNG_DECODER 0 +#define CONFIG_PPM_DECODER 0 +#define CONFIG_PRORES_DECODER 0 +#define CONFIG_PROSUMER_DECODER 0 +#define CONFIG_PSD_DECODER 0 +#define CONFIG_PTX_DECODER 0 +#define CONFIG_QDRAW_DECODER 0 +#define CONFIG_QOI_DECODER 0 +#define CONFIG_QPEG_DECODER 0 +#define CONFIG_QTRLE_DECODER 0 +#define CONFIG_R10K_DECODER 0 +#define CONFIG_R210_DECODER 0 +#define CONFIG_RASC_DECODER 0 +#define CONFIG_RAWVIDEO_DECODER 0 +#define CONFIG_RL2_DECODER 0 +#define CONFIG_ROQ_DECODER 0 +#define CONFIG_RPZA_DECODER 0 +#define CONFIG_RSCC_DECODER 0 +#define CONFIG_RV10_DECODER 0 +#define CONFIG_RV20_DECODER 0 +#define CONFIG_RV30_DECODER 0 +#define CONFIG_RV40_DECODER 0 +#define CONFIG_S302M_DECODER 0 +#define CONFIG_SANM_DECODER 0 +#define CONFIG_SCPR_DECODER 0 +#define CONFIG_SCREENPRESSO_DECODER 0 +#define CONFIG_SGA_DECODER 0 +#define CONFIG_SGI_DECODER 0 +#define CONFIG_SGIRLE_DECODER 0 +#define CONFIG_SHEERVIDEO_DECODER 0 +#define CONFIG_SIMBIOSIS_IMX_DECODER 0 +#define CONFIG_SMACKER_DECODER 0 +#define CONFIG_SMC_DECODER 0 +#define CONFIG_SMVJPEG_DECODER 0 +#define CONFIG_SNOW_DECODER 0 +#define CONFIG_SP5X_DECODER 0 +#define CONFIG_SPEEDHQ_DECODER 0 +#define CONFIG_SPEEX_DECODER 0 +#define CONFIG_SRGC_DECODER 0 +#define CONFIG_SUNRAST_DECODER 0 +#define CONFIG_SVQ1_DECODER 0 +#define CONFIG_SVQ3_DECODER 0 +#define CONFIG_TARGA_DECODER 0 +#define CONFIG_TARGA_Y216_DECODER 0 +#define CONFIG_TDSC_DECODER 0 +#define CONFIG_THEORA_DECODER 1 +#define CONFIG_THP_DECODER 0 +#define CONFIG_TIERTEXSEQVIDEO_DECODER 0 +#define CONFIG_TIFF_DECODER 0 +#define CONFIG_TMV_DECODER 0 +#define CONFIG_TRUEMOTION1_DECODER 0 +#define CONFIG_TRUEMOTION2_DECODER 0 +#define CONFIG_TRUEMOTION2RT_DECODER 0 +#define CONFIG_TSCC_DECODER 0 +#define CONFIG_TSCC2_DECODER 0 +#define CONFIG_TXD_DECODER 0 +#define CONFIG_ULTI_DECODER 0 +#define CONFIG_UTVIDEO_DECODER 0 +#define CONFIG_V210_DECODER 0 +#define CONFIG_V210X_DECODER 0 +#define CONFIG_V308_DECODER 0 +#define CONFIG_V408_DECODER 0 +#define CONFIG_V410_DECODER 0 +#define CONFIG_VB_DECODER 0 +#define CONFIG_VBN_DECODER 0 +#define CONFIG_VBLE_DECODER 0 +#define CONFIG_VC1_DECODER 0 +#define CONFIG_VC1_CRYSTALHD_DECODER 0 +#define CONFIG_VC1IMAGE_DECODER 0 +#define CONFIG_VC1_MMAL_DECODER 0 +#define CONFIG_VC1_QSV_DECODER 0 +#define CONFIG_VC1_V4L2M2M_DECODER 0 +#define CONFIG_VCR1_DECODER 0 +#define CONFIG_VMDVIDEO_DECODER 0 +#define CONFIG_VMNC_DECODER 0 +#define CONFIG_VP3_DECODER 1 +#define CONFIG_VP4_DECODER 0 +#define CONFIG_VP5_DECODER 0 +#define CONFIG_VP6_DECODER 0 +#define CONFIG_VP6A_DECODER 0 +#define CONFIG_VP6F_DECODER 0 +#define CONFIG_VP7_DECODER 0 +#define CONFIG_VP8_DECODER 1 +#define CONFIG_VP8_RKMPP_DECODER 0 +#define CONFIG_VP8_V4L2M2M_DECODER 0 +#define CONFIG_VP9_DECODER 0 +#define CONFIG_VP9_RKMPP_DECODER 0 +#define CONFIG_VP9_V4L2M2M_DECODER 0 +#define CONFIG_VQA_DECODER 0 +#define CONFIG_VQC_DECODER 0 +#define CONFIG_WBMP_DECODER 0 +#define CONFIG_WEBP_DECODER 0 +#define CONFIG_WCMV_DECODER 0 +#define CONFIG_WRAPPED_AVFRAME_DECODER 0 +#define CONFIG_WMV1_DECODER 0 +#define CONFIG_WMV2_DECODER 0 +#define CONFIG_WMV3_DECODER 0 +#define CONFIG_WMV3_CRYSTALHD_DECODER 0 +#define CONFIG_WMV3IMAGE_DECODER 0 +#define CONFIG_WNV1_DECODER 0 +#define CONFIG_XAN_WC3_DECODER 0 +#define CONFIG_XAN_WC4_DECODER 0 +#define CONFIG_XBM_DECODER 0 +#define CONFIG_XFACE_DECODER 0 +#define CONFIG_XL_DECODER 0 +#define CONFIG_XPM_DECODER 0 +#define CONFIG_XWD_DECODER 0 +#define CONFIG_Y41P_DECODER 0 +#define CONFIG_YLC_DECODER 0 +#define CONFIG_YOP_DECODER 0 +#define CONFIG_YUV4_DECODER 0 +#define CONFIG_ZERO12V_DECODER 0 +#define CONFIG_ZEROCODEC_DECODER 0 +#define CONFIG_ZLIB_DECODER 0 +#define CONFIG_ZMBV_DECODER 0 +#define CONFIG_AAC_DECODER 1 +#define CONFIG_AAC_FIXED_DECODER 0 +#define CONFIG_AAC_LATM_DECODER 0 +#define CONFIG_AC3_DECODER 0 +#define CONFIG_AC3_FIXED_DECODER 0 +#define CONFIG_ACELP_KELVIN_DECODER 0 +#define CONFIG_ALAC_DECODER 0 +#define CONFIG_ALS_DECODER 0 +#define CONFIG_AMRNB_DECODER 0 +#define CONFIG_AMRWB_DECODER 0 +#define CONFIG_APAC_DECODER 0 +#define CONFIG_APE_DECODER 0 +#define CONFIG_APTX_DECODER 0 +#define CONFIG_APTX_HD_DECODER 0 +#define CONFIG_ATRAC1_DECODER 0 +#define CONFIG_ATRAC3_DECODER 0 +#define CONFIG_ATRAC3AL_DECODER 0 +#define CONFIG_ATRAC3P_DECODER 0 +#define CONFIG_ATRAC3PAL_DECODER 0 +#define CONFIG_ATRAC9_DECODER 0 +#define CONFIG_BINKAUDIO_DCT_DECODER 0 +#define CONFIG_BINKAUDIO_RDFT_DECODER 0 +#define CONFIG_BMV_AUDIO_DECODER 0 +#define CONFIG_BONK_DECODER 0 +#define CONFIG_COOK_DECODER 0 +#define CONFIG_DCA_DECODER 0 +#define CONFIG_DFPWM_DECODER 0 +#define CONFIG_DOLBY_E_DECODER 0 +#define CONFIG_DSD_LSBF_DECODER 0 +#define CONFIG_DSD_MSBF_DECODER 0 +#define CONFIG_DSD_LSBF_PLANAR_DECODER 0 +#define CONFIG_DSD_MSBF_PLANAR_DECODER 0 +#define CONFIG_DSICINAUDIO_DECODER 0 +#define CONFIG_DSS_SP_DECODER 0 +#define CONFIG_DST_DECODER 0 +#define CONFIG_EAC3_DECODER 0 +#define CONFIG_EVRC_DECODER 0 +#define CONFIG_FASTAUDIO_DECODER 0 +#define CONFIG_FFWAVESYNTH_DECODER 0 +#define CONFIG_FLAC_DECODER 1 +#define CONFIG_FTR_DECODER 0 +#define CONFIG_G723_1_DECODER 0 +#define CONFIG_G729_DECODER 0 +#define CONFIG_GSM_DECODER 0 +#define CONFIG_GSM_MS_DECODER 0 +#define CONFIG_HCA_DECODER 0 +#define CONFIG_HCOM_DECODER 0 +#define CONFIG_HDR_DECODER 0 +#define CONFIG_IAC_DECODER 0 +#define CONFIG_ILBC_DECODER 0 +#define CONFIG_IMC_DECODER 0 +#define CONFIG_INTERPLAY_ACM_DECODER 0 +#define CONFIG_MACE3_DECODER 0 +#define CONFIG_MACE6_DECODER 0 +#define CONFIG_METASOUND_DECODER 0 +#define CONFIG_MISC4_DECODER 0 +#define CONFIG_MLP_DECODER 0 +#define CONFIG_MP1_DECODER 0 +#define CONFIG_MP1FLOAT_DECODER 0 +#define CONFIG_MP2_DECODER 0 +#define CONFIG_MP2FLOAT_DECODER 0 +#define CONFIG_MP3FLOAT_DECODER 0 +#define CONFIG_MP3_DECODER 1 +#define CONFIG_MP3ADUFLOAT_DECODER 0 +#define CONFIG_MP3ADU_DECODER 0 +#define CONFIG_MP3ON4FLOAT_DECODER 0 +#define CONFIG_MP3ON4_DECODER 0 +#define CONFIG_MPC7_DECODER 0 +#define CONFIG_MPC8_DECODER 0 +#define CONFIG_MSNSIREN_DECODER 0 +#define CONFIG_NELLYMOSER_DECODER 0 +#define CONFIG_ON2AVC_DECODER 0 +#define CONFIG_OPUS_DECODER 0 +#define CONFIG_PAF_AUDIO_DECODER 0 +#define CONFIG_QCELP_DECODER 0 +#define CONFIG_QDM2_DECODER 0 +#define CONFIG_QDMC_DECODER 0 +#define CONFIG_RA_144_DECODER 0 +#define CONFIG_RA_288_DECODER 0 +#define CONFIG_RALF_DECODER 0 +#define CONFIG_SBC_DECODER 0 +#define CONFIG_SHORTEN_DECODER 0 +#define CONFIG_SIPR_DECODER 0 +#define CONFIG_SIREN_DECODER 0 +#define CONFIG_SMACKAUD_DECODER 0 +#define CONFIG_SONIC_DECODER 0 +#define CONFIG_TAK_DECODER 0 +#define CONFIG_TRUEHD_DECODER 0 +#define CONFIG_TRUESPEECH_DECODER 0 +#define CONFIG_TTA_DECODER 0 +#define CONFIG_TWINVQ_DECODER 0 +#define CONFIG_VMDAUDIO_DECODER 0 +#define CONFIG_VORBIS_DECODER 1 +#define CONFIG_WAVPACK_DECODER 0 +#define CONFIG_WMALOSSLESS_DECODER 0 +#define CONFIG_WMAPRO_DECODER 0 +#define CONFIG_WMAV1_DECODER 0 +#define CONFIG_WMAV2_DECODER 0 +#define CONFIG_WMAVOICE_DECODER 0 +#define CONFIG_WS_SND1_DECODER 0 +#define CONFIG_XMA1_DECODER 0 +#define CONFIG_XMA2_DECODER 0 +#define CONFIG_PCM_ALAW_DECODER 1 +#define CONFIG_PCM_BLURAY_DECODER 0 +#define CONFIG_PCM_DVD_DECODER 0 +#define CONFIG_PCM_F16LE_DECODER 0 +#define CONFIG_PCM_F24LE_DECODER 0 +#define CONFIG_PCM_F32BE_DECODER 0 +#define CONFIG_PCM_F32LE_DECODER 1 +#define CONFIG_PCM_F64BE_DECODER 0 +#define CONFIG_PCM_F64LE_DECODER 0 +#define CONFIG_PCM_LXF_DECODER 0 +#define CONFIG_PCM_MULAW_DECODER 1 +#define CONFIG_PCM_S8_DECODER 0 +#define CONFIG_PCM_S8_PLANAR_DECODER 0 +#define CONFIG_PCM_S16BE_DECODER 1 +#define CONFIG_PCM_S16BE_PLANAR_DECODER 0 +#define CONFIG_PCM_S16LE_DECODER 1 +#define CONFIG_PCM_S16LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S24BE_DECODER 1 +#define CONFIG_PCM_S24DAUD_DECODER 0 +#define CONFIG_PCM_S24LE_DECODER 1 +#define CONFIG_PCM_S24LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S32BE_DECODER 0 +#define CONFIG_PCM_S32LE_DECODER 1 +#define CONFIG_PCM_S32LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S64BE_DECODER 0 +#define CONFIG_PCM_S64LE_DECODER 0 +#define CONFIG_PCM_SGA_DECODER 0 +#define CONFIG_PCM_U8_DECODER 1 +#define CONFIG_PCM_U16BE_DECODER 0 +#define CONFIG_PCM_U16LE_DECODER 0 +#define CONFIG_PCM_U24BE_DECODER 0 +#define CONFIG_PCM_U24LE_DECODER 0 +#define CONFIG_PCM_U32BE_DECODER 0 +#define CONFIG_PCM_U32LE_DECODER 0 +#define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 +#define CONFIG_DERF_DPCM_DECODER 0 +#define CONFIG_GREMLIN_DPCM_DECODER 0 +#define CONFIG_INTERPLAY_DPCM_DECODER 0 +#define CONFIG_ROQ_DPCM_DECODER 0 +#define CONFIG_SDX2_DPCM_DECODER 0 +#define CONFIG_SOL_DPCM_DECODER 0 +#define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 +#define CONFIG_ADPCM_4XM_DECODER 0 +#define CONFIG_ADPCM_ADX_DECODER 0 +#define CONFIG_ADPCM_AFC_DECODER 0 +#define CONFIG_ADPCM_AGM_DECODER 0 +#define CONFIG_ADPCM_AICA_DECODER 0 +#define CONFIG_ADPCM_ARGO_DECODER 0 +#define CONFIG_ADPCM_CT_DECODER 0 +#define CONFIG_ADPCM_DTK_DECODER 0 +#define CONFIG_ADPCM_EA_DECODER 0 +#define CONFIG_ADPCM_EA_MAXIS_XA_DECODER 0 +#define CONFIG_ADPCM_EA_R1_DECODER 0 +#define CONFIG_ADPCM_EA_R2_DECODER 0 +#define CONFIG_ADPCM_EA_R3_DECODER 0 +#define CONFIG_ADPCM_EA_XAS_DECODER 0 +#define CONFIG_ADPCM_G722_DECODER 0 +#define CONFIG_ADPCM_G726_DECODER 0 +#define CONFIG_ADPCM_G726LE_DECODER 0 +#define CONFIG_ADPCM_IMA_ACORN_DECODER 0 +#define CONFIG_ADPCM_IMA_AMV_DECODER 0 +#define CONFIG_ADPCM_IMA_ALP_DECODER 0 +#define CONFIG_ADPCM_IMA_APC_DECODER 0 +#define CONFIG_ADPCM_IMA_APM_DECODER 0 +#define CONFIG_ADPCM_IMA_CUNNING_DECODER 0 +#define CONFIG_ADPCM_IMA_DAT4_DECODER 0 +#define CONFIG_ADPCM_IMA_DK3_DECODER 0 +#define CONFIG_ADPCM_IMA_DK4_DECODER 0 +#define CONFIG_ADPCM_IMA_EA_EACS_DECODER 0 +#define CONFIG_ADPCM_IMA_EA_SEAD_DECODER 0 +#define CONFIG_ADPCM_IMA_ISS_DECODER 0 +#define CONFIG_ADPCM_IMA_MOFLEX_DECODER 0 +#define CONFIG_ADPCM_IMA_MTF_DECODER 0 +#define CONFIG_ADPCM_IMA_OKI_DECODER 0 +#define CONFIG_ADPCM_IMA_QT_DECODER 0 +#define CONFIG_ADPCM_IMA_RAD_DECODER 0 +#define CONFIG_ADPCM_IMA_SSI_DECODER 0 +#define CONFIG_ADPCM_IMA_SMJPEG_DECODER 0 +#define CONFIG_ADPCM_IMA_WAV_DECODER 0 +#define CONFIG_ADPCM_IMA_WS_DECODER 0 +#define CONFIG_ADPCM_MS_DECODER 0 +#define CONFIG_ADPCM_MTAF_DECODER 0 +#define CONFIG_ADPCM_PSX_DECODER 0 +#define CONFIG_ADPCM_SBPRO_2_DECODER 0 +#define CONFIG_ADPCM_SBPRO_3_DECODER 0 +#define CONFIG_ADPCM_SBPRO_4_DECODER 0 +#define CONFIG_ADPCM_SWF_DECODER 0 +#define CONFIG_ADPCM_THP_DECODER 0 +#define CONFIG_ADPCM_THP_LE_DECODER 0 +#define CONFIG_ADPCM_VIMA_DECODER 0 +#define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 +#define CONFIG_ADPCM_YAMAHA_DECODER 0 +#define CONFIG_ADPCM_ZORK_DECODER 0 +#define CONFIG_SSA_DECODER 0 +#define CONFIG_ASS_DECODER 0 +#define CONFIG_CCAPTION_DECODER 0 +#define CONFIG_DVBSUB_DECODER 0 +#define CONFIG_DVDSUB_DECODER 0 +#define CONFIG_JACOSUB_DECODER 0 +#define CONFIG_MICRODVD_DECODER 0 +#define CONFIG_MOVTEXT_DECODER 0 +#define CONFIG_MPL2_DECODER 0 +#define CONFIG_PGSSUB_DECODER 0 +#define CONFIG_PJS_DECODER 0 +#define CONFIG_REALTEXT_DECODER 0 +#define CONFIG_SAMI_DECODER 0 +#define CONFIG_SRT_DECODER 0 +#define CONFIG_STL_DECODER 0 +#define CONFIG_SUBRIP_DECODER 0 +#define CONFIG_SUBVIEWER_DECODER 0 +#define CONFIG_SUBVIEWER1_DECODER 0 +#define CONFIG_TEXT_DECODER 0 +#define CONFIG_VPLAYER_DECODER 0 +#define CONFIG_WEBVTT_DECODER 0 +#define CONFIG_XSUB_DECODER 0 +#define CONFIG_AAC_AT_DECODER 0 +#define CONFIG_AC3_AT_DECODER 0 +#define CONFIG_ADPCM_IMA_QT_AT_DECODER 0 +#define CONFIG_ALAC_AT_DECODER 0 +#define CONFIG_AMR_NB_AT_DECODER 0 +#define CONFIG_EAC3_AT_DECODER 0 +#define CONFIG_GSM_MS_AT_DECODER 0 +#define CONFIG_ILBC_AT_DECODER 0 +#define CONFIG_MP1_AT_DECODER 0 +#define CONFIG_MP2_AT_DECODER 0 +#define CONFIG_MP3_AT_DECODER 0 +#define CONFIG_PCM_ALAW_AT_DECODER 0 +#define CONFIG_PCM_MULAW_AT_DECODER 0 +#define CONFIG_QDMC_AT_DECODER 0 +#define CONFIG_QDM2_AT_DECODER 0 +#define CONFIG_LIBARIBB24_DECODER 0 +#define CONFIG_LIBCELT_DECODER 0 +#define CONFIG_LIBCODEC2_DECODER 0 +#define CONFIG_LIBDAV1D_DECODER 0 +#define CONFIG_LIBDAVS2_DECODER 0 +#define CONFIG_LIBFDK_AAC_DECODER 0 +#define CONFIG_LIBGSM_DECODER 0 +#define CONFIG_LIBGSM_MS_DECODER 0 +#define CONFIG_LIBILBC_DECODER 0 +#define CONFIG_LIBJXL_DECODER 0 +#define CONFIG_LIBOPENCORE_AMRNB_DECODER 0 +#define CONFIG_LIBOPENCORE_AMRWB_DECODER 0 +#define CONFIG_LIBOPENJPEG_DECODER 0 +#define CONFIG_LIBOPUS_DECODER 1 +#define CONFIG_LIBRSVG_DECODER 0 +#define CONFIG_LIBSPEEX_DECODER 0 +#define CONFIG_LIBUAVS3D_DECODER 0 +#define CONFIG_LIBVORBIS_DECODER 0 +#define CONFIG_LIBVPX_VP8_DECODER 0 +#define CONFIG_LIBVPX_VP9_DECODER 0 +#define CONFIG_LIBZVBI_TELETEXT_DECODER 0 +#define CONFIG_BINTEXT_DECODER 0 +#define CONFIG_XBIN_DECODER 0 +#define CONFIG_IDF_DECODER 0 +#define CONFIG_LIBAOM_AV1_DECODER 0 +#define CONFIG_AV1_DECODER 0 +#define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 +#define CONFIG_AV1_QSV_DECODER 0 +#define CONFIG_LIBOPENH264_DECODER 0 +#define CONFIG_H264_CUVID_DECODER 0 +#define CONFIG_HEVC_CUVID_DECODER 0 +#define CONFIG_HEVC_MEDIACODEC_DECODER 0 +#define CONFIG_MJPEG_CUVID_DECODER 0 +#define CONFIG_MJPEG_QSV_DECODER 0 +#define CONFIG_MPEG1_CUVID_DECODER 0 +#define CONFIG_MPEG2_CUVID_DECODER 0 +#define CONFIG_MPEG4_CUVID_DECODER 0 +#define CONFIG_MPEG4_MEDIACODEC_DECODER 0 +#define CONFIG_VC1_CUVID_DECODER 0 +#define CONFIG_VP8_CUVID_DECODER 0 +#define CONFIG_VP8_MEDIACODEC_DECODER 0 +#define CONFIG_VP8_QSV_DECODER 0 +#define CONFIG_VP9_CUVID_DECODER 0 +#define CONFIG_VP9_MEDIACODEC_DECODER 0 +#define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 +#define CONFIG_A64MULTI_ENCODER 0 +#define CONFIG_A64MULTI5_ENCODER 0 +#define CONFIG_ALIAS_PIX_ENCODER 0 +#define CONFIG_AMV_ENCODER 0 +#define CONFIG_APNG_ENCODER 0 +#define CONFIG_ASV1_ENCODER 0 +#define CONFIG_ASV2_ENCODER 0 +#define CONFIG_AVRP_ENCODER 0 +#define CONFIG_AVUI_ENCODER 0 +#define CONFIG_AYUV_ENCODER 0 +#define CONFIG_BITPACKED_ENCODER 0 +#define CONFIG_BMP_ENCODER 0 +#define CONFIG_CFHD_ENCODER 0 +#define CONFIG_CINEPAK_ENCODER 0 +#define CONFIG_CLJR_ENCODER 0 +#define CONFIG_COMFORTNOISE_ENCODER 0 +#define CONFIG_DNXHD_ENCODER 0 +#define CONFIG_DPX_ENCODER 0 +#define CONFIG_DVVIDEO_ENCODER 0 +#define CONFIG_EXR_ENCODER 0 +#define CONFIG_FFV1_ENCODER 0 +#define CONFIG_FFVHUFF_ENCODER 0 +#define CONFIG_FITS_ENCODER 0 +#define CONFIG_FLASHSV_ENCODER 0 +#define CONFIG_FLASHSV2_ENCODER 0 +#define CONFIG_FLV_ENCODER 0 +#define CONFIG_GIF_ENCODER 0 +#define CONFIG_H261_ENCODER 0 +#define CONFIG_H263_ENCODER 0 +#define CONFIG_H263P_ENCODER 0 +#define CONFIG_H264_MEDIACODEC_ENCODER 0 +#define CONFIG_HAP_ENCODER 0 +#define CONFIG_HUFFYUV_ENCODER 0 +#define CONFIG_JPEG2000_ENCODER 0 +#define CONFIG_JPEGLS_ENCODER 0 +#define CONFIG_LJPEG_ENCODER 0 +#define CONFIG_MAGICYUV_ENCODER 0 +#define CONFIG_MJPEG_ENCODER 0 +#define CONFIG_MPEG1VIDEO_ENCODER 0 +#define CONFIG_MPEG2VIDEO_ENCODER 0 +#define CONFIG_MPEG4_ENCODER 0 +#define CONFIG_MSMPEG4V2_ENCODER 0 +#define CONFIG_MSMPEG4V3_ENCODER 0 +#define CONFIG_MSVIDEO1_ENCODER 0 +#define CONFIG_PAM_ENCODER 0 +#define CONFIG_PBM_ENCODER 0 +#define CONFIG_PCX_ENCODER 0 +#define CONFIG_PFM_ENCODER 0 +#define CONFIG_PGM_ENCODER 0 +#define CONFIG_PGMYUV_ENCODER 0 +#define CONFIG_PHM_ENCODER 0 +#define CONFIG_PNG_ENCODER 0 +#define CONFIG_PPM_ENCODER 0 +#define CONFIG_PRORES_ENCODER 0 +#define CONFIG_PRORES_AW_ENCODER 0 +#define CONFIG_PRORES_KS_ENCODER 0 +#define CONFIG_QOI_ENCODER 0 +#define CONFIG_QTRLE_ENCODER 0 +#define CONFIG_R10K_ENCODER 0 +#define CONFIG_R210_ENCODER 0 +#define CONFIG_RAWVIDEO_ENCODER 0 +#define CONFIG_ROQ_ENCODER 0 +#define CONFIG_RPZA_ENCODER 0 +#define CONFIG_RV10_ENCODER 0 +#define CONFIG_RV20_ENCODER 0 +#define CONFIG_S302M_ENCODER 0 +#define CONFIG_SGI_ENCODER 0 +#define CONFIG_SMC_ENCODER 0 +#define CONFIG_SNOW_ENCODER 0 +#define CONFIG_SPEEDHQ_ENCODER 0 +#define CONFIG_SUNRAST_ENCODER 0 +#define CONFIG_SVQ1_ENCODER 0 +#define CONFIG_TARGA_ENCODER 0 +#define CONFIG_TIFF_ENCODER 0 +#define CONFIG_UTVIDEO_ENCODER 0 +#define CONFIG_V210_ENCODER 0 +#define CONFIG_V308_ENCODER 0 +#define CONFIG_V408_ENCODER 0 +#define CONFIG_V410_ENCODER 0 +#define CONFIG_VBN_ENCODER 0 +#define CONFIG_VC2_ENCODER 0 +#define CONFIG_WBMP_ENCODER 0 +#define CONFIG_WRAPPED_AVFRAME_ENCODER 0 +#define CONFIG_WMV1_ENCODER 0 +#define CONFIG_WMV2_ENCODER 0 +#define CONFIG_XBM_ENCODER 0 +#define CONFIG_XFACE_ENCODER 0 +#define CONFIG_XWD_ENCODER 0 +#define CONFIG_Y41P_ENCODER 0 +#define CONFIG_YUV4_ENCODER 0 +#define CONFIG_ZLIB_ENCODER 0 +#define CONFIG_ZMBV_ENCODER 0 +#define CONFIG_AAC_ENCODER 0 +#define CONFIG_AC3_ENCODER 0 +#define CONFIG_AC3_FIXED_ENCODER 0 +#define CONFIG_ALAC_ENCODER 0 +#define CONFIG_APTX_ENCODER 0 +#define CONFIG_APTX_HD_ENCODER 0 +#define CONFIG_DCA_ENCODER 0 +#define CONFIG_DFPWM_ENCODER 0 +#define CONFIG_EAC3_ENCODER 0 +#define CONFIG_FLAC_ENCODER 0 +#define CONFIG_G723_1_ENCODER 0 +#define CONFIG_HDR_ENCODER 0 +#define CONFIG_MLP_ENCODER 0 +#define CONFIG_MP2_ENCODER 0 +#define CONFIG_MP2FIXED_ENCODER 0 +#define CONFIG_NELLYMOSER_ENCODER 0 +#define CONFIG_OPUS_ENCODER 0 +#define CONFIG_RA_144_ENCODER 0 +#define CONFIG_SBC_ENCODER 0 +#define CONFIG_SONIC_ENCODER 0 +#define CONFIG_SONIC_LS_ENCODER 0 +#define CONFIG_TRUEHD_ENCODER 0 +#define CONFIG_TTA_ENCODER 0 +#define CONFIG_VORBIS_ENCODER 0 +#define CONFIG_WAVPACK_ENCODER 0 +#define CONFIG_WMAV1_ENCODER 0 +#define CONFIG_WMAV2_ENCODER 0 +#define CONFIG_PCM_ALAW_ENCODER 0 +#define CONFIG_PCM_BLURAY_ENCODER 0 +#define CONFIG_PCM_DVD_ENCODER 0 +#define CONFIG_PCM_F32BE_ENCODER 0 +#define CONFIG_PCM_F32LE_ENCODER 0 +#define CONFIG_PCM_F64BE_ENCODER 0 +#define CONFIG_PCM_F64LE_ENCODER 0 +#define CONFIG_PCM_MULAW_ENCODER 0 +#define CONFIG_PCM_S8_ENCODER 0 +#define CONFIG_PCM_S8_PLANAR_ENCODER 0 +#define CONFIG_PCM_S16BE_ENCODER 0 +#define CONFIG_PCM_S16BE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S16LE_ENCODER 0 +#define CONFIG_PCM_S16LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S24BE_ENCODER 0 +#define CONFIG_PCM_S24DAUD_ENCODER 0 +#define CONFIG_PCM_S24LE_ENCODER 0 +#define CONFIG_PCM_S24LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S32BE_ENCODER 0 +#define CONFIG_PCM_S32LE_ENCODER 0 +#define CONFIG_PCM_S32LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S64BE_ENCODER 0 +#define CONFIG_PCM_S64LE_ENCODER 0 +#define CONFIG_PCM_U8_ENCODER 0 +#define CONFIG_PCM_U16BE_ENCODER 0 +#define CONFIG_PCM_U16LE_ENCODER 0 +#define CONFIG_PCM_U24BE_ENCODER 0 +#define CONFIG_PCM_U24LE_ENCODER 0 +#define CONFIG_PCM_U32BE_ENCODER 0 +#define CONFIG_PCM_U32LE_ENCODER 0 +#define CONFIG_PCM_VIDC_ENCODER 0 +#define CONFIG_ROQ_DPCM_ENCODER 0 +#define CONFIG_ADPCM_ADX_ENCODER 0 +#define CONFIG_ADPCM_ARGO_ENCODER 0 +#define CONFIG_ADPCM_G722_ENCODER 0 +#define CONFIG_ADPCM_G726_ENCODER 0 +#define CONFIG_ADPCM_G726LE_ENCODER 0 +#define CONFIG_ADPCM_IMA_AMV_ENCODER 0 +#define CONFIG_ADPCM_IMA_ALP_ENCODER 0 +#define CONFIG_ADPCM_IMA_APM_ENCODER 0 +#define CONFIG_ADPCM_IMA_QT_ENCODER 0 +#define CONFIG_ADPCM_IMA_SSI_ENCODER 0 +#define CONFIG_ADPCM_IMA_WAV_ENCODER 0 +#define CONFIG_ADPCM_IMA_WS_ENCODER 0 +#define CONFIG_ADPCM_MS_ENCODER 0 +#define CONFIG_ADPCM_SWF_ENCODER 0 +#define CONFIG_ADPCM_YAMAHA_ENCODER 0 +#define CONFIG_SSA_ENCODER 0 +#define CONFIG_ASS_ENCODER 0 +#define CONFIG_DVBSUB_ENCODER 0 +#define CONFIG_DVDSUB_ENCODER 0 +#define CONFIG_MOVTEXT_ENCODER 0 +#define CONFIG_SRT_ENCODER 0 +#define CONFIG_SUBRIP_ENCODER 0 +#define CONFIG_TEXT_ENCODER 0 +#define CONFIG_TTML_ENCODER 0 +#define CONFIG_WEBVTT_ENCODER 0 +#define CONFIG_XSUB_ENCODER 0 +#define CONFIG_AAC_AT_ENCODER 0 +#define CONFIG_ALAC_AT_ENCODER 0 +#define CONFIG_ILBC_AT_ENCODER 0 +#define CONFIG_PCM_ALAW_AT_ENCODER 0 +#define CONFIG_PCM_MULAW_AT_ENCODER 0 +#define CONFIG_LIBAOM_AV1_ENCODER 0 +#define CONFIG_LIBCODEC2_ENCODER 0 +#define CONFIG_LIBFDK_AAC_ENCODER 0 +#define CONFIG_LIBGSM_ENCODER 0 +#define CONFIG_LIBGSM_MS_ENCODER 0 +#define CONFIG_LIBILBC_ENCODER 0 +#define CONFIG_LIBJXL_ENCODER 0 +#define CONFIG_LIBMP3LAME_ENCODER 0 +#define CONFIG_LIBOPENCORE_AMRNB_ENCODER 0 +#define CONFIG_LIBOPENJPEG_ENCODER 0 +#define CONFIG_LIBOPUS_ENCODER 0 +#define CONFIG_LIBRAV1E_ENCODER 0 +#define CONFIG_LIBSHINE_ENCODER 0 +#define CONFIG_LIBSPEEX_ENCODER 0 +#define CONFIG_LIBSVTAV1_ENCODER 0 +#define CONFIG_LIBTHEORA_ENCODER 0 +#define CONFIG_LIBTWOLAME_ENCODER 0 +#define CONFIG_LIBVO_AMRWBENC_ENCODER 0 +#define CONFIG_LIBVORBIS_ENCODER 0 +#define CONFIG_LIBVPX_VP8_ENCODER 0 +#define CONFIG_LIBVPX_VP9_ENCODER 0 +#define CONFIG_LIBWEBP_ANIM_ENCODER 0 +#define CONFIG_LIBWEBP_ENCODER 0 +#define CONFIG_LIBX262_ENCODER 0 +#define CONFIG_LIBX264_ENCODER 0 +#define CONFIG_LIBX264RGB_ENCODER 0 +#define CONFIG_LIBX265_ENCODER 0 +#define CONFIG_LIBXAVS_ENCODER 0 +#define CONFIG_LIBXAVS2_ENCODER 0 +#define CONFIG_LIBXVID_ENCODER 0 +#define CONFIG_AAC_MF_ENCODER 0 +#define CONFIG_AC3_MF_ENCODER 0 +#define CONFIG_H263_V4L2M2M_ENCODER 0 +#define CONFIG_AV1_NVENC_ENCODER 0 +#define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 +#define CONFIG_LIBOPENH264_ENCODER 0 +#define CONFIG_H264_AMF_ENCODER 0 +#define CONFIG_H264_MF_ENCODER 0 +#define CONFIG_H264_NVENC_ENCODER 0 +#define CONFIG_H264_OMX_ENCODER 0 +#define CONFIG_H264_QSV_ENCODER 0 +#define CONFIG_H264_V4L2M2M_ENCODER 0 +#define CONFIG_H264_VAAPI_ENCODER 0 +#define CONFIG_H264_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_HEVC_AMF_ENCODER 0 +#define CONFIG_HEVC_MEDIACODEC_ENCODER 0 +#define CONFIG_HEVC_MF_ENCODER 0 +#define CONFIG_HEVC_NVENC_ENCODER 0 +#define CONFIG_HEVC_QSV_ENCODER 0 +#define CONFIG_HEVC_V4L2M2M_ENCODER 0 +#define CONFIG_HEVC_VAAPI_ENCODER 0 +#define CONFIG_HEVC_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_LIBKVAZAAR_ENCODER 0 +#define CONFIG_MJPEG_QSV_ENCODER 0 +#define CONFIG_MJPEG_VAAPI_ENCODER 0 +#define CONFIG_MP3_MF_ENCODER 0 +#define CONFIG_MPEG2_QSV_ENCODER 0 +#define CONFIG_MPEG2_VAAPI_ENCODER 0 +#define CONFIG_MPEG4_OMX_ENCODER 0 +#define CONFIG_MPEG4_V4L2M2M_ENCODER 0 +#define CONFIG_PRORES_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_VP8_V4L2M2M_ENCODER 0 +#define CONFIG_VP8_VAAPI_ENCODER 0 +#define CONFIG_VP9_VAAPI_ENCODER 0 +#define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 +#define CONFIG_AV1_D3D11VA_HWACCEL 0 +#define CONFIG_AV1_D3D11VA2_HWACCEL 0 +#define CONFIG_AV1_DXVA2_HWACCEL 0 +#define CONFIG_AV1_NVDEC_HWACCEL 0 +#define CONFIG_AV1_VAAPI_HWACCEL 0 +#define CONFIG_AV1_VDPAU_HWACCEL 0 +#define CONFIG_H263_VAAPI_HWACCEL 0 +#define CONFIG_H263_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_H264_D3D11VA_HWACCEL 0 +#define CONFIG_H264_D3D11VA2_HWACCEL 0 +#define CONFIG_H264_DXVA2_HWACCEL 0 +#define CONFIG_H264_NVDEC_HWACCEL 0 +#define CONFIG_H264_VAAPI_HWACCEL 0 +#define CONFIG_H264_VDPAU_HWACCEL 0 +#define CONFIG_H264_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_HEVC_D3D11VA_HWACCEL 0 +#define CONFIG_HEVC_D3D11VA2_HWACCEL 0 +#define CONFIG_HEVC_DXVA2_HWACCEL 0 +#define CONFIG_HEVC_NVDEC_HWACCEL 0 +#define CONFIG_HEVC_VAAPI_HWACCEL 0 +#define CONFIG_HEVC_VDPAU_HWACCEL 0 +#define CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MJPEG_NVDEC_HWACCEL 0 +#define CONFIG_MJPEG_VAAPI_HWACCEL 0 +#define CONFIG_MPEG1_NVDEC_HWACCEL 0 +#define CONFIG_MPEG1_VDPAU_HWACCEL 0 +#define CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MPEG2_D3D11VA_HWACCEL 0 +#define CONFIG_MPEG2_D3D11VA2_HWACCEL 0 +#define CONFIG_MPEG2_NVDEC_HWACCEL 0 +#define CONFIG_MPEG2_DXVA2_HWACCEL 0 +#define CONFIG_MPEG2_VAAPI_HWACCEL 0 +#define CONFIG_MPEG2_VDPAU_HWACCEL 0 +#define CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MPEG4_NVDEC_HWACCEL 0 +#define CONFIG_MPEG4_VAAPI_HWACCEL 0 +#define CONFIG_MPEG4_VDPAU_HWACCEL 0 +#define CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_VC1_D3D11VA_HWACCEL 0 +#define CONFIG_VC1_D3D11VA2_HWACCEL 0 +#define CONFIG_VC1_DXVA2_HWACCEL 0 +#define CONFIG_VC1_NVDEC_HWACCEL 0 +#define CONFIG_VC1_VAAPI_HWACCEL 0 +#define CONFIG_VC1_VDPAU_HWACCEL 0 +#define CONFIG_VP8_NVDEC_HWACCEL 0 +#define CONFIG_VP8_VAAPI_HWACCEL 0 +#define CONFIG_VP9_D3D11VA_HWACCEL 0 +#define CONFIG_VP9_D3D11VA2_HWACCEL 0 +#define CONFIG_VP9_DXVA2_HWACCEL 0 +#define CONFIG_VP9_NVDEC_HWACCEL 0 +#define CONFIG_VP9_VAAPI_HWACCEL 0 +#define CONFIG_VP9_VDPAU_HWACCEL 0 +#define CONFIG_VP9_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_WMV3_D3D11VA_HWACCEL 0 +#define CONFIG_WMV3_D3D11VA2_HWACCEL 0 +#define CONFIG_WMV3_DXVA2_HWACCEL 0 +#define CONFIG_WMV3_NVDEC_HWACCEL 0 +#define CONFIG_WMV3_VAAPI_HWACCEL 0 +#define CONFIG_WMV3_VDPAU_HWACCEL 0 +#define CONFIG_AAC_PARSER 1 +#define CONFIG_AAC_LATM_PARSER 0 +#define CONFIG_AC3_PARSER 0 +#define CONFIG_ADX_PARSER 0 +#define CONFIG_AMR_PARSER 0 +#define CONFIG_AV1_PARSER 0 +#define CONFIG_AVS2_PARSER 0 +#define CONFIG_AVS3_PARSER 0 +#define CONFIG_BMP_PARSER 0 +#define CONFIG_CAVSVIDEO_PARSER 0 +#define CONFIG_COOK_PARSER 0 +#define CONFIG_CRI_PARSER 0 +#define CONFIG_DCA_PARSER 0 +#define CONFIG_DIRAC_PARSER 0 +#define CONFIG_DNXHD_PARSER 0 +#define CONFIG_DOLBY_E_PARSER 0 +#define CONFIG_DPX_PARSER 0 +#define CONFIG_DVAUDIO_PARSER 0 +#define CONFIG_DVBSUB_PARSER 0 +#define CONFIG_DVDSUB_PARSER 0 +#define CONFIG_DVD_NAV_PARSER 0 +#define CONFIG_FLAC_PARSER 1 +#define CONFIG_FTR_PARSER 0 +#define CONFIG_G723_1_PARSER 0 +#define CONFIG_G729_PARSER 0 +#define CONFIG_GIF_PARSER 0 +#define CONFIG_GSM_PARSER 0 +#define CONFIG_H261_PARSER 0 +#define CONFIG_H263_PARSER 0 +#define CONFIG_H264_PARSER 1 +#define CONFIG_HEVC_PARSER 1 +#define CONFIG_HDR_PARSER 0 +#define CONFIG_IPU_PARSER 0 +#define CONFIG_JPEG2000_PARSER 0 +#define CONFIG_MISC4_PARSER 0 +#define CONFIG_MJPEG_PARSER 0 +#define CONFIG_MLP_PARSER 0 +#define CONFIG_MPEG4VIDEO_PARSER 0 +#define CONFIG_MPEGAUDIO_PARSER 1 +#define CONFIG_MPEGVIDEO_PARSER 0 +#define CONFIG_OPUS_PARSER 1 +#define CONFIG_PNG_PARSER 0 +#define CONFIG_PNM_PARSER 0 +#define CONFIG_QOI_PARSER 0 +#define CONFIG_RV30_PARSER 0 +#define CONFIG_RV40_PARSER 0 +#define CONFIG_SBC_PARSER 0 +#define CONFIG_SIPR_PARSER 0 +#define CONFIG_TAK_PARSER 0 +#define CONFIG_VC1_PARSER 0 +#define CONFIG_VORBIS_PARSER 1 +#define CONFIG_VP3_PARSER 1 +#define CONFIG_VP8_PARSER 1 +#define CONFIG_VP9_PARSER 1 +#define CONFIG_WEBP_PARSER 0 +#define CONFIG_XBM_PARSER 0 +#define CONFIG_XMA_PARSER 0 +#define CONFIG_XWD_PARSER 0 +#define CONFIG_ALSA_INDEV 0 +#define CONFIG_ANDROID_CAMERA_INDEV 0 +#define CONFIG_AVFOUNDATION_INDEV 0 +#define CONFIG_BKTR_INDEV 0 +#define CONFIG_DECKLINK_INDEV 0 +#define CONFIG_DSHOW_INDEV 0 +#define CONFIG_FBDEV_INDEV 0 +#define CONFIG_GDIGRAB_INDEV 0 +#define CONFIG_IEC61883_INDEV 0 +#define CONFIG_JACK_INDEV 0 +#define CONFIG_KMSGRAB_INDEV 0 +#define CONFIG_LAVFI_INDEV 0 +#define CONFIG_OPENAL_INDEV 0 +#define CONFIG_OSS_INDEV 0 +#define CONFIG_PULSE_INDEV 0 +#define CONFIG_SNDIO_INDEV 0 +#define CONFIG_V4L2_INDEV 0 +#define CONFIG_VFWCAP_INDEV 0 +#define CONFIG_XCBGRAB_INDEV 0 +#define CONFIG_LIBCDIO_INDEV 0 +#define CONFIG_LIBDC1394_INDEV 0 +#define CONFIG_ALSA_OUTDEV 0 +#define CONFIG_AUDIOTOOLBOX_OUTDEV 0 +#define CONFIG_CACA_OUTDEV 0 +#define CONFIG_DECKLINK_OUTDEV 0 +#define CONFIG_FBDEV_OUTDEV 0 +#define CONFIG_OPENGL_OUTDEV 0 +#define CONFIG_OSS_OUTDEV 0 +#define CONFIG_PULSE_OUTDEV 0 +#define CONFIG_SDL2_OUTDEV 0 +#define CONFIG_SNDIO_OUTDEV 0 +#define CONFIG_V4L2_OUTDEV 0 +#define CONFIG_XV_OUTDEV 0 +#define CONFIG_ABENCH_FILTER 0 +#define CONFIG_ACOMPRESSOR_FILTER 0 +#define CONFIG_ACONTRAST_FILTER 0 +#define CONFIG_ACOPY_FILTER 0 +#define CONFIG_ACUE_FILTER 0 +#define CONFIG_ACROSSFADE_FILTER 0 +#define CONFIG_ACROSSOVER_FILTER 0 +#define CONFIG_ACRUSHER_FILTER 0 +#define CONFIG_ADECLICK_FILTER 0 +#define CONFIG_ADECLIP_FILTER 0 +#define CONFIG_ADECORRELATE_FILTER 0 +#define CONFIG_ADELAY_FILTER 0 +#define CONFIG_ADENORM_FILTER 0 +#define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 +#define CONFIG_ADYNAMICEQUALIZER_FILTER 0 +#define CONFIG_ADYNAMICSMOOTH_FILTER 0 +#define CONFIG_AECHO_FILTER 0 +#define CONFIG_AEMPHASIS_FILTER 0 +#define CONFIG_AEVAL_FILTER 0 +#define CONFIG_AEXCITER_FILTER 0 +#define CONFIG_AFADE_FILTER 0 +#define CONFIG_AFFTDN_FILTER 0 +#define CONFIG_AFFTFILT_FILTER 0 +#define CONFIG_AFIR_FILTER 0 +#define CONFIG_AFORMAT_FILTER 0 +#define CONFIG_AFREQSHIFT_FILTER 0 +#define CONFIG_AFWTDN_FILTER 0 +#define CONFIG_AGATE_FILTER 0 +#define CONFIG_AIIR_FILTER 0 +#define CONFIG_AINTEGRAL_FILTER 0 +#define CONFIG_AINTERLEAVE_FILTER 0 +#define CONFIG_ALATENCY_FILTER 0 +#define CONFIG_ALIMITER_FILTER 0 +#define CONFIG_ALLPASS_FILTER 0 +#define CONFIG_ALOOP_FILTER 0 +#define CONFIG_AMERGE_FILTER 0 +#define CONFIG_AMETADATA_FILTER 0 +#define CONFIG_AMIX_FILTER 0 +#define CONFIG_AMULTIPLY_FILTER 0 +#define CONFIG_ANEQUALIZER_FILTER 0 +#define CONFIG_ANLMDN_FILTER 0 +#define CONFIG_ANLMF_FILTER 0 +#define CONFIG_ANLMS_FILTER 0 +#define CONFIG_ANULL_FILTER 0 +#define CONFIG_APAD_FILTER 0 +#define CONFIG_APERMS_FILTER 0 +#define CONFIG_APHASER_FILTER 0 +#define CONFIG_APHASESHIFT_FILTER 0 +#define CONFIG_APSYCLIP_FILTER 0 +#define CONFIG_APULSATOR_FILTER 0 +#define CONFIG_AREALTIME_FILTER 0 +#define CONFIG_ARESAMPLE_FILTER 0 +#define CONFIG_AREVERSE_FILTER 0 +#define CONFIG_ARNNDN_FILTER 0 +#define CONFIG_ASDR_FILTER 0 +#define CONFIG_ASEGMENT_FILTER 0 +#define CONFIG_ASELECT_FILTER 0 +#define CONFIG_ASENDCMD_FILTER 0 +#define CONFIG_ASETNSAMPLES_FILTER 0 +#define CONFIG_ASETPTS_FILTER 0 +#define CONFIG_ASETRATE_FILTER 0 +#define CONFIG_ASETTB_FILTER 0 +#define CONFIG_ASHOWINFO_FILTER 0 +#define CONFIG_ASIDEDATA_FILTER 0 +#define CONFIG_ASOFTCLIP_FILTER 0 +#define CONFIG_ASPECTRALSTATS_FILTER 0 +#define CONFIG_ASPLIT_FILTER 0 +#define CONFIG_ASR_FILTER 0 +#define CONFIG_ASTATS_FILTER 0 +#define CONFIG_ASTREAMSELECT_FILTER 0 +#define CONFIG_ASUBBOOST_FILTER 0 +#define CONFIG_ASUBCUT_FILTER 0 +#define CONFIG_ASUPERCUT_FILTER 0 +#define CONFIG_ASUPERPASS_FILTER 0 +#define CONFIG_ASUPERSTOP_FILTER 0 +#define CONFIG_ATEMPO_FILTER 0 +#define CONFIG_ATILT_FILTER 0 +#define CONFIG_ATRIM_FILTER 0 +#define CONFIG_AXCORRELATE_FILTER 0 +#define CONFIG_AZMQ_FILTER 0 +#define CONFIG_BANDPASS_FILTER 0 +#define CONFIG_BANDREJECT_FILTER 0 +#define CONFIG_BASS_FILTER 0 +#define CONFIG_BIQUAD_FILTER 0 +#define CONFIG_BS2B_FILTER 0 +#define CONFIG_CHANNELMAP_FILTER 0 +#define CONFIG_CHANNELSPLIT_FILTER 0 +#define CONFIG_CHORUS_FILTER 0 +#define CONFIG_COMPAND_FILTER 0 +#define CONFIG_COMPENSATIONDELAY_FILTER 0 +#define CONFIG_CROSSFEED_FILTER 0 +#define CONFIG_CRYSTALIZER_FILTER 0 +#define CONFIG_DCSHIFT_FILTER 0 +#define CONFIG_DEESSER_FILTER 0 +#define CONFIG_DIALOGUENHANCE_FILTER 0 +#define CONFIG_DRMETER_FILTER 0 +#define CONFIG_DYNAUDNORM_FILTER 0 +#define CONFIG_EARWAX_FILTER 0 +#define CONFIG_EBUR128_FILTER 0 +#define CONFIG_EQUALIZER_FILTER 0 +#define CONFIG_EXTRASTEREO_FILTER 0 +#define CONFIG_FIREQUALIZER_FILTER 0 +#define CONFIG_FLANGER_FILTER 0 +#define CONFIG_HAAS_FILTER 0 +#define CONFIG_HDCD_FILTER 0 +#define CONFIG_HEADPHONE_FILTER 0 +#define CONFIG_HIGHPASS_FILTER 0 +#define CONFIG_HIGHSHELF_FILTER 0 +#define CONFIG_JOIN_FILTER 0 +#define CONFIG_LADSPA_FILTER 0 +#define CONFIG_LOUDNORM_FILTER 0 +#define CONFIG_LOWPASS_FILTER 0 +#define CONFIG_LOWSHELF_FILTER 0 +#define CONFIG_LV2_FILTER 0 +#define CONFIG_MCOMPAND_FILTER 0 +#define CONFIG_PAN_FILTER 0 +#define CONFIG_REPLAYGAIN_FILTER 0 +#define CONFIG_RUBBERBAND_FILTER 0 +#define CONFIG_SIDECHAINCOMPRESS_FILTER 0 +#define CONFIG_SIDECHAINGATE_FILTER 0 +#define CONFIG_SILENCEDETECT_FILTER 0 +#define CONFIG_SILENCEREMOVE_FILTER 0 +#define CONFIG_SOFALIZER_FILTER 0 +#define CONFIG_SPEECHNORM_FILTER 0 +#define CONFIG_STEREOTOOLS_FILTER 0 +#define CONFIG_STEREOWIDEN_FILTER 0 +#define CONFIG_SUPEREQUALIZER_FILTER 0 +#define CONFIG_SURROUND_FILTER 0 +#define CONFIG_TILTSHELF_FILTER 0 +#define CONFIG_TREBLE_FILTER 0 +#define CONFIG_TREMOLO_FILTER 0 +#define CONFIG_VIBRATO_FILTER 0 +#define CONFIG_VIRTUALBASS_FILTER 0 +#define CONFIG_VOLUME_FILTER 0 +#define CONFIG_VOLUMEDETECT_FILTER 0 +#define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 +#define CONFIG_AFIRSRC_FILTER 0 +#define CONFIG_ANOISESRC_FILTER 0 +#define CONFIG_ANULLSRC_FILTER 0 +#define CONFIG_FLITE_FILTER 0 +#define CONFIG_HILBERT_FILTER 0 +#define CONFIG_SINC_FILTER 0 +#define CONFIG_SINE_FILTER 0 +#define CONFIG_ANULLSINK_FILTER 0 +#define CONFIG_ADDROI_FILTER 0 +#define CONFIG_ALPHAEXTRACT_FILTER 0 +#define CONFIG_ALPHAMERGE_FILTER 0 +#define CONFIG_AMPLIFY_FILTER 0 +#define CONFIG_ASS_FILTER 0 +#define CONFIG_ATADENOISE_FILTER 0 +#define CONFIG_AVGBLUR_FILTER 0 +#define CONFIG_AVGBLUR_OPENCL_FILTER 0 +#define CONFIG_AVGBLUR_VULKAN_FILTER 0 +#define CONFIG_BACKGROUNDKEY_FILTER 0 +#define CONFIG_BBOX_FILTER 0 +#define CONFIG_BENCH_FILTER 0 +#define CONFIG_BILATERAL_FILTER 0 +#define CONFIG_BILATERAL_CUDA_FILTER 0 +#define CONFIG_BITPLANENOISE_FILTER 0 +#define CONFIG_BLACKDETECT_FILTER 0 +#define CONFIG_BLACKFRAME_FILTER 0 +#define CONFIG_BLEND_FILTER 0 +#define CONFIG_BLEND_VULKAN_FILTER 0 +#define CONFIG_BLOCKDETECT_FILTER 0 +#define CONFIG_BLURDETECT_FILTER 0 +#define CONFIG_BM3D_FILTER 0 +#define CONFIG_BOXBLUR_FILTER 0 +#define CONFIG_BOXBLUR_OPENCL_FILTER 0 +#define CONFIG_BWDIF_FILTER 0 +#define CONFIG_CAS_FILTER 0 +#define CONFIG_CHROMABER_VULKAN_FILTER 0 +#define CONFIG_CHROMAHOLD_FILTER 0 +#define CONFIG_CHROMAKEY_FILTER 0 +#define CONFIG_CHROMAKEY_CUDA_FILTER 0 +#define CONFIG_CHROMANR_FILTER 0 +#define CONFIG_CHROMASHIFT_FILTER 0 +#define CONFIG_CIESCOPE_FILTER 0 +#define CONFIG_CODECVIEW_FILTER 0 +#define CONFIG_COLORBALANCE_FILTER 0 +#define CONFIG_COLORCHANNELMIXER_FILTER 0 +#define CONFIG_COLORCONTRAST_FILTER 0 +#define CONFIG_COLORCORRECT_FILTER 0 +#define CONFIG_COLORIZE_FILTER 0 +#define CONFIG_COLORKEY_FILTER 0 +#define CONFIG_COLORKEY_OPENCL_FILTER 0 +#define CONFIG_COLORHOLD_FILTER 0 +#define CONFIG_COLORLEVELS_FILTER 0 +#define CONFIG_COLORMAP_FILTER 0 +#define CONFIG_COLORMATRIX_FILTER 0 +#define CONFIG_COLORSPACE_FILTER 0 +#define CONFIG_COLORSPACE_CUDA_FILTER 0 +#define CONFIG_COLORTEMPERATURE_FILTER 0 +#define CONFIG_CONVOLUTION_FILTER 0 +#define CONFIG_CONVOLUTION_OPENCL_FILTER 0 +#define CONFIG_CONVOLVE_FILTER 0 +#define CONFIG_COPY_FILTER 0 +#define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 +#define CONFIG_COVER_RECT_FILTER 0 +#define CONFIG_CROP_FILTER 0 +#define CONFIG_CROPDETECT_FILTER 0 +#define CONFIG_CUE_FILTER 0 +#define CONFIG_CURVES_FILTER 0 +#define CONFIG_DATASCOPE_FILTER 0 +#define CONFIG_DBLUR_FILTER 0 +#define CONFIG_DCTDNOIZ_FILTER 0 +#define CONFIG_DEBAND_FILTER 0 +#define CONFIG_DEBLOCK_FILTER 0 +#define CONFIG_DECIMATE_FILTER 0 +#define CONFIG_DECONVOLVE_FILTER 0 +#define CONFIG_DEDOT_FILTER 0 +#define CONFIG_DEFLATE_FILTER 0 +#define CONFIG_DEFLICKER_FILTER 0 +#define CONFIG_DEINTERLACE_QSV_FILTER 0 +#define CONFIG_DEINTERLACE_VAAPI_FILTER 0 +#define CONFIG_DEJUDDER_FILTER 0 +#define CONFIG_DELOGO_FILTER 0 +#define CONFIG_DENOISE_VAAPI_FILTER 0 +#define CONFIG_DERAIN_FILTER 0 +#define CONFIG_DESHAKE_FILTER 0 +#define CONFIG_DESHAKE_OPENCL_FILTER 0 +#define CONFIG_DESPILL_FILTER 0 +#define CONFIG_DETELECINE_FILTER 0 +#define CONFIG_DILATION_FILTER 0 +#define CONFIG_DILATION_OPENCL_FILTER 0 +#define CONFIG_DISPLACE_FILTER 0 +#define CONFIG_DNN_CLASSIFY_FILTER 0 +#define CONFIG_DNN_DETECT_FILTER 0 +#define CONFIG_DNN_PROCESSING_FILTER 0 +#define CONFIG_DOUBLEWEAVE_FILTER 0 +#define CONFIG_DRAWBOX_FILTER 0 +#define CONFIG_DRAWGRAPH_FILTER 0 +#define CONFIG_DRAWGRID_FILTER 0 +#define CONFIG_DRAWTEXT_FILTER 0 +#define CONFIG_EDGEDETECT_FILTER 0 +#define CONFIG_ELBG_FILTER 0 +#define CONFIG_ENTROPY_FILTER 0 +#define CONFIG_EPX_FILTER 0 +#define CONFIG_EQ_FILTER 0 +#define CONFIG_EROSION_FILTER 0 +#define CONFIG_EROSION_OPENCL_FILTER 0 +#define CONFIG_ESTDIF_FILTER 0 +#define CONFIG_EXPOSURE_FILTER 0 +#define CONFIG_EXTRACTPLANES_FILTER 0 +#define CONFIG_FADE_FILTER 0 +#define CONFIG_FEEDBACK_FILTER 0 +#define CONFIG_FFTDNOIZ_FILTER 0 +#define CONFIG_FFTFILT_FILTER 0 +#define CONFIG_FIELD_FILTER 0 +#define CONFIG_FIELDHINT_FILTER 0 +#define CONFIG_FIELDMATCH_FILTER 0 +#define CONFIG_FIELDORDER_FILTER 0 +#define CONFIG_FILLBORDERS_FILTER 0 +#define CONFIG_FIND_RECT_FILTER 0 +#define CONFIG_FLIP_VULKAN_FILTER 0 +#define CONFIG_FLOODFILL_FILTER 0 +#define CONFIG_FORMAT_FILTER 0 +#define CONFIG_FPS_FILTER 0 +#define CONFIG_FRAMEPACK_FILTER 0 +#define CONFIG_FRAMERATE_FILTER 0 +#define CONFIG_FRAMESTEP_FILTER 0 +#define CONFIG_FREEZEDETECT_FILTER 0 +#define CONFIG_FREEZEFRAMES_FILTER 0 +#define CONFIG_FREI0R_FILTER 0 +#define CONFIG_FSPP_FILTER 0 +#define CONFIG_GBLUR_FILTER 0 +#define CONFIG_GBLUR_VULKAN_FILTER 0 +#define CONFIG_GEQ_FILTER 0 +#define CONFIG_GRADFUN_FILTER 0 +#define CONFIG_GRAPHMONITOR_FILTER 0 +#define CONFIG_GRAYWORLD_FILTER 0 +#define CONFIG_GREYEDGE_FILTER 0 +#define CONFIG_GUIDED_FILTER 0 +#define CONFIG_HALDCLUT_FILTER 0 +#define CONFIG_HFLIP_FILTER 0 +#define CONFIG_HFLIP_VULKAN_FILTER 0 +#define CONFIG_HISTEQ_FILTER 0 +#define CONFIG_HISTOGRAM_FILTER 0 +#define CONFIG_HQDN3D_FILTER 0 +#define CONFIG_HQX_FILTER 0 +#define CONFIG_HSTACK_FILTER 0 +#define CONFIG_HSVHOLD_FILTER 0 +#define CONFIG_HSVKEY_FILTER 0 +#define CONFIG_HUE_FILTER 0 +#define CONFIG_HUESATURATION_FILTER 0 +#define CONFIG_HWDOWNLOAD_FILTER 0 +#define CONFIG_HWMAP_FILTER 0 +#define CONFIG_HWUPLOAD_FILTER 0 +#define CONFIG_HWUPLOAD_CUDA_FILTER 0 +#define CONFIG_HYSTERESIS_FILTER 0 +#define CONFIG_ICCDETECT_FILTER 0 +#define CONFIG_ICCGEN_FILTER 0 +#define CONFIG_IDENTITY_FILTER 0 +#define CONFIG_IDET_FILTER 0 +#define CONFIG_IL_FILTER 0 +#define CONFIG_INFLATE_FILTER 0 +#define CONFIG_INTERLACE_FILTER 0 +#define CONFIG_INTERLEAVE_FILTER 0 +#define CONFIG_KERNDEINT_FILTER 0 +#define CONFIG_KIRSCH_FILTER 0 +#define CONFIG_LAGFUN_FILTER 0 +#define CONFIG_LATENCY_FILTER 0 +#define CONFIG_LENSCORRECTION_FILTER 0 +#define CONFIG_LENSFUN_FILTER 0 +#define CONFIG_LIBPLACEBO_FILTER 0 +#define CONFIG_LIBVMAF_FILTER 0 +#define CONFIG_LIMITDIFF_FILTER 0 +#define CONFIG_LIMITER_FILTER 0 +#define CONFIG_LOOP_FILTER 0 +#define CONFIG_LUMAKEY_FILTER 0 +#define CONFIG_LUT_FILTER 0 +#define CONFIG_LUT1D_FILTER 0 +#define CONFIG_LUT2_FILTER 0 +#define CONFIG_LUT3D_FILTER 0 +#define CONFIG_LUTRGB_FILTER 0 +#define CONFIG_LUTYUV_FILTER 0 +#define CONFIG_MASKEDCLAMP_FILTER 0 +#define CONFIG_MASKEDMAX_FILTER 0 +#define CONFIG_MASKEDMERGE_FILTER 0 +#define CONFIG_MASKEDMIN_FILTER 0 +#define CONFIG_MASKEDTHRESHOLD_FILTER 0 +#define CONFIG_MASKFUN_FILTER 0 +#define CONFIG_MCDEINT_FILTER 0 +#define CONFIG_MEDIAN_FILTER 0 +#define CONFIG_MERGEPLANES_FILTER 0 +#define CONFIG_MESTIMATE_FILTER 0 +#define CONFIG_METADATA_FILTER 0 +#define CONFIG_MIDEQUALIZER_FILTER 0 +#define CONFIG_MINTERPOLATE_FILTER 0 +#define CONFIG_MIX_FILTER 0 +#define CONFIG_MONOCHROME_FILTER 0 +#define CONFIG_MORPHO_FILTER 0 +#define CONFIG_MPDECIMATE_FILTER 0 +#define CONFIG_MSAD_FILTER 0 +#define CONFIG_MULTIPLY_FILTER 0 +#define CONFIG_NEGATE_FILTER 0 +#define CONFIG_NLMEANS_FILTER 0 +#define CONFIG_NLMEANS_OPENCL_FILTER 0 +#define CONFIG_NNEDI_FILTER 0 +#define CONFIG_NOFORMAT_FILTER 0 +#define CONFIG_NOISE_FILTER 0 +#define CONFIG_NORMALIZE_FILTER 0 +#define CONFIG_NULL_FILTER 0 +#define CONFIG_OCR_FILTER 0 +#define CONFIG_OCV_FILTER 0 +#define CONFIG_OSCILLOSCOPE_FILTER 0 +#define CONFIG_OVERLAY_FILTER 0 +#define CONFIG_OVERLAY_OPENCL_FILTER 0 +#define CONFIG_OVERLAY_QSV_FILTER 0 +#define CONFIG_OVERLAY_VAAPI_FILTER 0 +#define CONFIG_OVERLAY_VULKAN_FILTER 0 +#define CONFIG_OVERLAY_CUDA_FILTER 0 +#define CONFIG_OWDENOISE_FILTER 0 +#define CONFIG_PAD_FILTER 0 +#define CONFIG_PAD_OPENCL_FILTER 0 +#define CONFIG_PALETTEGEN_FILTER 0 +#define CONFIG_PALETTEUSE_FILTER 0 +#define CONFIG_PERMS_FILTER 0 +#define CONFIG_PERSPECTIVE_FILTER 0 +#define CONFIG_PHASE_FILTER 0 +#define CONFIG_PHOTOSENSITIVITY_FILTER 0 +#define CONFIG_PIXDESCTEST_FILTER 0 +#define CONFIG_PIXELIZE_FILTER 0 +#define CONFIG_PIXSCOPE_FILTER 0 +#define CONFIG_PP_FILTER 0 +#define CONFIG_PP7_FILTER 0 +#define CONFIG_PREMULTIPLY_FILTER 0 +#define CONFIG_PREWITT_FILTER 0 +#define CONFIG_PREWITT_OPENCL_FILTER 0 +#define CONFIG_PROCAMP_VAAPI_FILTER 0 +#define CONFIG_PROGRAM_OPENCL_FILTER 0 +#define CONFIG_PSEUDOCOLOR_FILTER 0 +#define CONFIG_PSNR_FILTER 0 +#define CONFIG_PULLUP_FILTER 0 +#define CONFIG_QP_FILTER 0 +#define CONFIG_RANDOM_FILTER 0 +#define CONFIG_READEIA608_FILTER 0 +#define CONFIG_READVITC_FILTER 0 +#define CONFIG_REALTIME_FILTER 0 +#define CONFIG_REMAP_FILTER 0 +#define CONFIG_REMAP_OPENCL_FILTER 0 +#define CONFIG_REMOVEGRAIN_FILTER 0 +#define CONFIG_REMOVELOGO_FILTER 0 +#define CONFIG_REPEATFIELDS_FILTER 0 +#define CONFIG_REVERSE_FILTER 0 +#define CONFIG_RGBASHIFT_FILTER 0 +#define CONFIG_ROBERTS_FILTER 0 +#define CONFIG_ROBERTS_OPENCL_FILTER 0 +#define CONFIG_ROTATE_FILTER 0 +#define CONFIG_SAB_FILTER 0 +#define CONFIG_SCALE_FILTER 0 +#define CONFIG_SCALE_CUDA_FILTER 0 +#define CONFIG_SCALE_NPP_FILTER 0 +#define CONFIG_SCALE_QSV_FILTER 0 +#define CONFIG_SCALE_VAAPI_FILTER 0 +#define CONFIG_SCALE_VULKAN_FILTER 0 +#define CONFIG_SCALE2REF_FILTER 0 +#define CONFIG_SCALE2REF_NPP_FILTER 0 +#define CONFIG_SCDET_FILTER 0 +#define CONFIG_SCHARR_FILTER 0 +#define CONFIG_SCROLL_FILTER 0 +#define CONFIG_SEGMENT_FILTER 0 +#define CONFIG_SELECT_FILTER 0 +#define CONFIG_SELECTIVECOLOR_FILTER 0 +#define CONFIG_SENDCMD_FILTER 0 +#define CONFIG_SEPARATEFIELDS_FILTER 0 +#define CONFIG_SETDAR_FILTER 0 +#define CONFIG_SETFIELD_FILTER 0 +#define CONFIG_SETPARAMS_FILTER 0 +#define CONFIG_SETPTS_FILTER 0 +#define CONFIG_SETRANGE_FILTER 0 +#define CONFIG_SETSAR_FILTER 0 +#define CONFIG_SETTB_FILTER 0 +#define CONFIG_SHARPEN_NPP_FILTER 0 +#define CONFIG_SHARPNESS_VAAPI_FILTER 0 +#define CONFIG_SHEAR_FILTER 0 +#define CONFIG_SHOWINFO_FILTER 0 +#define CONFIG_SHOWPALETTE_FILTER 0 +#define CONFIG_SHUFFLEFRAMES_FILTER 0 +#define CONFIG_SHUFFLEPIXELS_FILTER 0 +#define CONFIG_SHUFFLEPLANES_FILTER 0 +#define CONFIG_SIDEDATA_FILTER 0 +#define CONFIG_SIGNALSTATS_FILTER 0 +#define CONFIG_SIGNATURE_FILTER 0 +#define CONFIG_SITI_FILTER 0 +#define CONFIG_SMARTBLUR_FILTER 0 +#define CONFIG_SOBEL_FILTER 0 +#define CONFIG_SOBEL_OPENCL_FILTER 0 +#define CONFIG_SPLIT_FILTER 0 +#define CONFIG_SPP_FILTER 0 +#define CONFIG_SR_FILTER 0 +#define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 +#define CONFIG_STEREO3D_FILTER 0 +#define CONFIG_STREAMSELECT_FILTER 0 +#define CONFIG_SUBTITLES_FILTER 0 +#define CONFIG_SUPER2XSAI_FILTER 0 +#define CONFIG_SWAPRECT_FILTER 0 +#define CONFIG_SWAPUV_FILTER 0 +#define CONFIG_TBLEND_FILTER 0 +#define CONFIG_TELECINE_FILTER 0 +#define CONFIG_THISTOGRAM_FILTER 0 +#define CONFIG_THRESHOLD_FILTER 0 +#define CONFIG_THUMBNAIL_FILTER 0 +#define CONFIG_THUMBNAIL_CUDA_FILTER 0 +#define CONFIG_TILE_FILTER 0 +#define CONFIG_TINTERLACE_FILTER 0 +#define CONFIG_TLUT2_FILTER 0 +#define CONFIG_TMEDIAN_FILTER 0 +#define CONFIG_TMIDEQUALIZER_FILTER 0 +#define CONFIG_TMIX_FILTER 0 +#define CONFIG_TONEMAP_FILTER 0 +#define CONFIG_TONEMAP_OPENCL_FILTER 0 +#define CONFIG_TONEMAP_VAAPI_FILTER 0 +#define CONFIG_TPAD_FILTER 0 +#define CONFIG_TRANSPOSE_FILTER 0 +#define CONFIG_TRANSPOSE_NPP_FILTER 0 +#define CONFIG_TRANSPOSE_OPENCL_FILTER 0 +#define CONFIG_TRANSPOSE_VAAPI_FILTER 0 +#define CONFIG_TRANSPOSE_VULKAN_FILTER 0 +#define CONFIG_TRIM_FILTER 0 +#define CONFIG_UNPREMULTIPLY_FILTER 0 +#define CONFIG_UNSHARP_FILTER 0 +#define CONFIG_UNSHARP_OPENCL_FILTER 0 +#define CONFIG_UNTILE_FILTER 0 +#define CONFIG_USPP_FILTER 0 +#define CONFIG_V360_FILTER 0 +#define CONFIG_VAGUEDENOISER_FILTER 0 +#define CONFIG_VARBLUR_FILTER 0 +#define CONFIG_VECTORSCOPE_FILTER 0 +#define CONFIG_VFLIP_FILTER 0 +#define CONFIG_VFLIP_VULKAN_FILTER 0 +#define CONFIG_VFRDET_FILTER 0 +#define CONFIG_VIBRANCE_FILTER 0 +#define CONFIG_VIDSTABDETECT_FILTER 0 +#define CONFIG_VIDSTABTRANSFORM_FILTER 0 +#define CONFIG_VIF_FILTER 0 +#define CONFIG_VIGNETTE_FILTER 0 +#define CONFIG_VMAFMOTION_FILTER 0 +#define CONFIG_VPP_QSV_FILTER 0 +#define CONFIG_VSTACK_FILTER 0 +#define CONFIG_W3FDIF_FILTER 0 +#define CONFIG_WAVEFORM_FILTER 0 +#define CONFIG_WEAVE_FILTER 0 +#define CONFIG_XBR_FILTER 0 +#define CONFIG_XCORRELATE_FILTER 0 +#define CONFIG_XFADE_FILTER 0 +#define CONFIG_XFADE_OPENCL_FILTER 0 +#define CONFIG_XMEDIAN_FILTER 0 +#define CONFIG_XSTACK_FILTER 0 +#define CONFIG_YADIF_FILTER 0 +#define CONFIG_YADIF_CUDA_FILTER 0 +#define CONFIG_YADIF_VIDEOTOOLBOX_FILTER 0 +#define CONFIG_YAEPBLUR_FILTER 0 +#define CONFIG_ZMQ_FILTER 0 +#define CONFIG_ZOOMPAN_FILTER 0 +#define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 +#define CONFIG_ALLRGB_FILTER 0 +#define CONFIG_ALLYUV_FILTER 0 +#define CONFIG_CELLAUTO_FILTER 0 +#define CONFIG_COLOR_FILTER 0 +#define CONFIG_COLORCHART_FILTER 0 +#define CONFIG_COLORSPECTRUM_FILTER 0 +#define CONFIG_COREIMAGESRC_FILTER 0 +#define CONFIG_DDAGRAB_FILTER 0 +#define CONFIG_FREI0R_SRC_FILTER 0 +#define CONFIG_GRADIENTS_FILTER 0 +#define CONFIG_HALDCLUTSRC_FILTER 0 +#define CONFIG_LIFE_FILTER 0 +#define CONFIG_MANDELBROT_FILTER 0 +#define CONFIG_MPTESTSRC_FILTER 0 +#define CONFIG_NULLSRC_FILTER 0 +#define CONFIG_OPENCLSRC_FILTER 0 +#define CONFIG_PAL75BARS_FILTER 0 +#define CONFIG_PAL100BARS_FILTER 0 +#define CONFIG_RGBTESTSRC_FILTER 0 +#define CONFIG_SIERPINSKI_FILTER 0 +#define CONFIG_SMPTEBARS_FILTER 0 +#define CONFIG_SMPTEHDBARS_FILTER 0 +#define CONFIG_TESTSRC_FILTER 0 +#define CONFIG_TESTSRC2_FILTER 0 +#define CONFIG_YUVTESTSRC_FILTER 0 +#define CONFIG_NULLSINK_FILTER 0 +#define CONFIG_A3DSCOPE_FILTER 0 +#define CONFIG_ABITSCOPE_FILTER 0 +#define CONFIG_ADRAWGRAPH_FILTER 0 +#define CONFIG_AGRAPHMONITOR_FILTER 0 +#define CONFIG_AHISTOGRAM_FILTER 0 +#define CONFIG_APHASEMETER_FILTER 0 +#define CONFIG_AVECTORSCOPE_FILTER 0 +#define CONFIG_CONCAT_FILTER 0 +#define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 +#define CONFIG_SHOWFREQS_FILTER 0 +#define CONFIG_SHOWSPATIAL_FILTER 0 +#define CONFIG_SHOWSPECTRUM_FILTER 0 +#define CONFIG_SHOWSPECTRUMPIC_FILTER 0 +#define CONFIG_SHOWVOLUME_FILTER 0 +#define CONFIG_SHOWWAVES_FILTER 0 +#define CONFIG_SHOWWAVESPIC_FILTER 0 +#define CONFIG_SPECTRUMSYNTH_FILTER 0 +#define CONFIG_AVSYNCTEST_FILTER 0 +#define CONFIG_AMOVIE_FILTER 0 +#define CONFIG_MOVIE_FILTER 0 +#define CONFIG_AFIFO_FILTER 0 +#define CONFIG_FIFO_FILTER 0 +#define CONFIG_AA_DEMUXER 0 +#define CONFIG_AAC_DEMUXER 1 +#define CONFIG_AAX_DEMUXER 0 +#define CONFIG_AC3_DEMUXER 0 +#define CONFIG_ACE_DEMUXER 0 +#define CONFIG_ACM_DEMUXER 0 +#define CONFIG_ACT_DEMUXER 0 +#define CONFIG_ADF_DEMUXER 0 +#define CONFIG_ADP_DEMUXER 0 +#define CONFIG_ADS_DEMUXER 0 +#define CONFIG_ADX_DEMUXER 0 +#define CONFIG_AEA_DEMUXER 0 +#define CONFIG_AFC_DEMUXER 0 +#define CONFIG_AIFF_DEMUXER 0 +#define CONFIG_AIX_DEMUXER 0 +#define CONFIG_ALP_DEMUXER 0 +#define CONFIG_AMR_DEMUXER 0 +#define CONFIG_AMRNB_DEMUXER 0 +#define CONFIG_AMRWB_DEMUXER 0 +#define CONFIG_ANM_DEMUXER 0 +#define CONFIG_APAC_DEMUXER 0 +#define CONFIG_APC_DEMUXER 0 +#define CONFIG_APE_DEMUXER 0 +#define CONFIG_APM_DEMUXER 0 +#define CONFIG_APNG_DEMUXER 0 +#define CONFIG_APTX_DEMUXER 0 +#define CONFIG_APTX_HD_DEMUXER 0 +#define CONFIG_AQTITLE_DEMUXER 0 +#define CONFIG_ARGO_ASF_DEMUXER 0 +#define CONFIG_ARGO_BRP_DEMUXER 0 +#define CONFIG_ARGO_CVG_DEMUXER 0 +#define CONFIG_ASF_DEMUXER 0 +#define CONFIG_ASF_O_DEMUXER 0 +#define CONFIG_ASS_DEMUXER 0 +#define CONFIG_AST_DEMUXER 0 +#define CONFIG_AU_DEMUXER 0 +#define CONFIG_AV1_DEMUXER 0 +#define CONFIG_AVI_DEMUXER 0 +#define CONFIG_AVISYNTH_DEMUXER 0 +#define CONFIG_AVR_DEMUXER 0 +#define CONFIG_AVS_DEMUXER 0 +#define CONFIG_AVS2_DEMUXER 0 +#define CONFIG_AVS3_DEMUXER 0 +#define CONFIG_BETHSOFTVID_DEMUXER 0 +#define CONFIG_BFI_DEMUXER 0 +#define CONFIG_BINTEXT_DEMUXER 0 +#define CONFIG_BINK_DEMUXER 0 +#define CONFIG_BINKA_DEMUXER 0 +#define CONFIG_BIT_DEMUXER 0 +#define CONFIG_BITPACKED_DEMUXER 0 +#define CONFIG_BMV_DEMUXER 0 +#define CONFIG_BFSTM_DEMUXER 0 +#define CONFIG_BRSTM_DEMUXER 0 +#define CONFIG_BOA_DEMUXER 0 +#define CONFIG_BONK_DEMUXER 0 +#define CONFIG_C93_DEMUXER 0 +#define CONFIG_CAF_DEMUXER 0 +#define CONFIG_CAVSVIDEO_DEMUXER 0 +#define CONFIG_CDG_DEMUXER 0 +#define CONFIG_CDXL_DEMUXER 0 +#define CONFIG_CINE_DEMUXER 0 +#define CONFIG_CODEC2_DEMUXER 0 +#define CONFIG_CODEC2RAW_DEMUXER 0 +#define CONFIG_CONCAT_DEMUXER 0 +#define CONFIG_DASH_DEMUXER 0 +#define CONFIG_DATA_DEMUXER 0 +#define CONFIG_DAUD_DEMUXER 0 +#define CONFIG_DCSTR_DEMUXER 0 +#define CONFIG_DERF_DEMUXER 0 +#define CONFIG_DFA_DEMUXER 0 +#define CONFIG_DFPWM_DEMUXER 0 +#define CONFIG_DHAV_DEMUXER 0 +#define CONFIG_DIRAC_DEMUXER 0 +#define CONFIG_DNXHD_DEMUXER 0 +#define CONFIG_DSF_DEMUXER 0 +#define CONFIG_DSICIN_DEMUXER 0 +#define CONFIG_DSS_DEMUXER 0 +#define CONFIG_DTS_DEMUXER 0 +#define CONFIG_DTSHD_DEMUXER 0 +#define CONFIG_DV_DEMUXER 0 +#define CONFIG_DVBSUB_DEMUXER 0 +#define CONFIG_DVBTXT_DEMUXER 0 +#define CONFIG_DXA_DEMUXER 0 +#define CONFIG_EA_DEMUXER 0 +#define CONFIG_EA_CDATA_DEMUXER 0 +#define CONFIG_EAC3_DEMUXER 0 +#define CONFIG_EPAF_DEMUXER 0 +#define CONFIG_FFMETADATA_DEMUXER 0 +#define CONFIG_FILMSTRIP_DEMUXER 0 +#define CONFIG_FITS_DEMUXER 0 +#define CONFIG_FLAC_DEMUXER 1 +#define CONFIG_FLIC_DEMUXER 0 +#define CONFIG_FLV_DEMUXER 0 +#define CONFIG_LIVE_FLV_DEMUXER 0 +#define CONFIG_FOURXM_DEMUXER 0 +#define CONFIG_FRM_DEMUXER 0 +#define CONFIG_FSB_DEMUXER 0 +#define CONFIG_FWSE_DEMUXER 0 +#define CONFIG_G722_DEMUXER 0 +#define CONFIG_G723_1_DEMUXER 0 +#define CONFIG_G726_DEMUXER 0 +#define CONFIG_G726LE_DEMUXER 0 +#define CONFIG_G729_DEMUXER 0 +#define CONFIG_GDV_DEMUXER 0 +#define CONFIG_GENH_DEMUXER 0 +#define CONFIG_GIF_DEMUXER 0 +#define CONFIG_GSM_DEMUXER 0 +#define CONFIG_GXF_DEMUXER 0 +#define CONFIG_H261_DEMUXER 0 +#define CONFIG_H263_DEMUXER 0 +#define CONFIG_H264_DEMUXER 0 +#define CONFIG_HCA_DEMUXER 0 +#define CONFIG_HCOM_DEMUXER 0 +#define CONFIG_HEVC_DEMUXER 0 +#define CONFIG_HLS_DEMUXER 0 +#define CONFIG_HNM_DEMUXER 0 +#define CONFIG_ICO_DEMUXER 0 +#define CONFIG_IDCIN_DEMUXER 0 +#define CONFIG_IDF_DEMUXER 0 +#define CONFIG_IFF_DEMUXER 0 +#define CONFIG_IFV_DEMUXER 0 +#define CONFIG_ILBC_DEMUXER 0 +#define CONFIG_IMAGE2_DEMUXER 0 +#define CONFIG_IMAGE2PIPE_DEMUXER 0 +#define CONFIG_IMAGE2_ALIAS_PIX_DEMUXER 0 +#define CONFIG_IMAGE2_BRENDER_PIX_DEMUXER 0 +#define CONFIG_IMF_DEMUXER 0 +#define CONFIG_INGENIENT_DEMUXER 0 +#define CONFIG_IPMOVIE_DEMUXER 0 +#define CONFIG_IPU_DEMUXER 0 +#define CONFIG_IRCAM_DEMUXER 0 +#define CONFIG_ISS_DEMUXER 0 +#define CONFIG_IV8_DEMUXER 0 +#define CONFIG_IVF_DEMUXER 0 +#define CONFIG_IVR_DEMUXER 0 +#define CONFIG_JACOSUB_DEMUXER 0 +#define CONFIG_JV_DEMUXER 0 +#define CONFIG_KUX_DEMUXER 0 +#define CONFIG_KVAG_DEMUXER 0 +#define CONFIG_LAF_DEMUXER 0 +#define CONFIG_LMLM4_DEMUXER 0 +#define CONFIG_LOAS_DEMUXER 0 +#define CONFIG_LUODAT_DEMUXER 0 +#define CONFIG_LRC_DEMUXER 0 +#define CONFIG_LVF_DEMUXER 0 +#define CONFIG_LXF_DEMUXER 0 +#define CONFIG_M4V_DEMUXER 0 +#define CONFIG_MCA_DEMUXER 0 +#define CONFIG_MCC_DEMUXER 0 +#define CONFIG_MATROSKA_DEMUXER 1 +#define CONFIG_MGSTS_DEMUXER 0 +#define CONFIG_MICRODVD_DEMUXER 0 +#define CONFIG_MJPEG_DEMUXER 0 +#define CONFIG_MJPEG_2000_DEMUXER 0 +#define CONFIG_MLP_DEMUXER 0 +#define CONFIG_MLV_DEMUXER 0 +#define CONFIG_MM_DEMUXER 0 +#define CONFIG_MMF_DEMUXER 0 +#define CONFIG_MODS_DEMUXER 0 +#define CONFIG_MOFLEX_DEMUXER 0 +#define CONFIG_MOV_DEMUXER 1 +#define CONFIG_MP3_DEMUXER 1 +#define CONFIG_MPC_DEMUXER 0 +#define CONFIG_MPC8_DEMUXER 0 +#define CONFIG_MPEGPS_DEMUXER 0 +#define CONFIG_MPEGTS_DEMUXER 0 +#define CONFIG_MPEGTSRAW_DEMUXER 0 +#define CONFIG_MPEGVIDEO_DEMUXER 0 +#define CONFIG_MPJPEG_DEMUXER 0 +#define CONFIG_MPL2_DEMUXER 0 +#define CONFIG_MPSUB_DEMUXER 0 +#define CONFIG_MSF_DEMUXER 0 +#define CONFIG_MSNWC_TCP_DEMUXER 0 +#define CONFIG_MSP_DEMUXER 0 +#define CONFIG_MTAF_DEMUXER 0 +#define CONFIG_MTV_DEMUXER 0 +#define CONFIG_MUSX_DEMUXER 0 +#define CONFIG_MV_DEMUXER 0 +#define CONFIG_MVI_DEMUXER 0 +#define CONFIG_MXF_DEMUXER 0 +#define CONFIG_MXG_DEMUXER 0 +#define CONFIG_NC_DEMUXER 0 +#define CONFIG_NISTSPHERE_DEMUXER 0 +#define CONFIG_NSP_DEMUXER 0 +#define CONFIG_NSV_DEMUXER 0 +#define CONFIG_NUT_DEMUXER 0 +#define CONFIG_NUV_DEMUXER 0 +#define CONFIG_OBU_DEMUXER 0 +#define CONFIG_OGG_DEMUXER 1 +#define CONFIG_OMA_DEMUXER 0 +#define CONFIG_PAF_DEMUXER 0 +#define CONFIG_PCM_ALAW_DEMUXER 0 +#define CONFIG_PCM_MULAW_DEMUXER 0 +#define CONFIG_PCM_VIDC_DEMUXER 0 +#define CONFIG_PCM_F64BE_DEMUXER 0 +#define CONFIG_PCM_F64LE_DEMUXER 0 +#define CONFIG_PCM_F32BE_DEMUXER 0 +#define CONFIG_PCM_F32LE_DEMUXER 0 +#define CONFIG_PCM_S32BE_DEMUXER 0 +#define CONFIG_PCM_S32LE_DEMUXER 0 +#define CONFIG_PCM_S24BE_DEMUXER 0 +#define CONFIG_PCM_S24LE_DEMUXER 0 +#define CONFIG_PCM_S16BE_DEMUXER 0 +#define CONFIG_PCM_S16LE_DEMUXER 0 +#define CONFIG_PCM_S8_DEMUXER 0 +#define CONFIG_PCM_U32BE_DEMUXER 0 +#define CONFIG_PCM_U32LE_DEMUXER 0 +#define CONFIG_PCM_U24BE_DEMUXER 0 +#define CONFIG_PCM_U24LE_DEMUXER 0 +#define CONFIG_PCM_U16BE_DEMUXER 0 +#define CONFIG_PCM_U16LE_DEMUXER 0 +#define CONFIG_PCM_U8_DEMUXER 0 +#define CONFIG_PJS_DEMUXER 0 +#define CONFIG_PMP_DEMUXER 0 +#define CONFIG_PP_BNK_DEMUXER 0 +#define CONFIG_PVA_DEMUXER 0 +#define CONFIG_PVF_DEMUXER 0 +#define CONFIG_QCP_DEMUXER 0 +#define CONFIG_R3D_DEMUXER 0 +#define CONFIG_RAWVIDEO_DEMUXER 0 +#define CONFIG_REALTEXT_DEMUXER 0 +#define CONFIG_REDSPARK_DEMUXER 0 +#define CONFIG_RL2_DEMUXER 0 +#define CONFIG_RM_DEMUXER 0 +#define CONFIG_ROQ_DEMUXER 0 +#define CONFIG_RPL_DEMUXER 0 +#define CONFIG_RSD_DEMUXER 0 +#define CONFIG_RSO_DEMUXER 0 +#define CONFIG_RTP_DEMUXER 0 +#define CONFIG_RTSP_DEMUXER 0 +#define CONFIG_S337M_DEMUXER 0 +#define CONFIG_SAMI_DEMUXER 0 +#define CONFIG_SAP_DEMUXER 0 +#define CONFIG_SBC_DEMUXER 0 +#define CONFIG_SBG_DEMUXER 0 +#define CONFIG_SCC_DEMUXER 0 +#define CONFIG_SCD_DEMUXER 0 +#define CONFIG_SDP_DEMUXER 0 +#define CONFIG_SDR2_DEMUXER 0 +#define CONFIG_SDS_DEMUXER 0 +#define CONFIG_SDX_DEMUXER 0 +#define CONFIG_SEGAFILM_DEMUXER 0 +#define CONFIG_SER_DEMUXER 0 +#define CONFIG_SGA_DEMUXER 0 +#define CONFIG_SHORTEN_DEMUXER 0 +#define CONFIG_SIFF_DEMUXER 0 +#define CONFIG_SIMBIOSIS_IMX_DEMUXER 0 +#define CONFIG_SLN_DEMUXER 0 +#define CONFIG_SMACKER_DEMUXER 0 +#define CONFIG_SMJPEG_DEMUXER 0 +#define CONFIG_SMUSH_DEMUXER 0 +#define CONFIG_SOL_DEMUXER 0 +#define CONFIG_SOX_DEMUXER 0 +#define CONFIG_SPDIF_DEMUXER 0 +#define CONFIG_SRT_DEMUXER 0 +#define CONFIG_STR_DEMUXER 0 +#define CONFIG_STL_DEMUXER 0 +#define CONFIG_SUBVIEWER1_DEMUXER 0 +#define CONFIG_SUBVIEWER_DEMUXER 0 +#define CONFIG_SUP_DEMUXER 0 +#define CONFIG_SVAG_DEMUXER 0 +#define CONFIG_SVS_DEMUXER 0 +#define CONFIG_SWF_DEMUXER 0 +#define CONFIG_TAK_DEMUXER 0 +#define CONFIG_TEDCAPTIONS_DEMUXER 0 +#define CONFIG_THP_DEMUXER 0 +#define CONFIG_THREEDOSTR_DEMUXER 0 +#define CONFIG_TIERTEXSEQ_DEMUXER 0 +#define CONFIG_TMV_DEMUXER 0 +#define CONFIG_TRUEHD_DEMUXER 0 +#define CONFIG_TTA_DEMUXER 0 +#define CONFIG_TXD_DEMUXER 0 +#define CONFIG_TTY_DEMUXER 0 +#define CONFIG_TY_DEMUXER 0 +#define CONFIG_V210_DEMUXER 0 +#define CONFIG_V210X_DEMUXER 0 +#define CONFIG_VAG_DEMUXER 0 +#define CONFIG_VC1_DEMUXER 0 +#define CONFIG_VC1T_DEMUXER 0 +#define CONFIG_VIVIDAS_DEMUXER 0 +#define CONFIG_VIVO_DEMUXER 0 +#define CONFIG_VMD_DEMUXER 0 +#define CONFIG_VOBSUB_DEMUXER 0 +#define CONFIG_VOC_DEMUXER 0 +#define CONFIG_VPK_DEMUXER 0 +#define CONFIG_VPLAYER_DEMUXER 0 +#define CONFIG_VQF_DEMUXER 0 +#define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 +#define CONFIG_WAV_DEMUXER 1 +#define CONFIG_WC3_DEMUXER 0 +#define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 +#define CONFIG_WEBVTT_DEMUXER 0 +#define CONFIG_WSAUD_DEMUXER 0 +#define CONFIG_WSD_DEMUXER 0 +#define CONFIG_WSVQA_DEMUXER 0 +#define CONFIG_WTV_DEMUXER 0 +#define CONFIG_WVE_DEMUXER 0 +#define CONFIG_WV_DEMUXER 0 +#define CONFIG_XA_DEMUXER 0 +#define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 +#define CONFIG_XMV_DEMUXER 0 +#define CONFIG_XVAG_DEMUXER 0 +#define CONFIG_XWMA_DEMUXER 0 +#define CONFIG_YOP_DEMUXER 0 +#define CONFIG_YUV4MPEGPIPE_DEMUXER 0 +#define CONFIG_IMAGE_BMP_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_CRI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_DDS_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_DPX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_EXR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_GEM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_GIF_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_HDR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_J2K_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEGLS_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PAM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PBM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PCX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PFM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGMYUV_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PHM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PHOTOCD_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PICTOR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PNG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PPM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PSD_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_QDRAW_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_QOI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SGI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SVG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_TIFF_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_VBN_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_WEBP_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XBM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XPM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XWD_PIPE_DEMUXER 0 +#define CONFIG_LIBGME_DEMUXER 0 +#define CONFIG_LIBMODPLUG_DEMUXER 0 +#define CONFIG_LIBOPENMPT_DEMUXER 0 +#define CONFIG_VAPOURSYNTH_DEMUXER 0 +#define CONFIG_A64_MUXER 0 +#define CONFIG_AC3_MUXER 0 +#define CONFIG_ADTS_MUXER 0 +#define CONFIG_ADX_MUXER 0 +#define CONFIG_AIFF_MUXER 0 +#define CONFIG_ALP_MUXER 0 +#define CONFIG_AMR_MUXER 0 +#define CONFIG_AMV_MUXER 0 +#define CONFIG_APM_MUXER 0 +#define CONFIG_APNG_MUXER 0 +#define CONFIG_APTX_MUXER 0 +#define CONFIG_APTX_HD_MUXER 0 +#define CONFIG_ARGO_ASF_MUXER 0 +#define CONFIG_ARGO_CVG_MUXER 0 +#define CONFIG_ASF_MUXER 0 +#define CONFIG_ASS_MUXER 0 +#define CONFIG_AST_MUXER 0 +#define CONFIG_ASF_STREAM_MUXER 0 +#define CONFIG_AU_MUXER 0 +#define CONFIG_AVI_MUXER 0 +#define CONFIG_AVIF_MUXER 0 +#define CONFIG_AVM2_MUXER 0 +#define CONFIG_AVS2_MUXER 0 +#define CONFIG_AVS3_MUXER 0 +#define CONFIG_BIT_MUXER 0 +#define CONFIG_CAF_MUXER 0 +#define CONFIG_CAVSVIDEO_MUXER 0 +#define CONFIG_CODEC2_MUXER 0 +#define CONFIG_CODEC2RAW_MUXER 0 +#define CONFIG_CRC_MUXER 0 +#define CONFIG_DASH_MUXER 0 +#define CONFIG_DATA_MUXER 0 +#define CONFIG_DAUD_MUXER 0 +#define CONFIG_DFPWM_MUXER 0 +#define CONFIG_DIRAC_MUXER 0 +#define CONFIG_DNXHD_MUXER 0 +#define CONFIG_DTS_MUXER 0 +#define CONFIG_DV_MUXER 0 +#define CONFIG_EAC3_MUXER 0 +#define CONFIG_F4V_MUXER 0 +#define CONFIG_FFMETADATA_MUXER 0 +#define CONFIG_FIFO_MUXER 0 +#define CONFIG_FIFO_TEST_MUXER 0 +#define CONFIG_FILMSTRIP_MUXER 0 +#define CONFIG_FITS_MUXER 0 +#define CONFIG_FLAC_MUXER 0 +#define CONFIG_FLV_MUXER 0 +#define CONFIG_FRAMECRC_MUXER 0 +#define CONFIG_FRAMEHASH_MUXER 0 +#define CONFIG_FRAMEMD5_MUXER 0 +#define CONFIG_G722_MUXER 0 +#define CONFIG_G723_1_MUXER 0 +#define CONFIG_G726_MUXER 0 +#define CONFIG_G726LE_MUXER 0 +#define CONFIG_GIF_MUXER 0 +#define CONFIG_GSM_MUXER 0 +#define CONFIG_GXF_MUXER 0 +#define CONFIG_H261_MUXER 0 +#define CONFIG_H263_MUXER 0 +#define CONFIG_H264_MUXER 0 +#define CONFIG_HASH_MUXER 0 +#define CONFIG_HDS_MUXER 0 +#define CONFIG_HEVC_MUXER 0 +#define CONFIG_HLS_MUXER 0 +#define CONFIG_ICO_MUXER 0 +#define CONFIG_ILBC_MUXER 0 +#define CONFIG_IMAGE2_MUXER 0 +#define CONFIG_IMAGE2PIPE_MUXER 0 +#define CONFIG_IPOD_MUXER 0 +#define CONFIG_IRCAM_MUXER 0 +#define CONFIG_ISMV_MUXER 0 +#define CONFIG_IVF_MUXER 0 +#define CONFIG_JACOSUB_MUXER 0 +#define CONFIG_KVAG_MUXER 0 +#define CONFIG_LATM_MUXER 0 +#define CONFIG_LRC_MUXER 0 +#define CONFIG_M4V_MUXER 0 +#define CONFIG_MD5_MUXER 0 +#define CONFIG_MATROSKA_MUXER 0 +#define CONFIG_MATROSKA_AUDIO_MUXER 0 +#define CONFIG_MICRODVD_MUXER 0 +#define CONFIG_MJPEG_MUXER 0 +#define CONFIG_MLP_MUXER 0 +#define CONFIG_MMF_MUXER 0 +#define CONFIG_MOV_MUXER 0 +#define CONFIG_MP2_MUXER 0 +#define CONFIG_MP3_MUXER 0 +#define CONFIG_MP4_MUXER 0 +#define CONFIG_MPEG1SYSTEM_MUXER 0 +#define CONFIG_MPEG1VCD_MUXER 0 +#define CONFIG_MPEG1VIDEO_MUXER 0 +#define CONFIG_MPEG2DVD_MUXER 0 +#define CONFIG_MPEG2SVCD_MUXER 0 +#define CONFIG_MPEG2VIDEO_MUXER 0 +#define CONFIG_MPEG2VOB_MUXER 0 +#define CONFIG_MPEGTS_MUXER 0 +#define CONFIG_MPJPEG_MUXER 0 +#define CONFIG_MXF_MUXER 0 +#define CONFIG_MXF_D10_MUXER 0 +#define CONFIG_MXF_OPATOM_MUXER 0 +#define CONFIG_NULL_MUXER 0 +#define CONFIG_NUT_MUXER 0 +#define CONFIG_OBU_MUXER 0 +#define CONFIG_OGA_MUXER 0 +#define CONFIG_OGG_MUXER 0 +#define CONFIG_OGV_MUXER 0 +#define CONFIG_OMA_MUXER 0 +#define CONFIG_OPUS_MUXER 0 +#define CONFIG_PCM_ALAW_MUXER 0 +#define CONFIG_PCM_MULAW_MUXER 0 +#define CONFIG_PCM_VIDC_MUXER 0 +#define CONFIG_PCM_F64BE_MUXER 0 +#define CONFIG_PCM_F64LE_MUXER 0 +#define CONFIG_PCM_F32BE_MUXER 0 +#define CONFIG_PCM_F32LE_MUXER 0 +#define CONFIG_PCM_S32BE_MUXER 0 +#define CONFIG_PCM_S32LE_MUXER 0 +#define CONFIG_PCM_S24BE_MUXER 0 +#define CONFIG_PCM_S24LE_MUXER 0 +#define CONFIG_PCM_S16BE_MUXER 0 +#define CONFIG_PCM_S16LE_MUXER 0 +#define CONFIG_PCM_S8_MUXER 0 +#define CONFIG_PCM_U32BE_MUXER 0 +#define CONFIG_PCM_U32LE_MUXER 0 +#define CONFIG_PCM_U24BE_MUXER 0 +#define CONFIG_PCM_U24LE_MUXER 0 +#define CONFIG_PCM_U16BE_MUXER 0 +#define CONFIG_PCM_U16LE_MUXER 0 +#define CONFIG_PCM_U8_MUXER 0 +#define CONFIG_PSP_MUXER 0 +#define CONFIG_RAWVIDEO_MUXER 0 +#define CONFIG_RM_MUXER 0 +#define CONFIG_ROQ_MUXER 0 +#define CONFIG_RSO_MUXER 0 +#define CONFIG_RTP_MUXER 0 +#define CONFIG_RTP_MPEGTS_MUXER 0 +#define CONFIG_RTSP_MUXER 0 +#define CONFIG_SAP_MUXER 0 +#define CONFIG_SBC_MUXER 0 +#define CONFIG_SCC_MUXER 0 +#define CONFIG_SEGAFILM_MUXER 0 +#define CONFIG_SEGMENT_MUXER 0 +#define CONFIG_STREAM_SEGMENT_MUXER 0 +#define CONFIG_SMJPEG_MUXER 0 +#define CONFIG_SMOOTHSTREAMING_MUXER 0 +#define CONFIG_SOX_MUXER 0 +#define CONFIG_SPX_MUXER 0 +#define CONFIG_SPDIF_MUXER 0 +#define CONFIG_SRT_MUXER 0 +#define CONFIG_STREAMHASH_MUXER 0 +#define CONFIG_SUP_MUXER 0 +#define CONFIG_SWF_MUXER 0 +#define CONFIG_TEE_MUXER 0 +#define CONFIG_TG2_MUXER 0 +#define CONFIG_TGP_MUXER 0 +#define CONFIG_MKVTIMESTAMP_V2_MUXER 0 +#define CONFIG_TRUEHD_MUXER 0 +#define CONFIG_TTA_MUXER 0 +#define CONFIG_TTML_MUXER 0 +#define CONFIG_UNCODEDFRAMECRC_MUXER 0 +#define CONFIG_VC1_MUXER 0 +#define CONFIG_VC1T_MUXER 0 +#define CONFIG_VOC_MUXER 0 +#define CONFIG_W64_MUXER 0 +#define CONFIG_WAV_MUXER 0 +#define CONFIG_WEBM_MUXER 0 +#define CONFIG_WEBM_DASH_MANIFEST_MUXER 0 +#define CONFIG_WEBM_CHUNK_MUXER 0 +#define CONFIG_WEBP_MUXER 0 +#define CONFIG_WEBVTT_MUXER 0 +#define CONFIG_WSAUD_MUXER 0 +#define CONFIG_WTV_MUXER 0 +#define CONFIG_WV_MUXER 0 +#define CONFIG_YUV4MPEGPIPE_MUXER 0 +#define CONFIG_CHROMAPRINT_MUXER 0 +#define CONFIG_ASYNC_PROTOCOL 0 +#define CONFIG_BLURAY_PROTOCOL 0 +#define CONFIG_CACHE_PROTOCOL 0 +#define CONFIG_CONCAT_PROTOCOL 0 +#define CONFIG_CONCATF_PROTOCOL 0 +#define CONFIG_CRYPTO_PROTOCOL 0 +#define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 +#define CONFIG_FFRTMPCRYPT_PROTOCOL 0 +#define CONFIG_FFRTMPHTTP_PROTOCOL 0 +#define CONFIG_FILE_PROTOCOL 0 +#define CONFIG_FTP_PROTOCOL 0 +#define CONFIG_GOPHER_PROTOCOL 0 +#define CONFIG_GOPHERS_PROTOCOL 0 +#define CONFIG_HLS_PROTOCOL 0 +#define CONFIG_HTTP_PROTOCOL 0 +#define CONFIG_HTTPPROXY_PROTOCOL 0 +#define CONFIG_HTTPS_PROTOCOL 0 +#define CONFIG_ICECAST_PROTOCOL 0 +#define CONFIG_MMSH_PROTOCOL 0 +#define CONFIG_MMST_PROTOCOL 0 +#define CONFIG_MD5_PROTOCOL 0 +#define CONFIG_PIPE_PROTOCOL 0 +#define CONFIG_PROMPEG_PROTOCOL 0 +#define CONFIG_RTMP_PROTOCOL 0 +#define CONFIG_RTMPE_PROTOCOL 0 +#define CONFIG_RTMPS_PROTOCOL 0 +#define CONFIG_RTMPT_PROTOCOL 0 +#define CONFIG_RTMPTE_PROTOCOL 0 +#define CONFIG_RTMPTS_PROTOCOL 0 +#define CONFIG_RTP_PROTOCOL 0 +#define CONFIG_SCTP_PROTOCOL 0 +#define CONFIG_SRTP_PROTOCOL 0 +#define CONFIG_SUBFILE_PROTOCOL 0 +#define CONFIG_TEE_PROTOCOL 0 +#define CONFIG_TCP_PROTOCOL 0 +#define CONFIG_TLS_PROTOCOL 0 +#define CONFIG_UDP_PROTOCOL 0 +#define CONFIG_UDPLITE_PROTOCOL 0 +#define CONFIG_UNIX_PROTOCOL 0 +#define CONFIG_LIBAMQP_PROTOCOL 0 +#define CONFIG_LIBRIST_PROTOCOL 0 +#define CONFIG_LIBRTMP_PROTOCOL 0 +#define CONFIG_LIBRTMPE_PROTOCOL 0 +#define CONFIG_LIBRTMPS_PROTOCOL 0 +#define CONFIG_LIBRTMPT_PROTOCOL 0 +#define CONFIG_LIBRTMPTE_PROTOCOL 0 +#define CONFIG_LIBSRT_PROTOCOL 0 +#define CONFIG_LIBSSH_PROTOCOL 0 +#define CONFIG_LIBSMBCLIENT_PROTOCOL 0 +#define CONFIG_LIBZMQ_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 +#endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/bsf_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/bsf_list.c new file mode 100644 index 00000000..7ff70c6e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/bsf_list.c @@ -0,0 +1,2 @@ +static const FFBitStreamFilter * const bitstream_filters[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/codec_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/codec_list.c new file mode 100644 index 00000000..80d0456b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/codec_list.c @@ -0,0 +1,21 @@ +static const FFCodec * const codec_list[] = { + &ff_h264_decoder, + &ff_theora_decoder, + &ff_vp3_decoder, + &ff_vp8_decoder, + &ff_aac_decoder, + &ff_flac_decoder, + &ff_mp3_decoder, + &ff_vorbis_decoder, + &ff_pcm_alaw_decoder, + &ff_pcm_f32le_decoder, + &ff_pcm_mulaw_decoder, + &ff_pcm_s16be_decoder, + &ff_pcm_s16le_decoder, + &ff_pcm_s24be_decoder, + &ff_pcm_s24le_decoder, + &ff_pcm_s32le_decoder, + &ff_pcm_u8_decoder, + &ff_libopus_decoder, + &ff_hevc_decoder, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/parser_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/parser_list.c new file mode 100644 index 00000000..1269282a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavcodec/parser_list.c @@ -0,0 +1,12 @@ +static const AVCodecParser * const parser_list[] = { + &ff_aac_parser, + &ff_flac_parser, + &ff_h264_parser, + &ff_mpegaudio_parser, + &ff_opus_parser, + &ff_vorbis_parser, + &ff_vp3_parser, + &ff_vp8_parser, + &ff_vp9_parser, + &ff_hevc_parser, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/demuxer_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/demuxer_list.c new file mode 100644 index 00000000..920b22bf --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/demuxer_list.c @@ -0,0 +1,9 @@ +static const AVInputFormat * const demuxer_list[] = { + &ff_aac_demuxer, + &ff_flac_demuxer, + &ff_matroska_demuxer, + &ff_mov_demuxer, + &ff_mp3_demuxer, + &ff_ogg_demuxer, + &ff_wav_demuxer, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/muxer_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/muxer_list.c new file mode 100644 index 00000000..f36d9499 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/muxer_list.c @@ -0,0 +1,2 @@ +static const AVOutputFormat * const muxer_list[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/protocol_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/protocol_list.c new file mode 100644 index 00000000..247e1e4c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavformat/protocol_list.c @@ -0,0 +1,2 @@ +static const URLProtocol * const url_protocols[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/avconfig.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/avconfig.h new file mode 100644 index 00000000..c289fbb5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/avconfig.h @@ -0,0 +1,6 @@ +/* Generated by ffmpeg configure */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#define AV_HAVE_FAST_UNALIGNED 1 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/ffversion.h new file mode 100644 index 00000000..52669657 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/ios/arm64/libavutil/ffversion.h @@ -0,0 +1,5 @@ +/* Automatically generated by version.sh, do not manually edit! */ +#ifndef AVUTIL_FFVERSION_H +#define AVUTIL_FFVERSION_H +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" +#endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config.h index 8fabb17a..132da910 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264' --enable-demuxer=aac --enable-parser='aac,h264'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264' --enable-demuxer=aac --enable-parser='aac,h264'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 0 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config_components.h index 4ae9aaf5..756afe79 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux-noasm/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config.h index fe265ffd..be10e6b3 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm-neon/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config.h index e947e3a1..3e7641c2 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config.h index 953be71a..eccafdb8 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.asm index 7878baf5..3f03b23d 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.h index 9a9f81f9..3082b208 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.asm index f85e998f..ea6f7bdb 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.h index c3eb6e53..8ba577c9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/linux/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config.h index a261a7bc..08c0435e 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME darwin #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 1 -#define HAVE_CEXP 1 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.asm index 072ef238..1999473b 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 1 -%define HAVE_CEXP 1 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.h index 498467c3..f4f123da 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=x86_64-apple-macosx' --extra-cflags=-F/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=x86_64 --extra-cflags=-m64 --extra-ldflags='-arch x86_64' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=x86_64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=x86_64 --extra-cflags=-m64 --extra-ldflags='-arch x86_64' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME darwin #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 1 -#define HAVE_CEXP 1 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/mac/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config.h index 3feca4f8..576b3beb 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --arch=aarch64 --as=clang-cl --extra-cflags='--target=arm64-windows' --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --arch=aarch64 --as=clang-cl --extra-cflags='--target=arm64-windows' --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win32 #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.asm index 04672fa4..c1d1af48 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 1 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.h index 741735d8..e4371e17 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=-m32 --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=-m32 --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win32 #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 1 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.asm index 53c7c3d3..73f81773 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 1 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.h index 13824f84..7f5212c1 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --target-os=win64 --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --target-os=win64 --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win64 #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 1 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config_components.h index 72820513..539cd1a5 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chrome/win/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config.h index b8ad02f4..d63a2e2d 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 0 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux-noasm/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config.h index 2df07c15..588afc38 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm-neon/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config.h index c2646c59..528baa2c 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config.h index 9df75f81..1a501c31 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.asm index c59746f7..9c38bd20 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.h index 416d5f45..0cdfe849 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.asm index 81b0e3c8..54b775f1 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 1 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 1 +%define CONFIG_H264_SEI 1 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.h index b9d5a939..392e764c 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld' --enable-decoder='aac,h264,hevc' --enable-demuxer=aac --enable-decoder='aac,h264,hevc' --enable-decoder=mpeg4 --enable-parser='h263,mpeg4video' --enable-demuxer=avi" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 1 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 1 +#define CONFIG_H264_SEI 1 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config_components.h index 00e70c97..944d2f89 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/ChromeOS/linux/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config.h index f0514c71..31b854c6 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi --extra-cflags='--target=arm-linux-androideabi24' --extra-ldflags='--target=arm-linux-androideabi24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/arm-linux-androideabi --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-neon --extra-cflags='-mtune=generic-armv7-a' --extra-cflags='-mfloat-abi=softfp' --extra-cflags='-mfpu=neon'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi --extra-cflags='--target=arm-linux-androideabi24' --extra-ldflags='--target=arm-linux-androideabi24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/arm-linux-androideabi --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-neon --extra-cflags='-mtune=generic-armv7-a' --extra-cflags='-mfloat-abi=softfp' --extra-cflags='-mfpu=neon'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config_components.h index 669c7185..0157fc79 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm-neon/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config.h index 078abad0..fafa9457 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android --extra-cflags='--target=aarch64-linux-android24' --extra-ldflags='--target=aarch64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android --extra-cflags='--target=aarch64-linux-android24' --extra-ldflags='--target=aarch64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config_components.h index 669c7185..0157fc79 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config.h index 4de75e95..81a9ecec 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android --extra-cflags='--target=i686-linux-android24' --extra-ldflags='--target=i686-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/i686-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --disable-x86asm" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android --extra-cflags='--target=i686-linux-android24' --extra-ldflags='--target=i686-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/i686-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --disable-x86asm" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config_components.h index 669c7185..0157fc79 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.asm index 2e424688..e429f840 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 0 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 0 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.h index 43876ed1..d4665e26 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config.h @@ -1,9 +1,9 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/x86_64-linux-android --extra-cflags='--target=x86_64-linux-android24' --extra-ldflags='--target=x86_64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/x86_64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/tguilbert/Code/chromium/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=x86_64" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --enable-small --enable-pic --cc=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --cxx=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --ld=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --enable-cross-compile --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/x86_64-linux-android --extra-cflags='--target=x86_64-linux-android24' --extra-ldflags='--target=x86_64-linux-android24' --extra-ldflags=-L/tmp/fakelinkerscripts --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/x86_64-linux-android --extra-ldflags='--gcc-toolchain=/usr/local/google/home/liberato/src/release_chrome/src/third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/' --target-os=android --arch=x86_64" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" #define CC_IDENT "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 0 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 0 +#define CONFIG_HEVC_SEI 0 #define CONFIG_HPELDSP 0 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config_components.h index 669c7185..0157fc79 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/android/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config.h new file mode 100644 index 00000000..c90abc8c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config.h @@ -0,0 +1,749 @@ +/* Automatically generated by configure - do not modify! */ +#ifndef FFMPEG_CONFIG_H +#define FFMPEG_CONFIG_H +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64'" -- elide long configuration string from binary */ +#define FFMPEG_LICENSE "LGPL version 2.1 or later" +#define CONFIG_THIS_YEAR 2023 +#define FFMPEG_DATADIR "/usr/local/share/ffmpeg" +#define AVCONV_DATADIR "/usr/local/share/ffmpeg" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" +#define OS_NAME darwin +#define av_restrict restrict +#define EXTERN_PREFIX "_" +#define EXTERN_ASM _ +#define BUILDSUF "" +#define SLIBSUF ".dylib" +#define HAVE_MMX2 HAVE_MMXEXT +#define SWS_MAX_FILTER_SIZE 256 +#define ARCH_AARCH64 1 +#define ARCH_ALPHA 0 +#define ARCH_ARM 0 +#define ARCH_AVR32 0 +#define ARCH_AVR32_AP 0 +#define ARCH_AVR32_UC 0 +#define ARCH_BFIN 0 +#define ARCH_IA64 0 +#define ARCH_LOONGARCH 0 +#define ARCH_LOONGARCH32 0 +#define ARCH_LOONGARCH64 0 +#define ARCH_M68K 0 +#define ARCH_MIPS 0 +#define ARCH_MIPS64 0 +#define ARCH_PARISC 0 +#define ARCH_PPC 0 +#define ARCH_PPC64 0 +#define ARCH_RISCV 0 +#define ARCH_S390 0 +#define ARCH_SH4 0 +#define ARCH_SPARC 0 +#define ARCH_SPARC64 0 +#define ARCH_TILEGX 0 +#define ARCH_TILEPRO 0 +#define ARCH_TOMI 0 +#define ARCH_X86 0 +#define ARCH_X86_32 0 +#define ARCH_X86_64 0 +#define HAVE_ARMV5TE 0 +#define HAVE_ARMV6 0 +#define HAVE_ARMV6T2 0 +#define HAVE_ARMV8 1 +#define HAVE_NEON 1 +#define HAVE_VFP 1 +#define HAVE_VFPV3 0 +#define HAVE_SETEND 0 +#define HAVE_ALTIVEC 0 +#define HAVE_DCBZL 0 +#define HAVE_LDBRX 0 +#define HAVE_POWER8 0 +#define HAVE_PPC4XX 0 +#define HAVE_VSX 0 +#define HAVE_RVV 0 +#define HAVE_AESNI 0 +#define HAVE_AMD3DNOW 0 +#define HAVE_AMD3DNOWEXT 0 +#define HAVE_AVX 0 +#define HAVE_AVX2 0 +#define HAVE_AVX512 0 +#define HAVE_AVX512ICL 0 +#define HAVE_FMA3 0 +#define HAVE_FMA4 0 +#define HAVE_MMX 0 +#define HAVE_MMXEXT 0 +#define HAVE_SSE 0 +#define HAVE_SSE2 0 +#define HAVE_SSE3 0 +#define HAVE_SSE4 0 +#define HAVE_SSE42 0 +#define HAVE_SSSE3 0 +#define HAVE_XOP 0 +#define HAVE_CPUNOP 0 +#define HAVE_I686 0 +#define HAVE_MIPSFPU 0 +#define HAVE_MIPS32R2 0 +#define HAVE_MIPS32R5 0 +#define HAVE_MIPS64R2 0 +#define HAVE_MIPS32R6 0 +#define HAVE_MIPS64R6 0 +#define HAVE_MIPSDSP 0 +#define HAVE_MIPSDSPR2 0 +#define HAVE_MSA 0 +#define HAVE_LOONGSON2 0 +#define HAVE_LOONGSON3 0 +#define HAVE_MMI 0 +#define HAVE_LSX 0 +#define HAVE_LASX 0 +#define HAVE_ARMV5TE_EXTERNAL 0 +#define HAVE_ARMV6_EXTERNAL 0 +#define HAVE_ARMV6T2_EXTERNAL 0 +#define HAVE_ARMV8_EXTERNAL 1 +#define HAVE_NEON_EXTERNAL 1 +#define HAVE_VFP_EXTERNAL 1 +#define HAVE_VFPV3_EXTERNAL 0 +#define HAVE_SETEND_EXTERNAL 0 +#define HAVE_ALTIVEC_EXTERNAL 0 +#define HAVE_DCBZL_EXTERNAL 0 +#define HAVE_LDBRX_EXTERNAL 0 +#define HAVE_POWER8_EXTERNAL 0 +#define HAVE_PPC4XX_EXTERNAL 0 +#define HAVE_VSX_EXTERNAL 0 +#define HAVE_RVV_EXTERNAL 0 +#define HAVE_AESNI_EXTERNAL 0 +#define HAVE_AMD3DNOW_EXTERNAL 0 +#define HAVE_AMD3DNOWEXT_EXTERNAL 0 +#define HAVE_AVX_EXTERNAL 0 +#define HAVE_AVX2_EXTERNAL 0 +#define HAVE_AVX512_EXTERNAL 0 +#define HAVE_AVX512ICL_EXTERNAL 0 +#define HAVE_FMA3_EXTERNAL 0 +#define HAVE_FMA4_EXTERNAL 0 +#define HAVE_MMX_EXTERNAL 0 +#define HAVE_MMXEXT_EXTERNAL 0 +#define HAVE_SSE_EXTERNAL 0 +#define HAVE_SSE2_EXTERNAL 0 +#define HAVE_SSE3_EXTERNAL 0 +#define HAVE_SSE4_EXTERNAL 0 +#define HAVE_SSE42_EXTERNAL 0 +#define HAVE_SSSE3_EXTERNAL 0 +#define HAVE_XOP_EXTERNAL 0 +#define HAVE_CPUNOP_EXTERNAL 0 +#define HAVE_I686_EXTERNAL 0 +#define HAVE_MIPSFPU_EXTERNAL 0 +#define HAVE_MIPS32R2_EXTERNAL 0 +#define HAVE_MIPS32R5_EXTERNAL 0 +#define HAVE_MIPS64R2_EXTERNAL 0 +#define HAVE_MIPS32R6_EXTERNAL 0 +#define HAVE_MIPS64R6_EXTERNAL 0 +#define HAVE_MIPSDSP_EXTERNAL 0 +#define HAVE_MIPSDSPR2_EXTERNAL 0 +#define HAVE_MSA_EXTERNAL 0 +#define HAVE_LOONGSON2_EXTERNAL 0 +#define HAVE_LOONGSON3_EXTERNAL 0 +#define HAVE_MMI_EXTERNAL 0 +#define HAVE_LSX_EXTERNAL 0 +#define HAVE_LASX_EXTERNAL 0 +#define HAVE_ARMV5TE_INLINE 0 +#define HAVE_ARMV6_INLINE 0 +#define HAVE_ARMV6T2_INLINE 0 +#define HAVE_ARMV8_INLINE 1 +#define HAVE_NEON_INLINE 1 +#define HAVE_VFP_INLINE 1 +#define HAVE_VFPV3_INLINE 0 +#define HAVE_SETEND_INLINE 0 +#define HAVE_ALTIVEC_INLINE 0 +#define HAVE_DCBZL_INLINE 0 +#define HAVE_LDBRX_INLINE 0 +#define HAVE_POWER8_INLINE 0 +#define HAVE_PPC4XX_INLINE 0 +#define HAVE_VSX_INLINE 0 +#define HAVE_RVV_INLINE 0 +#define HAVE_AESNI_INLINE 0 +#define HAVE_AMD3DNOW_INLINE 0 +#define HAVE_AMD3DNOWEXT_INLINE 0 +#define HAVE_AVX_INLINE 0 +#define HAVE_AVX2_INLINE 0 +#define HAVE_AVX512_INLINE 0 +#define HAVE_AVX512ICL_INLINE 0 +#define HAVE_FMA3_INLINE 0 +#define HAVE_FMA4_INLINE 0 +#define HAVE_MMX_INLINE 0 +#define HAVE_MMXEXT_INLINE 0 +#define HAVE_SSE_INLINE 0 +#define HAVE_SSE2_INLINE 0 +#define HAVE_SSE3_INLINE 0 +#define HAVE_SSE4_INLINE 0 +#define HAVE_SSE42_INLINE 0 +#define HAVE_SSSE3_INLINE 0 +#define HAVE_XOP_INLINE 0 +#define HAVE_CPUNOP_INLINE 0 +#define HAVE_I686_INLINE 0 +#define HAVE_MIPSFPU_INLINE 0 +#define HAVE_MIPS32R2_INLINE 0 +#define HAVE_MIPS32R5_INLINE 0 +#define HAVE_MIPS64R2_INLINE 0 +#define HAVE_MIPS32R6_INLINE 0 +#define HAVE_MIPS64R6_INLINE 0 +#define HAVE_MIPSDSP_INLINE 0 +#define HAVE_MIPSDSPR2_INLINE 0 +#define HAVE_MSA_INLINE 0 +#define HAVE_LOONGSON2_INLINE 0 +#define HAVE_LOONGSON3_INLINE 0 +#define HAVE_MMI_INLINE 0 +#define HAVE_LSX_INLINE 0 +#define HAVE_LASX_INLINE 0 +#define HAVE_ALIGNED_STACK 1 +#define HAVE_FAST_64BIT 1 +#define HAVE_FAST_CLZ 1 +#define HAVE_FAST_CMOV 0 +#define HAVE_FAST_FLOAT16 1 +#define HAVE_LOCAL_ALIGNED 0 +#define HAVE_SIMD_ALIGN_16 1 +#define HAVE_SIMD_ALIGN_32 0 +#define HAVE_SIMD_ALIGN_64 0 +#define HAVE_ATOMIC_CAS_PTR 0 +#define HAVE_MACHINE_RW_BARRIER 0 +#define HAVE_MEMORYBARRIER 0 +#define HAVE_MM_EMPTY 0 +#define HAVE_RDTSC 0 +#define HAVE_SEM_TIMEDWAIT 0 +#define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 +#define HAVE_INLINE_ASM 1 +#define HAVE_SYMVER 0 +#define HAVE_X86ASM 0 +#define HAVE_BIGENDIAN 0 +#define HAVE_FAST_UNALIGNED 1 +#define HAVE_ARPA_INET_H 0 +#define HAVE_ASM_TYPES_H 0 +#define HAVE_CDIO_PARANOIA_H 0 +#define HAVE_CDIO_PARANOIA_PARANOIA_H 0 +#define HAVE_CUDA_H 0 +#define HAVE_DISPATCH_DISPATCH_H 1 +#define HAVE_DEV_BKTR_IOCTL_BT848_H 0 +#define HAVE_DEV_BKTR_IOCTL_METEOR_H 0 +#define HAVE_DEV_IC_BT8XX_H 0 +#define HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H 0 +#define HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H 0 +#define HAVE_DIRECT_H 0 +#define HAVE_DIRENT_H 1 +#define HAVE_DXGIDEBUG_H 0 +#define HAVE_DXVA_H 0 +#define HAVE_ES2_GL_H 0 +#define HAVE_GSM_H 0 +#define HAVE_IO_H 0 +#define HAVE_LINUX_DMA_BUF_H 0 +#define HAVE_LINUX_PERF_EVENT_H 0 +#define HAVE_MACHINE_IOCTL_BT848_H 0 +#define HAVE_MACHINE_IOCTL_METEOR_H 0 +#define HAVE_MALLOC_H 0 +#define HAVE_OPENCV2_CORE_CORE_C_H 0 +#define HAVE_OPENGL_GL3_H 0 +#define HAVE_POLL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_RESOURCE_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_SOUNDCARD_H 0 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_UN_H 1 +#define HAVE_SYS_VIDEOIO_H 0 +#define HAVE_TERMIOS_H 1 +#define HAVE_UDPLITE_H 0 +#define HAVE_UNISTD_H 1 +#define HAVE_VALGRIND_VALGRIND_H 0 /* #define HAVE_VALGRIND_VALGRIND_H 0 -- forced to 0. See https://crbug.com/590440 */ +#define HAVE_WINDOWS_H 0 +#define HAVE_WINSOCK2_H 0 +#define HAVE_INTRINSICS_NEON 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CBRT 1 +#define HAVE_CBRTF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_ERF 1 +#define HAVE_EXP2 1 +#define HAVE_EXP2F 1 +#define HAVE_EXPF 1 +#define HAVE_HYPOT 1 +#define HAVE_ISFINITE 1 +#define HAVE_ISINF 1 +#define HAVE_ISNAN 1 +#define HAVE_LDEXPF 1 +#define HAVE_LLRINT 1 +#define HAVE_LLRINTF 1 +#define HAVE_LOG2 1 +#define HAVE_LOG2F 1 +#define HAVE_LOG10F 1 +#define HAVE_LRINT 1 +#define HAVE_LRINTF 1 +#define HAVE_POWF 1 +#define HAVE_RINT 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SINF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_DOS_PATHS 0 +#define HAVE_LIBC_MSVCRT 0 +#define HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS 0 +#define HAVE_SECTION_DATA_REL_RO 0 +#define HAVE_THREADS 1 +#define HAVE_UWP 0 +#define HAVE_WINRT 0 +#define HAVE_ACCESS 1 +#define HAVE_ALIGNED_MALLOC 0 +#define HAVE_ARC4RANDOM 1 +#define HAVE_CLOCK_GETTIME 0 +#define HAVE_CLOSESOCKET 0 +#define HAVE_COMMANDLINETOARGVW 0 +#define HAVE_FCNTL 1 +#define HAVE_GETADDRINFO 0 +#define HAVE_GETAUXVAL 0 +#define HAVE_GETENV 1 +#define HAVE_GETHRTIME 0 +#define HAVE_GETOPT 1 +#define HAVE_GETMODULEHANDLE 0 +#define HAVE_GETPROCESSAFFINITYMASK 0 +#define HAVE_GETPROCESSMEMORYINFO 0 +#define HAVE_GETPROCESSTIMES 0 +#define HAVE_GETRUSAGE 1 +#define HAVE_GETSTDHANDLE 0 +#define HAVE_GETSYSTEMTIMEASFILETIME 0 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GLOB 1 +#define HAVE_GLXGETPROCADDRESS 0 +#define HAVE_GMTIME_R 1 +#define HAVE_INET_ATON 0 +#define HAVE_ISATTY 1 +#define HAVE_KBHIT 0 +#define HAVE_LOCALTIME_R 1 +#define HAVE_LSTAT 1 +#define HAVE_LZO1X_999_COMPRESS 0 +#define HAVE_MACH_ABSOLUTE_TIME 1 +#define HAVE_MAPVIEWOFFILE 0 +#define HAVE_MEMALIGN 0 +#define HAVE_MKSTEMP 1 +#define HAVE_MMAP 1 +#define HAVE_MPROTECT 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_PEEKNAMEDPIPE 0 +#define HAVE_POSIX_MEMALIGN 1 +#define HAVE_PRCTL 0 +#define HAVE_PTHREAD_CANCEL 1 +#define HAVE_SCHED_GETAFFINITY 0 +#define HAVE_SECITEMIMPORT 0 +#define HAVE_SETCONSOLETEXTATTRIBUTE 0 +#define HAVE_SETCONSOLECTRLHANDLER 0 +#define HAVE_SETDLLDIRECTORY 0 +#define HAVE_SETMODE 0 +#define HAVE_SETRLIMIT 1 +#define HAVE_SLEEP 0 +#define HAVE_STRERROR_R 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTL 1 +#define HAVE_USLEEP 1 +#define HAVE_UTGETOSTYPEFROMSTRING 0 +#define HAVE_VIRTUALALLOC 0 +#define HAVE_WGLGETPROCADDRESS 0 +#define HAVE_BCRYPT 0 +#define HAVE_VAAPI_DRM 0 +#define HAVE_VAAPI_X11 0 +#define HAVE_VDPAU_X11 0 +#define HAVE_PTHREADS 1 +#define HAVE_OS2THREADS 0 +#define HAVE_W32THREADS 0 +#define HAVE_AS_ARCH_DIRECTIVE 0 +#define HAVE_AS_DN_DIRECTIVE 0 +#define HAVE_AS_FPU_DIRECTIVE 0 +#define HAVE_AS_FUNC 0 +#define HAVE_AS_OBJECT_ARCH 0 +#define HAVE_ASM_MOD_Q 0 +#define HAVE_BLOCKS_EXTENSION 1 +#define HAVE_EBP_AVAILABLE 0 +#define HAVE_EBX_AVAILABLE 0 +#define HAVE_GNU_AS 0 +#define HAVE_GNU_WINDRES 0 +#define HAVE_IBM_ASM 0 +#define HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS 0 +#define HAVE_INLINE_ASM_LABELS 1 +#define HAVE_INLINE_ASM_NONLOCAL_LABELS 1 +#define HAVE_PRAGMA_DEPRECATED 1 +#define HAVE_RSYNC_CONTIMEOUT 1 +#define HAVE_SYMVER_ASM_LABEL 0 +#define HAVE_SYMVER_GNU_ASM 0 +/* #define HAVE_VFP_ARGS 0 -- softfp/hardfp selection is done by the chrome build */ +#define HAVE_XFORM_ASM 0 +#define HAVE_XMM_CLOBBERS 0 +#define HAVE_DPI_AWARENESS_CONTEXT 0 +#define HAVE_IDXGIOUTPUT5 0 +#define HAVE_KCMVIDEOCODECTYPE_HEVC 0 +#define HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA 0 +#define HAVE_KCMVIDEOCODECTYPE_VP9 0 +#define HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE 0 +#define HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR 0 +#define HAVE_KCVIMAGEBUFFERYCBCRMATRIX_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERCOLORPRIMARIES_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2020 0 +#define HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_428_1 0 +#define HAVE_SOCKLEN_T 0 +#define HAVE_STRUCT_ADDRINFO 0 +#define HAVE_STRUCT_GROUP_SOURCE_REQ 0 +#define HAVE_STRUCT_IP_MREQ_SOURCE 0 +#define HAVE_STRUCT_IPV6_MREQ 0 +#define HAVE_STRUCT_MSGHDR_MSG_FLAGS 0 +#define HAVE_STRUCT_POLLFD 0 +#define HAVE_STRUCT_RUSAGE_RU_MAXRSS 1 +#define HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE 0 +#define HAVE_STRUCT_SOCKADDR_IN6 0 +#define HAVE_STRUCT_SOCKADDR_SA_LEN 0 +#define HAVE_STRUCT_SOCKADDR_STORAGE 0 +#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 0 +#define HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE 0 +#define HAVE_GZIP 1 +#define HAVE_LIBDRM_GETFB2 0 +#define HAVE_MAKEINFO 0 +#define HAVE_MAKEINFO_HTML 0 +#define HAVE_OPENCL_D3D11 0 +#define HAVE_OPENCL_DRM_ARM 0 +#define HAVE_OPENCL_DRM_BEIGNET 0 +#define HAVE_OPENCL_DXVA2 0 +#define HAVE_OPENCL_VAAPI_BEIGNET 0 +#define HAVE_OPENCL_VAAPI_INTEL_MEDIA 0 +#define HAVE_PERL 1 +#define HAVE_POD2MAN 1 +#define HAVE_TEXI2HTML 0 +#define HAVE_XMLLINT 1 +#define HAVE_ZLIB_GZIP 0 +#define CONFIG_DOC 0 +#define CONFIG_HTMLPAGES 0 +#define CONFIG_MANPAGES 0 +#define CONFIG_PODPAGES 0 +#define CONFIG_TXTPAGES 0 +#define CONFIG_AVIO_LIST_DIR_EXAMPLE 1 +#define CONFIG_AVIO_READING_EXAMPLE 1 +#define CONFIG_DECODE_AUDIO_EXAMPLE 1 +#define CONFIG_DECODE_VIDEO_EXAMPLE 1 +#define CONFIG_DEMUXING_DECODING_EXAMPLE 1 +#define CONFIG_ENCODE_AUDIO_EXAMPLE 1 +#define CONFIG_ENCODE_VIDEO_EXAMPLE 1 +#define CONFIG_EXTRACT_MVS_EXAMPLE 1 +#define CONFIG_FILTER_AUDIO_EXAMPLE 0 +#define CONFIG_FILTERING_AUDIO_EXAMPLE 0 +#define CONFIG_FILTERING_VIDEO_EXAMPLE 0 +#define CONFIG_HTTP_MULTICLIENT_EXAMPLE 1 +#define CONFIG_HW_DECODE_EXAMPLE 1 +#define CONFIG_METADATA_EXAMPLE 1 +#define CONFIG_MUXING_EXAMPLE 0 +#define CONFIG_QSVDEC_EXAMPLE 0 +#define CONFIG_REMUXING_EXAMPLE 1 +#define CONFIG_RESAMPLING_AUDIO_EXAMPLE 0 +#define CONFIG_SCALING_VIDEO_EXAMPLE 0 +#define CONFIG_TRANSCODE_AAC_EXAMPLE 0 +#define CONFIG_TRANSCODING_EXAMPLE 0 +#define CONFIG_VAAPI_ENCODE_EXAMPLE 0 +#define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 +#define CONFIG_AVISYNTH 0 +#define CONFIG_FREI0R 0 +#define CONFIG_LIBCDIO 0 +#define CONFIG_LIBDAVS2 0 +#define CONFIG_LIBRUBBERBAND 0 +#define CONFIG_LIBVIDSTAB 0 +#define CONFIG_LIBX264 0 +#define CONFIG_LIBX265 0 +#define CONFIG_LIBXAVS 0 +#define CONFIG_LIBXAVS2 0 +#define CONFIG_LIBXVID 0 +#define CONFIG_DECKLINK 0 +#define CONFIG_LIBFDK_AAC 0 +#define CONFIG_LIBTLS 0 +#define CONFIG_GMP 0 +#define CONFIG_LIBARIBB24 0 +#define CONFIG_LIBLENSFUN 0 +#define CONFIG_LIBOPENCORE_AMRNB 0 +#define CONFIG_LIBOPENCORE_AMRWB 0 +#define CONFIG_LIBVO_AMRWBENC 0 +#define CONFIG_MBEDTLS 0 +#define CONFIG_RKMPP 0 +#define CONFIG_LIBSMBCLIENT 0 +#define CONFIG_CHROMAPRINT 0 +#define CONFIG_GCRYPT 0 +#define CONFIG_GNUTLS 0 +#define CONFIG_JNI 0 +#define CONFIG_LADSPA 0 +#define CONFIG_LCMS2 0 +#define CONFIG_LIBAOM 0 +#define CONFIG_LIBASS 0 +#define CONFIG_LIBBLURAY 0 +#define CONFIG_LIBBS2B 0 +#define CONFIG_LIBCACA 0 +#define CONFIG_LIBCELT 0 +#define CONFIG_LIBCODEC2 0 +#define CONFIG_LIBDAV1D 0 +#define CONFIG_LIBDC1394 0 +#define CONFIG_LIBDRM 0 +#define CONFIG_LIBFLITE 0 +#define CONFIG_LIBFONTCONFIG 0 +#define CONFIG_LIBFREETYPE 0 +#define CONFIG_LIBFRIBIDI 0 +#define CONFIG_LIBGLSLANG 0 +#define CONFIG_LIBGME 0 +#define CONFIG_LIBGSM 0 +#define CONFIG_LIBIEC61883 0 +#define CONFIG_LIBILBC 0 +#define CONFIG_LIBJACK 0 +#define CONFIG_LIBJXL 0 +#define CONFIG_LIBKLVANC 0 +#define CONFIG_LIBKVAZAAR 0 +#define CONFIG_LIBMODPLUG 0 +#define CONFIG_LIBMP3LAME 0 +#define CONFIG_LIBMYSOFA 0 +#define CONFIG_LIBOPENCV 0 +#define CONFIG_LIBOPENH264 0 +#define CONFIG_LIBOPENJPEG 0 +#define CONFIG_LIBOPENMPT 0 +#define CONFIG_LIBOPENVINO 0 +#define CONFIG_LIBOPUS 1 +#define CONFIG_LIBPLACEBO 0 +#define CONFIG_LIBPULSE 0 +#define CONFIG_LIBRABBITMQ 0 +#define CONFIG_LIBRAV1E 0 +#define CONFIG_LIBRIST 0 +#define CONFIG_LIBRSVG 0 +#define CONFIG_LIBRTMP 0 +#define CONFIG_LIBSHADERC 0 +#define CONFIG_LIBSHINE 0 +#define CONFIG_LIBSMBCLIENT 0 +#define CONFIG_LIBSNAPPY 0 +#define CONFIG_LIBSOXR 0 +#define CONFIG_LIBSPEEX 0 +#define CONFIG_LIBSRT 0 +#define CONFIG_LIBSSH 0 +#define CONFIG_LIBSVTAV1 0 +#define CONFIG_LIBTENSORFLOW 0 +#define CONFIG_LIBTESSERACT 0 +#define CONFIG_LIBTHEORA 0 +#define CONFIG_LIBTWOLAME 0 +#define CONFIG_LIBUAVS3D 0 +#define CONFIG_LIBV4L2 0 +#define CONFIG_LIBVMAF 0 +#define CONFIG_LIBVORBIS 0 +#define CONFIG_LIBVPX 0 +#define CONFIG_LIBWEBP 0 +#define CONFIG_LIBXML2 0 +#define CONFIG_LIBZIMG 0 +#define CONFIG_LIBZMQ 0 +#define CONFIG_LIBZVBI 0 +#define CONFIG_LV2 0 +#define CONFIG_MEDIACODEC 0 +#define CONFIG_OPENAL 0 +#define CONFIG_OPENGL 0 +#define CONFIG_OPENSSL 0 +#define CONFIG_POCKETSPHINX 0 +#define CONFIG_VAPOURSYNTH 0 +#define CONFIG_ALSA 0 +#define CONFIG_APPKIT 0 +#define CONFIG_AVFOUNDATION 0 +#define CONFIG_BZLIB 0 +#define CONFIG_COREIMAGE 0 +#define CONFIG_ICONV 0 +#define CONFIG_LIBXCB 0 +#define CONFIG_LIBXCB_SHM 0 +#define CONFIG_LIBXCB_SHAPE 0 +#define CONFIG_LIBXCB_XFIXES 0 +#define CONFIG_LZMA 0 +#define CONFIG_MEDIAFOUNDATION 0 +#define CONFIG_METAL 0 +#define CONFIG_SCHANNEL 0 +#define CONFIG_SDL2 0 +#define CONFIG_SECURETRANSPORT 0 +#define CONFIG_SNDIO 0 +#define CONFIG_XLIB 0 +#define CONFIG_ZLIB 0 +#define CONFIG_CUDA_NVCC 0 +#define CONFIG_CUDA_SDK 0 +#define CONFIG_LIBNPP 0 +#define CONFIG_LIBMFX 0 +#define CONFIG_LIBVPL 0 +#define CONFIG_MMAL 0 +#define CONFIG_OMX 0 +#define CONFIG_OPENCL 0 +#define CONFIG_AMF 0 +#define CONFIG_AUDIOTOOLBOX 0 +#define CONFIG_CRYSTALHD 0 +#define CONFIG_CUDA 0 +#define CONFIG_CUDA_LLVM 0 +#define CONFIG_CUVID 0 +#define CONFIG_D3D11VA 0 +#define CONFIG_DXVA2 0 +#define CONFIG_FFNVCODEC 0 +#define CONFIG_NVDEC 0 +#define CONFIG_NVENC 0 +#define CONFIG_VAAPI 0 +#define CONFIG_VDPAU 0 +#define CONFIG_VIDEOTOOLBOX 0 +#define CONFIG_VULKAN 0 +#define CONFIG_V4L2_M2M 0 +#define CONFIG_FTRAPV 0 +#define CONFIG_GRAY 0 +#define CONFIG_HARDCODED_TABLES 0 +#define CONFIG_OMX_RPI 0 +#define CONFIG_RUNTIME_CPUDETECT 1 +#define CONFIG_SAFE_BITSTREAM_READER 1 +#define CONFIG_SHARED 0 +#define CONFIG_SMALL 0 +#define CONFIG_STATIC 1 +#define CONFIG_SWSCALE_ALPHA 1 +#define CONFIG_GPL 0 +#define CONFIG_NONFREE 0 +#define CONFIG_VERSION3 0 +#define CONFIG_AVDEVICE 0 +#define CONFIG_AVFILTER 0 +#define CONFIG_SWSCALE 0 +#define CONFIG_POSTPROC 0 +#define CONFIG_AVFORMAT 1 +#define CONFIG_AVCODEC 1 +#define CONFIG_SWRESAMPLE 0 +#define CONFIG_AVUTIL 1 +#define CONFIG_FFPLAY 0 +#define CONFIG_FFPROBE 0 +#define CONFIG_FFMPEG 0 +#define CONFIG_DCT 1 +#define CONFIG_DWT 0 +#define CONFIG_ERROR_RESILIENCE 0 +#define CONFIG_FAAN 0 +#define CONFIG_FAST_UNALIGNED 1 +#define CONFIG_FFT 1 +#define CONFIG_LSP 0 +#define CONFIG_MDCT 0 +#define CONFIG_PIXELUTILS 0 +#define CONFIG_NETWORK 0 +#define CONFIG_RDFT 1 +#define CONFIG_AUTODETECT 0 +#define CONFIG_FONTCONFIG 0 +#define CONFIG_LARGE_TESTS 1 +#define CONFIG_LINUX_PERF 0 +#define CONFIG_MACOS_KPERF 0 +#define CONFIG_MEMORY_POISONING 0 +#define CONFIG_NEON_CLOBBER_TEST 0 +#define CONFIG_OSSFUZZ 0 +#define CONFIG_PIC 1 +#define CONFIG_PTX_COMPRESSION 0 +#define CONFIG_THUMB 0 +#define CONFIG_VALGRIND_BACKTRACE 0 +#define CONFIG_XMM_CLOBBER_TEST 0 +#define CONFIG_BSFS 0 +#define CONFIG_DECODERS 1 +#define CONFIG_ENCODERS 0 +#define CONFIG_HWACCELS 0 +#define CONFIG_PARSERS 1 +#define CONFIG_INDEVS 0 +#define CONFIG_OUTDEVS 0 +#define CONFIG_FILTERS 0 +#define CONFIG_DEMUXERS 1 +#define CONFIG_MUXERS 0 +#define CONFIG_PROTOCOLS 0 +#define CONFIG_AANDCTTABLES 0 +#define CONFIG_AC3DSP 0 +#define CONFIG_ADTS_HEADER 0 +#define CONFIG_ATSC_A53 0 +#define CONFIG_AUDIO_FRAME_QUEUE 0 +#define CONFIG_AUDIODSP 0 +#define CONFIG_BLOCKDSP 0 +#define CONFIG_BSWAPDSP 1 +#define CONFIG_CABAC 0 +#define CONFIG_CBS 0 +#define CONFIG_CBS_AV1 0 +#define CONFIG_CBS_H264 0 +#define CONFIG_CBS_H265 0 +#define CONFIG_CBS_JPEG 0 +#define CONFIG_CBS_MPEG2 0 +#define CONFIG_CBS_VP9 0 +#define CONFIG_DEFLATE_WRAPPER 0 +#define CONFIG_DIRAC_PARSE 1 +#define CONFIG_DNN 0 +#define CONFIG_DOVI_RPU 1 +#define CONFIG_DVPROFILE 0 +#define CONFIG_EXIF 0 +#define CONFIG_FAANDCT 0 +#define CONFIG_FAANIDCT 0 +#define CONFIG_FDCTDSP 0 +#define CONFIG_FMTCONVERT 0 +#define CONFIG_FRAME_THREAD_ENCODER 0 +#define CONFIG_G722DSP 0 +#define CONFIG_GOLOMB 1 +#define CONFIG_GPLV3 0 +#define CONFIG_H263DSP 0 +#define CONFIG_H264CHROMA 0 +#define CONFIG_H264DSP 0 +#define CONFIG_H264PARSE 0 +#define CONFIG_H264PRED 1 +#define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 +#define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 +#define CONFIG_HPELDSP 1 +#define CONFIG_HUFFMAN 0 +#define CONFIG_HUFFYUVDSP 0 +#define CONFIG_HUFFYUVENCDSP 0 +#define CONFIG_IDCTDSP 0 +#define CONFIG_IIRFILTER 0 +#define CONFIG_INFLATE_WRAPPER 0 +#define CONFIG_INTRAX8 0 +#define CONFIG_ISO_MEDIA 1 +#define CONFIG_IVIDSP 0 +#define CONFIG_JPEGTABLES 0 +#define CONFIG_LGPLV3 0 +#define CONFIG_LIBX262 0 +#define CONFIG_LLAUDDSP 0 +#define CONFIG_LLVIDDSP 0 +#define CONFIG_LLVIDENCDSP 0 +#define CONFIG_LPC 0 +#define CONFIG_LZF 0 +#define CONFIG_ME_CMP 0 +#define CONFIG_MPEG_ER 0 +#define CONFIG_MPEGAUDIO 1 +#define CONFIG_MPEGAUDIODSP 1 +#define CONFIG_MPEGAUDIOHEADER 1 +#define CONFIG_MPEG4AUDIO 1 +#define CONFIG_MPEGVIDEO 0 +#define CONFIG_MPEGVIDEODEC 0 +#define CONFIG_MPEGVIDEOENC 0 +#define CONFIG_MSMPEG4DEC 0 +#define CONFIG_MSMPEG4ENC 0 +#define CONFIG_MSS34DSP 0 +#define CONFIG_PIXBLOCKDSP 0 +#define CONFIG_QPELDSP 0 +#define CONFIG_QSV 0 +#define CONFIG_QSVDEC 0 +#define CONFIG_QSVENC 0 +#define CONFIG_QSVVPP 0 +#define CONFIG_RANGECODER 0 +#define CONFIG_RIFFDEC 1 +#define CONFIG_RIFFENC 0 +#define CONFIG_RTPDEC 0 +#define CONFIG_RTPENC_CHAIN 0 +#define CONFIG_RV34DSP 0 +#define CONFIG_SCENE_SAD 0 +#define CONFIG_SINEWIN 0 +#define CONFIG_SNAPPY 0 +#define CONFIG_SRTP 0 +#define CONFIG_STARTCODE 0 +#define CONFIG_TEXTUREDSP 0 +#define CONFIG_TEXTUREDSPENC 0 +#define CONFIG_TPELDSP 0 +#define CONFIG_VAAPI_1 0 +#define CONFIG_VAAPI_ENCODE 0 +#define CONFIG_VC1DSP 0 +#define CONFIG_VIDEODSP 1 +#define CONFIG_VP3DSP 1 +#define CONFIG_VP56DSP 0 +#define CONFIG_VP8DSP 1 +#define CONFIG_WMA_FREQS 0 +#define CONFIG_WMV2DSP 0 +#endif /* FFMPEG_CONFIG_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config_components.h new file mode 100644 index 00000000..397677d9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/config_components.h @@ -0,0 +1,2146 @@ +/* Automatically generated by configure - do not modify! */ +#ifndef FFMPEG_CONFIG_COMPONENTS_H +#define FFMPEG_CONFIG_COMPONENTS_H +#define CONFIG_AAC_ADTSTOASC_BSF 0 +#define CONFIG_AV1_FRAME_MERGE_BSF 0 +#define CONFIG_AV1_FRAME_SPLIT_BSF 0 +#define CONFIG_AV1_METADATA_BSF 0 +#define CONFIG_CHOMP_BSF 0 +#define CONFIG_DUMP_EXTRADATA_BSF 0 +#define CONFIG_DCA_CORE_BSF 0 +#define CONFIG_DTS2PTS_BSF 0 +#define CONFIG_DV_ERROR_MARKER_BSF 0 +#define CONFIG_EAC3_CORE_BSF 0 +#define CONFIG_EXTRACT_EXTRADATA_BSF 0 +#define CONFIG_FILTER_UNITS_BSF 0 +#define CONFIG_H264_METADATA_BSF 0 +#define CONFIG_H264_MP4TOANNEXB_BSF 0 +#define CONFIG_H264_REDUNDANT_PPS_BSF 0 +#define CONFIG_HAPQA_EXTRACT_BSF 0 +#define CONFIG_HEVC_METADATA_BSF 0 +#define CONFIG_HEVC_MP4TOANNEXB_BSF 0 +#define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 +#define CONFIG_MJPEG2JPEG_BSF 0 +#define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 +#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 +#define CONFIG_MPEG2_METADATA_BSF 0 +#define CONFIG_MPEG4_UNPACK_BFRAMES_BSF 0 +#define CONFIG_MOV2TEXTSUB_BSF 0 +#define CONFIG_NOISE_BSF 0 +#define CONFIG_NULL_BSF 0 +#define CONFIG_OPUS_METADATA_BSF 0 +#define CONFIG_PCM_RECHUNK_BSF 0 +#define CONFIG_PGS_FRAME_MERGE_BSF 0 +#define CONFIG_PRORES_METADATA_BSF 0 +#define CONFIG_REMOVE_EXTRADATA_BSF 0 +#define CONFIG_SETTS_BSF 0 +#define CONFIG_TEXT2MOVSUB_BSF 0 +#define CONFIG_TRACE_HEADERS_BSF 0 +#define CONFIG_TRUEHD_CORE_BSF 0 +#define CONFIG_VP9_METADATA_BSF 0 +#define CONFIG_VP9_RAW_REORDER_BSF 0 +#define CONFIG_VP9_SUPERFRAME_BSF 0 +#define CONFIG_VP9_SUPERFRAME_SPLIT_BSF 0 +#define CONFIG_AASC_DECODER 0 +#define CONFIG_AIC_DECODER 0 +#define CONFIG_ALIAS_PIX_DECODER 0 +#define CONFIG_AGM_DECODER 0 +#define CONFIG_AMV_DECODER 0 +#define CONFIG_ANM_DECODER 0 +#define CONFIG_ANSI_DECODER 0 +#define CONFIG_APNG_DECODER 0 +#define CONFIG_ARBC_DECODER 0 +#define CONFIG_ARGO_DECODER 0 +#define CONFIG_ASV1_DECODER 0 +#define CONFIG_ASV2_DECODER 0 +#define CONFIG_AURA_DECODER 0 +#define CONFIG_AURA2_DECODER 0 +#define CONFIG_AVRP_DECODER 0 +#define CONFIG_AVRN_DECODER 0 +#define CONFIG_AVS_DECODER 0 +#define CONFIG_AVUI_DECODER 0 +#define CONFIG_AYUV_DECODER 0 +#define CONFIG_BETHSOFTVID_DECODER 0 +#define CONFIG_BFI_DECODER 0 +#define CONFIG_BINK_DECODER 0 +#define CONFIG_BITPACKED_DECODER 0 +#define CONFIG_BMP_DECODER 0 +#define CONFIG_BMV_VIDEO_DECODER 0 +#define CONFIG_BRENDER_PIX_DECODER 0 +#define CONFIG_C93_DECODER 0 +#define CONFIG_CAVS_DECODER 0 +#define CONFIG_CDGRAPHICS_DECODER 0 +#define CONFIG_CDTOONS_DECODER 0 +#define CONFIG_CDXL_DECODER 0 +#define CONFIG_CFHD_DECODER 0 +#define CONFIG_CINEPAK_DECODER 0 +#define CONFIG_CLEARVIDEO_DECODER 0 +#define CONFIG_CLJR_DECODER 0 +#define CONFIG_CLLC_DECODER 0 +#define CONFIG_COMFORTNOISE_DECODER 0 +#define CONFIG_CPIA_DECODER 0 +#define CONFIG_CRI_DECODER 0 +#define CONFIG_CSCD_DECODER 0 +#define CONFIG_CYUV_DECODER 0 +#define CONFIG_DDS_DECODER 0 +#define CONFIG_DFA_DECODER 0 +#define CONFIG_DIRAC_DECODER 0 +#define CONFIG_DNXHD_DECODER 0 +#define CONFIG_DPX_DECODER 0 +#define CONFIG_DSICINVIDEO_DECODER 0 +#define CONFIG_DVAUDIO_DECODER 0 +#define CONFIG_DVVIDEO_DECODER 0 +#define CONFIG_DXA_DECODER 0 +#define CONFIG_DXTORY_DECODER 0 +#define CONFIG_DXV_DECODER 0 +#define CONFIG_EACMV_DECODER 0 +#define CONFIG_EAMAD_DECODER 0 +#define CONFIG_EATGQ_DECODER 0 +#define CONFIG_EATGV_DECODER 0 +#define CONFIG_EATQI_DECODER 0 +#define CONFIG_EIGHTBPS_DECODER 0 +#define CONFIG_EIGHTSVX_EXP_DECODER 0 +#define CONFIG_EIGHTSVX_FIB_DECODER 0 +#define CONFIG_ESCAPE124_DECODER 0 +#define CONFIG_ESCAPE130_DECODER 0 +#define CONFIG_EXR_DECODER 0 +#define CONFIG_FFV1_DECODER 0 +#define CONFIG_FFVHUFF_DECODER 0 +#define CONFIG_FIC_DECODER 0 +#define CONFIG_FITS_DECODER 0 +#define CONFIG_FLASHSV_DECODER 0 +#define CONFIG_FLASHSV2_DECODER 0 +#define CONFIG_FLIC_DECODER 0 +#define CONFIG_FLV_DECODER 0 +#define CONFIG_FMVC_DECODER 0 +#define CONFIG_FOURXM_DECODER 0 +#define CONFIG_FRAPS_DECODER 0 +#define CONFIG_FRWU_DECODER 0 +#define CONFIG_G2M_DECODER 0 +#define CONFIG_GDV_DECODER 0 +#define CONFIG_GEM_DECODER 0 +#define CONFIG_GIF_DECODER 0 +#define CONFIG_H261_DECODER 0 +#define CONFIG_H263_DECODER 0 +#define CONFIG_H263I_DECODER 0 +#define CONFIG_H263P_DECODER 0 +#define CONFIG_H263_V4L2M2M_DECODER 0 +#define CONFIG_H264_DECODER 0 +#define CONFIG_H264_CRYSTALHD_DECODER 0 +#define CONFIG_H264_V4L2M2M_DECODER 0 +#define CONFIG_H264_MEDIACODEC_DECODER 0 +#define CONFIG_H264_MMAL_DECODER 0 +#define CONFIG_H264_QSV_DECODER 0 +#define CONFIG_H264_RKMPP_DECODER 0 +#define CONFIG_HAP_DECODER 0 +#define CONFIG_HEVC_DECODER 1 +#define CONFIG_HEVC_QSV_DECODER 0 +#define CONFIG_HEVC_RKMPP_DECODER 0 +#define CONFIG_HEVC_V4L2M2M_DECODER 0 +#define CONFIG_HNM4_VIDEO_DECODER 0 +#define CONFIG_HQ_HQA_DECODER 0 +#define CONFIG_HQX_DECODER 0 +#define CONFIG_HUFFYUV_DECODER 0 +#define CONFIG_HYMT_DECODER 0 +#define CONFIG_IDCIN_DECODER 0 +#define CONFIG_IFF_ILBM_DECODER 0 +#define CONFIG_IMM4_DECODER 0 +#define CONFIG_IMM5_DECODER 0 +#define CONFIG_INDEO2_DECODER 0 +#define CONFIG_INDEO3_DECODER 0 +#define CONFIG_INDEO4_DECODER 0 +#define CONFIG_INDEO5_DECODER 0 +#define CONFIG_INTERPLAY_VIDEO_DECODER 0 +#define CONFIG_IPU_DECODER 0 +#define CONFIG_JPEG2000_DECODER 0 +#define CONFIG_JPEGLS_DECODER 0 +#define CONFIG_JV_DECODER 0 +#define CONFIG_KGV1_DECODER 0 +#define CONFIG_KMVC_DECODER 0 +#define CONFIG_LAGARITH_DECODER 0 +#define CONFIG_LOCO_DECODER 0 +#define CONFIG_LSCR_DECODER 0 +#define CONFIG_M101_DECODER 0 +#define CONFIG_MAGICYUV_DECODER 0 +#define CONFIG_MDEC_DECODER 0 +#define CONFIG_MEDIA100_DECODER 0 +#define CONFIG_MIMIC_DECODER 0 +#define CONFIG_MJPEG_DECODER 0 +#define CONFIG_MJPEGB_DECODER 0 +#define CONFIG_MMVIDEO_DECODER 0 +#define CONFIG_MOBICLIP_DECODER 0 +#define CONFIG_MOTIONPIXELS_DECODER 0 +#define CONFIG_MPEG1VIDEO_DECODER 0 +#define CONFIG_MPEG2VIDEO_DECODER 0 +#define CONFIG_MPEG4_DECODER 0 +#define CONFIG_MPEG4_CRYSTALHD_DECODER 0 +#define CONFIG_MPEG4_V4L2M2M_DECODER 0 +#define CONFIG_MPEG4_MMAL_DECODER 0 +#define CONFIG_MPEGVIDEO_DECODER 0 +#define CONFIG_MPEG1_V4L2M2M_DECODER 0 +#define CONFIG_MPEG2_MMAL_DECODER 0 +#define CONFIG_MPEG2_CRYSTALHD_DECODER 0 +#define CONFIG_MPEG2_V4L2M2M_DECODER 0 +#define CONFIG_MPEG2_QSV_DECODER 0 +#define CONFIG_MPEG2_MEDIACODEC_DECODER 0 +#define CONFIG_MSA1_DECODER 0 +#define CONFIG_MSCC_DECODER 0 +#define CONFIG_MSMPEG4V1_DECODER 0 +#define CONFIG_MSMPEG4V2_DECODER 0 +#define CONFIG_MSMPEG4V3_DECODER 0 +#define CONFIG_MSMPEG4_CRYSTALHD_DECODER 0 +#define CONFIG_MSP2_DECODER 0 +#define CONFIG_MSRLE_DECODER 0 +#define CONFIG_MSS1_DECODER 0 +#define CONFIG_MSS2_DECODER 0 +#define CONFIG_MSVIDEO1_DECODER 0 +#define CONFIG_MSZH_DECODER 0 +#define CONFIG_MTS2_DECODER 0 +#define CONFIG_MV30_DECODER 0 +#define CONFIG_MVC1_DECODER 0 +#define CONFIG_MVC2_DECODER 0 +#define CONFIG_MVDV_DECODER 0 +#define CONFIG_MVHA_DECODER 0 +#define CONFIG_MWSC_DECODER 0 +#define CONFIG_MXPEG_DECODER 0 +#define CONFIG_NOTCHLC_DECODER 0 +#define CONFIG_NUV_DECODER 0 +#define CONFIG_PAF_VIDEO_DECODER 0 +#define CONFIG_PAM_DECODER 0 +#define CONFIG_PBM_DECODER 0 +#define CONFIG_PCX_DECODER 0 +#define CONFIG_PFM_DECODER 0 +#define CONFIG_PGM_DECODER 0 +#define CONFIG_PGMYUV_DECODER 0 +#define CONFIG_PGX_DECODER 0 +#define CONFIG_PHM_DECODER 0 +#define CONFIG_PHOTOCD_DECODER 0 +#define CONFIG_PICTOR_DECODER 0 +#define CONFIG_PIXLET_DECODER 0 +#define CONFIG_PNG_DECODER 0 +#define CONFIG_PPM_DECODER 0 +#define CONFIG_PRORES_DECODER 0 +#define CONFIG_PROSUMER_DECODER 0 +#define CONFIG_PSD_DECODER 0 +#define CONFIG_PTX_DECODER 0 +#define CONFIG_QDRAW_DECODER 0 +#define CONFIG_QOI_DECODER 0 +#define CONFIG_QPEG_DECODER 0 +#define CONFIG_QTRLE_DECODER 0 +#define CONFIG_R10K_DECODER 0 +#define CONFIG_R210_DECODER 0 +#define CONFIG_RASC_DECODER 0 +#define CONFIG_RAWVIDEO_DECODER 0 +#define CONFIG_RL2_DECODER 0 +#define CONFIG_ROQ_DECODER 0 +#define CONFIG_RPZA_DECODER 0 +#define CONFIG_RSCC_DECODER 0 +#define CONFIG_RV10_DECODER 0 +#define CONFIG_RV20_DECODER 0 +#define CONFIG_RV30_DECODER 0 +#define CONFIG_RV40_DECODER 0 +#define CONFIG_S302M_DECODER 0 +#define CONFIG_SANM_DECODER 0 +#define CONFIG_SCPR_DECODER 0 +#define CONFIG_SCREENPRESSO_DECODER 0 +#define CONFIG_SGA_DECODER 0 +#define CONFIG_SGI_DECODER 0 +#define CONFIG_SGIRLE_DECODER 0 +#define CONFIG_SHEERVIDEO_DECODER 0 +#define CONFIG_SIMBIOSIS_IMX_DECODER 0 +#define CONFIG_SMACKER_DECODER 0 +#define CONFIG_SMC_DECODER 0 +#define CONFIG_SMVJPEG_DECODER 0 +#define CONFIG_SNOW_DECODER 0 +#define CONFIG_SP5X_DECODER 0 +#define CONFIG_SPEEDHQ_DECODER 0 +#define CONFIG_SPEEX_DECODER 0 +#define CONFIG_SRGC_DECODER 0 +#define CONFIG_SUNRAST_DECODER 0 +#define CONFIG_SVQ1_DECODER 0 +#define CONFIG_SVQ3_DECODER 0 +#define CONFIG_TARGA_DECODER 0 +#define CONFIG_TARGA_Y216_DECODER 0 +#define CONFIG_TDSC_DECODER 0 +#define CONFIG_THEORA_DECODER 1 +#define CONFIG_THP_DECODER 0 +#define CONFIG_TIERTEXSEQVIDEO_DECODER 0 +#define CONFIG_TIFF_DECODER 0 +#define CONFIG_TMV_DECODER 0 +#define CONFIG_TRUEMOTION1_DECODER 0 +#define CONFIG_TRUEMOTION2_DECODER 0 +#define CONFIG_TRUEMOTION2RT_DECODER 0 +#define CONFIG_TSCC_DECODER 0 +#define CONFIG_TSCC2_DECODER 0 +#define CONFIG_TXD_DECODER 0 +#define CONFIG_ULTI_DECODER 0 +#define CONFIG_UTVIDEO_DECODER 0 +#define CONFIG_V210_DECODER 0 +#define CONFIG_V210X_DECODER 0 +#define CONFIG_V308_DECODER 0 +#define CONFIG_V408_DECODER 0 +#define CONFIG_V410_DECODER 0 +#define CONFIG_VB_DECODER 0 +#define CONFIG_VBN_DECODER 0 +#define CONFIG_VBLE_DECODER 0 +#define CONFIG_VC1_DECODER 0 +#define CONFIG_VC1_CRYSTALHD_DECODER 0 +#define CONFIG_VC1IMAGE_DECODER 0 +#define CONFIG_VC1_MMAL_DECODER 0 +#define CONFIG_VC1_QSV_DECODER 0 +#define CONFIG_VC1_V4L2M2M_DECODER 0 +#define CONFIG_VCR1_DECODER 0 +#define CONFIG_VMDVIDEO_DECODER 0 +#define CONFIG_VMNC_DECODER 0 +#define CONFIG_VP3_DECODER 1 +#define CONFIG_VP4_DECODER 0 +#define CONFIG_VP5_DECODER 0 +#define CONFIG_VP6_DECODER 0 +#define CONFIG_VP6A_DECODER 0 +#define CONFIG_VP6F_DECODER 0 +#define CONFIG_VP7_DECODER 0 +#define CONFIG_VP8_DECODER 1 +#define CONFIG_VP8_RKMPP_DECODER 0 +#define CONFIG_VP8_V4L2M2M_DECODER 0 +#define CONFIG_VP9_DECODER 0 +#define CONFIG_VP9_RKMPP_DECODER 0 +#define CONFIG_VP9_V4L2M2M_DECODER 0 +#define CONFIG_VQA_DECODER 0 +#define CONFIG_VQC_DECODER 0 +#define CONFIG_WBMP_DECODER 0 +#define CONFIG_WEBP_DECODER 0 +#define CONFIG_WCMV_DECODER 0 +#define CONFIG_WRAPPED_AVFRAME_DECODER 0 +#define CONFIG_WMV1_DECODER 0 +#define CONFIG_WMV2_DECODER 0 +#define CONFIG_WMV3_DECODER 0 +#define CONFIG_WMV3_CRYSTALHD_DECODER 0 +#define CONFIG_WMV3IMAGE_DECODER 0 +#define CONFIG_WNV1_DECODER 0 +#define CONFIG_XAN_WC3_DECODER 0 +#define CONFIG_XAN_WC4_DECODER 0 +#define CONFIG_XBM_DECODER 0 +#define CONFIG_XFACE_DECODER 0 +#define CONFIG_XL_DECODER 0 +#define CONFIG_XPM_DECODER 0 +#define CONFIG_XWD_DECODER 0 +#define CONFIG_Y41P_DECODER 0 +#define CONFIG_YLC_DECODER 0 +#define CONFIG_YOP_DECODER 0 +#define CONFIG_YUV4_DECODER 0 +#define CONFIG_ZERO12V_DECODER 0 +#define CONFIG_ZEROCODEC_DECODER 0 +#define CONFIG_ZLIB_DECODER 0 +#define CONFIG_ZMBV_DECODER 0 +#define CONFIG_AAC_DECODER 0 +#define CONFIG_AAC_FIXED_DECODER 0 +#define CONFIG_AAC_LATM_DECODER 0 +#define CONFIG_AC3_DECODER 0 +#define CONFIG_AC3_FIXED_DECODER 0 +#define CONFIG_ACELP_KELVIN_DECODER 0 +#define CONFIG_ALAC_DECODER 0 +#define CONFIG_ALS_DECODER 0 +#define CONFIG_AMRNB_DECODER 0 +#define CONFIG_AMRWB_DECODER 0 +#define CONFIG_APAC_DECODER 0 +#define CONFIG_APE_DECODER 0 +#define CONFIG_APTX_DECODER 0 +#define CONFIG_APTX_HD_DECODER 0 +#define CONFIG_ATRAC1_DECODER 0 +#define CONFIG_ATRAC3_DECODER 0 +#define CONFIG_ATRAC3AL_DECODER 0 +#define CONFIG_ATRAC3P_DECODER 0 +#define CONFIG_ATRAC3PAL_DECODER 0 +#define CONFIG_ATRAC9_DECODER 0 +#define CONFIG_BINKAUDIO_DCT_DECODER 0 +#define CONFIG_BINKAUDIO_RDFT_DECODER 0 +#define CONFIG_BMV_AUDIO_DECODER 0 +#define CONFIG_BONK_DECODER 0 +#define CONFIG_COOK_DECODER 0 +#define CONFIG_DCA_DECODER 0 +#define CONFIG_DFPWM_DECODER 0 +#define CONFIG_DOLBY_E_DECODER 0 +#define CONFIG_DSD_LSBF_DECODER 0 +#define CONFIG_DSD_MSBF_DECODER 0 +#define CONFIG_DSD_LSBF_PLANAR_DECODER 0 +#define CONFIG_DSD_MSBF_PLANAR_DECODER 0 +#define CONFIG_DSICINAUDIO_DECODER 0 +#define CONFIG_DSS_SP_DECODER 0 +#define CONFIG_DST_DECODER 0 +#define CONFIG_EAC3_DECODER 0 +#define CONFIG_EVRC_DECODER 0 +#define CONFIG_FASTAUDIO_DECODER 0 +#define CONFIG_FFWAVESYNTH_DECODER 0 +#define CONFIG_FLAC_DECODER 1 +#define CONFIG_FTR_DECODER 0 +#define CONFIG_G723_1_DECODER 0 +#define CONFIG_G729_DECODER 0 +#define CONFIG_GSM_DECODER 0 +#define CONFIG_GSM_MS_DECODER 0 +#define CONFIG_HCA_DECODER 0 +#define CONFIG_HCOM_DECODER 0 +#define CONFIG_HDR_DECODER 0 +#define CONFIG_IAC_DECODER 0 +#define CONFIG_ILBC_DECODER 0 +#define CONFIG_IMC_DECODER 0 +#define CONFIG_INTERPLAY_ACM_DECODER 0 +#define CONFIG_MACE3_DECODER 0 +#define CONFIG_MACE6_DECODER 0 +#define CONFIG_METASOUND_DECODER 0 +#define CONFIG_MISC4_DECODER 0 +#define CONFIG_MLP_DECODER 0 +#define CONFIG_MP1_DECODER 0 +#define CONFIG_MP1FLOAT_DECODER 0 +#define CONFIG_MP2_DECODER 0 +#define CONFIG_MP2FLOAT_DECODER 0 +#define CONFIG_MP3FLOAT_DECODER 0 +#define CONFIG_MP3_DECODER 1 +#define CONFIG_MP3ADUFLOAT_DECODER 0 +#define CONFIG_MP3ADU_DECODER 0 +#define CONFIG_MP3ON4FLOAT_DECODER 0 +#define CONFIG_MP3ON4_DECODER 0 +#define CONFIG_MPC7_DECODER 0 +#define CONFIG_MPC8_DECODER 0 +#define CONFIG_MSNSIREN_DECODER 0 +#define CONFIG_NELLYMOSER_DECODER 0 +#define CONFIG_ON2AVC_DECODER 0 +#define CONFIG_OPUS_DECODER 0 +#define CONFIG_PAF_AUDIO_DECODER 0 +#define CONFIG_QCELP_DECODER 0 +#define CONFIG_QDM2_DECODER 0 +#define CONFIG_QDMC_DECODER 0 +#define CONFIG_RA_144_DECODER 0 +#define CONFIG_RA_288_DECODER 0 +#define CONFIG_RALF_DECODER 0 +#define CONFIG_SBC_DECODER 0 +#define CONFIG_SHORTEN_DECODER 0 +#define CONFIG_SIPR_DECODER 0 +#define CONFIG_SIREN_DECODER 0 +#define CONFIG_SMACKAUD_DECODER 0 +#define CONFIG_SONIC_DECODER 0 +#define CONFIG_TAK_DECODER 0 +#define CONFIG_TRUEHD_DECODER 0 +#define CONFIG_TRUESPEECH_DECODER 0 +#define CONFIG_TTA_DECODER 0 +#define CONFIG_TWINVQ_DECODER 0 +#define CONFIG_VMDAUDIO_DECODER 0 +#define CONFIG_VORBIS_DECODER 1 +#define CONFIG_WAVPACK_DECODER 0 +#define CONFIG_WMALOSSLESS_DECODER 0 +#define CONFIG_WMAPRO_DECODER 0 +#define CONFIG_WMAV1_DECODER 0 +#define CONFIG_WMAV2_DECODER 0 +#define CONFIG_WMAVOICE_DECODER 0 +#define CONFIG_WS_SND1_DECODER 0 +#define CONFIG_XMA1_DECODER 0 +#define CONFIG_XMA2_DECODER 0 +#define CONFIG_PCM_ALAW_DECODER 1 +#define CONFIG_PCM_BLURAY_DECODER 0 +#define CONFIG_PCM_DVD_DECODER 0 +#define CONFIG_PCM_F16LE_DECODER 0 +#define CONFIG_PCM_F24LE_DECODER 0 +#define CONFIG_PCM_F32BE_DECODER 0 +#define CONFIG_PCM_F32LE_DECODER 1 +#define CONFIG_PCM_F64BE_DECODER 0 +#define CONFIG_PCM_F64LE_DECODER 0 +#define CONFIG_PCM_LXF_DECODER 0 +#define CONFIG_PCM_MULAW_DECODER 1 +#define CONFIG_PCM_S8_DECODER 0 +#define CONFIG_PCM_S8_PLANAR_DECODER 0 +#define CONFIG_PCM_S16BE_DECODER 1 +#define CONFIG_PCM_S16BE_PLANAR_DECODER 0 +#define CONFIG_PCM_S16LE_DECODER 1 +#define CONFIG_PCM_S16LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S24BE_DECODER 1 +#define CONFIG_PCM_S24DAUD_DECODER 0 +#define CONFIG_PCM_S24LE_DECODER 1 +#define CONFIG_PCM_S24LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S32BE_DECODER 0 +#define CONFIG_PCM_S32LE_DECODER 1 +#define CONFIG_PCM_S32LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S64BE_DECODER 0 +#define CONFIG_PCM_S64LE_DECODER 0 +#define CONFIG_PCM_SGA_DECODER 0 +#define CONFIG_PCM_U8_DECODER 1 +#define CONFIG_PCM_U16BE_DECODER 0 +#define CONFIG_PCM_U16LE_DECODER 0 +#define CONFIG_PCM_U24BE_DECODER 0 +#define CONFIG_PCM_U24LE_DECODER 0 +#define CONFIG_PCM_U32BE_DECODER 0 +#define CONFIG_PCM_U32LE_DECODER 0 +#define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 +#define CONFIG_DERF_DPCM_DECODER 0 +#define CONFIG_GREMLIN_DPCM_DECODER 0 +#define CONFIG_INTERPLAY_DPCM_DECODER 0 +#define CONFIG_ROQ_DPCM_DECODER 0 +#define CONFIG_SDX2_DPCM_DECODER 0 +#define CONFIG_SOL_DPCM_DECODER 0 +#define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 +#define CONFIG_ADPCM_4XM_DECODER 0 +#define CONFIG_ADPCM_ADX_DECODER 0 +#define CONFIG_ADPCM_AFC_DECODER 0 +#define CONFIG_ADPCM_AGM_DECODER 0 +#define CONFIG_ADPCM_AICA_DECODER 0 +#define CONFIG_ADPCM_ARGO_DECODER 0 +#define CONFIG_ADPCM_CT_DECODER 0 +#define CONFIG_ADPCM_DTK_DECODER 0 +#define CONFIG_ADPCM_EA_DECODER 0 +#define CONFIG_ADPCM_EA_MAXIS_XA_DECODER 0 +#define CONFIG_ADPCM_EA_R1_DECODER 0 +#define CONFIG_ADPCM_EA_R2_DECODER 0 +#define CONFIG_ADPCM_EA_R3_DECODER 0 +#define CONFIG_ADPCM_EA_XAS_DECODER 0 +#define CONFIG_ADPCM_G722_DECODER 0 +#define CONFIG_ADPCM_G726_DECODER 0 +#define CONFIG_ADPCM_G726LE_DECODER 0 +#define CONFIG_ADPCM_IMA_ACORN_DECODER 0 +#define CONFIG_ADPCM_IMA_AMV_DECODER 0 +#define CONFIG_ADPCM_IMA_ALP_DECODER 0 +#define CONFIG_ADPCM_IMA_APC_DECODER 0 +#define CONFIG_ADPCM_IMA_APM_DECODER 0 +#define CONFIG_ADPCM_IMA_CUNNING_DECODER 0 +#define CONFIG_ADPCM_IMA_DAT4_DECODER 0 +#define CONFIG_ADPCM_IMA_DK3_DECODER 0 +#define CONFIG_ADPCM_IMA_DK4_DECODER 0 +#define CONFIG_ADPCM_IMA_EA_EACS_DECODER 0 +#define CONFIG_ADPCM_IMA_EA_SEAD_DECODER 0 +#define CONFIG_ADPCM_IMA_ISS_DECODER 0 +#define CONFIG_ADPCM_IMA_MOFLEX_DECODER 0 +#define CONFIG_ADPCM_IMA_MTF_DECODER 0 +#define CONFIG_ADPCM_IMA_OKI_DECODER 0 +#define CONFIG_ADPCM_IMA_QT_DECODER 0 +#define CONFIG_ADPCM_IMA_RAD_DECODER 0 +#define CONFIG_ADPCM_IMA_SSI_DECODER 0 +#define CONFIG_ADPCM_IMA_SMJPEG_DECODER 0 +#define CONFIG_ADPCM_IMA_WAV_DECODER 0 +#define CONFIG_ADPCM_IMA_WS_DECODER 0 +#define CONFIG_ADPCM_MS_DECODER 0 +#define CONFIG_ADPCM_MTAF_DECODER 0 +#define CONFIG_ADPCM_PSX_DECODER 0 +#define CONFIG_ADPCM_SBPRO_2_DECODER 0 +#define CONFIG_ADPCM_SBPRO_3_DECODER 0 +#define CONFIG_ADPCM_SBPRO_4_DECODER 0 +#define CONFIG_ADPCM_SWF_DECODER 0 +#define CONFIG_ADPCM_THP_DECODER 0 +#define CONFIG_ADPCM_THP_LE_DECODER 0 +#define CONFIG_ADPCM_VIMA_DECODER 0 +#define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 +#define CONFIG_ADPCM_YAMAHA_DECODER 0 +#define CONFIG_ADPCM_ZORK_DECODER 0 +#define CONFIG_SSA_DECODER 0 +#define CONFIG_ASS_DECODER 0 +#define CONFIG_CCAPTION_DECODER 0 +#define CONFIG_DVBSUB_DECODER 0 +#define CONFIG_DVDSUB_DECODER 0 +#define CONFIG_JACOSUB_DECODER 0 +#define CONFIG_MICRODVD_DECODER 0 +#define CONFIG_MOVTEXT_DECODER 0 +#define CONFIG_MPL2_DECODER 0 +#define CONFIG_PGSSUB_DECODER 0 +#define CONFIG_PJS_DECODER 0 +#define CONFIG_REALTEXT_DECODER 0 +#define CONFIG_SAMI_DECODER 0 +#define CONFIG_SRT_DECODER 0 +#define CONFIG_STL_DECODER 0 +#define CONFIG_SUBRIP_DECODER 0 +#define CONFIG_SUBVIEWER_DECODER 0 +#define CONFIG_SUBVIEWER1_DECODER 0 +#define CONFIG_TEXT_DECODER 0 +#define CONFIG_VPLAYER_DECODER 0 +#define CONFIG_WEBVTT_DECODER 0 +#define CONFIG_XSUB_DECODER 0 +#define CONFIG_AAC_AT_DECODER 0 +#define CONFIG_AC3_AT_DECODER 0 +#define CONFIG_ADPCM_IMA_QT_AT_DECODER 0 +#define CONFIG_ALAC_AT_DECODER 0 +#define CONFIG_AMR_NB_AT_DECODER 0 +#define CONFIG_EAC3_AT_DECODER 0 +#define CONFIG_GSM_MS_AT_DECODER 0 +#define CONFIG_ILBC_AT_DECODER 0 +#define CONFIG_MP1_AT_DECODER 0 +#define CONFIG_MP2_AT_DECODER 0 +#define CONFIG_MP3_AT_DECODER 0 +#define CONFIG_PCM_ALAW_AT_DECODER 0 +#define CONFIG_PCM_MULAW_AT_DECODER 0 +#define CONFIG_QDMC_AT_DECODER 0 +#define CONFIG_QDM2_AT_DECODER 0 +#define CONFIG_LIBARIBB24_DECODER 0 +#define CONFIG_LIBCELT_DECODER 0 +#define CONFIG_LIBCODEC2_DECODER 0 +#define CONFIG_LIBDAV1D_DECODER 0 +#define CONFIG_LIBDAVS2_DECODER 0 +#define CONFIG_LIBFDK_AAC_DECODER 0 +#define CONFIG_LIBGSM_DECODER 0 +#define CONFIG_LIBGSM_MS_DECODER 0 +#define CONFIG_LIBILBC_DECODER 0 +#define CONFIG_LIBJXL_DECODER 0 +#define CONFIG_LIBOPENCORE_AMRNB_DECODER 0 +#define CONFIG_LIBOPENCORE_AMRWB_DECODER 0 +#define CONFIG_LIBOPENJPEG_DECODER 0 +#define CONFIG_LIBOPUS_DECODER 1 +#define CONFIG_LIBRSVG_DECODER 0 +#define CONFIG_LIBSPEEX_DECODER 0 +#define CONFIG_LIBUAVS3D_DECODER 0 +#define CONFIG_LIBVORBIS_DECODER 0 +#define CONFIG_LIBVPX_VP8_DECODER 0 +#define CONFIG_LIBVPX_VP9_DECODER 0 +#define CONFIG_LIBZVBI_TELETEXT_DECODER 0 +#define CONFIG_BINTEXT_DECODER 0 +#define CONFIG_XBIN_DECODER 0 +#define CONFIG_IDF_DECODER 0 +#define CONFIG_LIBAOM_AV1_DECODER 0 +#define CONFIG_AV1_DECODER 0 +#define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 +#define CONFIG_AV1_QSV_DECODER 0 +#define CONFIG_LIBOPENH264_DECODER 0 +#define CONFIG_H264_CUVID_DECODER 0 +#define CONFIG_HEVC_CUVID_DECODER 0 +#define CONFIG_HEVC_MEDIACODEC_DECODER 0 +#define CONFIG_MJPEG_CUVID_DECODER 0 +#define CONFIG_MJPEG_QSV_DECODER 0 +#define CONFIG_MPEG1_CUVID_DECODER 0 +#define CONFIG_MPEG2_CUVID_DECODER 0 +#define CONFIG_MPEG4_CUVID_DECODER 0 +#define CONFIG_MPEG4_MEDIACODEC_DECODER 0 +#define CONFIG_VC1_CUVID_DECODER 0 +#define CONFIG_VP8_CUVID_DECODER 0 +#define CONFIG_VP8_MEDIACODEC_DECODER 0 +#define CONFIG_VP8_QSV_DECODER 0 +#define CONFIG_VP9_CUVID_DECODER 0 +#define CONFIG_VP9_MEDIACODEC_DECODER 0 +#define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 +#define CONFIG_A64MULTI_ENCODER 0 +#define CONFIG_A64MULTI5_ENCODER 0 +#define CONFIG_ALIAS_PIX_ENCODER 0 +#define CONFIG_AMV_ENCODER 0 +#define CONFIG_APNG_ENCODER 0 +#define CONFIG_ASV1_ENCODER 0 +#define CONFIG_ASV2_ENCODER 0 +#define CONFIG_AVRP_ENCODER 0 +#define CONFIG_AVUI_ENCODER 0 +#define CONFIG_AYUV_ENCODER 0 +#define CONFIG_BITPACKED_ENCODER 0 +#define CONFIG_BMP_ENCODER 0 +#define CONFIG_CFHD_ENCODER 0 +#define CONFIG_CINEPAK_ENCODER 0 +#define CONFIG_CLJR_ENCODER 0 +#define CONFIG_COMFORTNOISE_ENCODER 0 +#define CONFIG_DNXHD_ENCODER 0 +#define CONFIG_DPX_ENCODER 0 +#define CONFIG_DVVIDEO_ENCODER 0 +#define CONFIG_EXR_ENCODER 0 +#define CONFIG_FFV1_ENCODER 0 +#define CONFIG_FFVHUFF_ENCODER 0 +#define CONFIG_FITS_ENCODER 0 +#define CONFIG_FLASHSV_ENCODER 0 +#define CONFIG_FLASHSV2_ENCODER 0 +#define CONFIG_FLV_ENCODER 0 +#define CONFIG_GIF_ENCODER 0 +#define CONFIG_H261_ENCODER 0 +#define CONFIG_H263_ENCODER 0 +#define CONFIG_H263P_ENCODER 0 +#define CONFIG_H264_MEDIACODEC_ENCODER 0 +#define CONFIG_HAP_ENCODER 0 +#define CONFIG_HUFFYUV_ENCODER 0 +#define CONFIG_JPEG2000_ENCODER 0 +#define CONFIG_JPEGLS_ENCODER 0 +#define CONFIG_LJPEG_ENCODER 0 +#define CONFIG_MAGICYUV_ENCODER 0 +#define CONFIG_MJPEG_ENCODER 0 +#define CONFIG_MPEG1VIDEO_ENCODER 0 +#define CONFIG_MPEG2VIDEO_ENCODER 0 +#define CONFIG_MPEG4_ENCODER 0 +#define CONFIG_MSMPEG4V2_ENCODER 0 +#define CONFIG_MSMPEG4V3_ENCODER 0 +#define CONFIG_MSVIDEO1_ENCODER 0 +#define CONFIG_PAM_ENCODER 0 +#define CONFIG_PBM_ENCODER 0 +#define CONFIG_PCX_ENCODER 0 +#define CONFIG_PFM_ENCODER 0 +#define CONFIG_PGM_ENCODER 0 +#define CONFIG_PGMYUV_ENCODER 0 +#define CONFIG_PHM_ENCODER 0 +#define CONFIG_PNG_ENCODER 0 +#define CONFIG_PPM_ENCODER 0 +#define CONFIG_PRORES_ENCODER 0 +#define CONFIG_PRORES_AW_ENCODER 0 +#define CONFIG_PRORES_KS_ENCODER 0 +#define CONFIG_QOI_ENCODER 0 +#define CONFIG_QTRLE_ENCODER 0 +#define CONFIG_R10K_ENCODER 0 +#define CONFIG_R210_ENCODER 0 +#define CONFIG_RAWVIDEO_ENCODER 0 +#define CONFIG_ROQ_ENCODER 0 +#define CONFIG_RPZA_ENCODER 0 +#define CONFIG_RV10_ENCODER 0 +#define CONFIG_RV20_ENCODER 0 +#define CONFIG_S302M_ENCODER 0 +#define CONFIG_SGI_ENCODER 0 +#define CONFIG_SMC_ENCODER 0 +#define CONFIG_SNOW_ENCODER 0 +#define CONFIG_SPEEDHQ_ENCODER 0 +#define CONFIG_SUNRAST_ENCODER 0 +#define CONFIG_SVQ1_ENCODER 0 +#define CONFIG_TARGA_ENCODER 0 +#define CONFIG_TIFF_ENCODER 0 +#define CONFIG_UTVIDEO_ENCODER 0 +#define CONFIG_V210_ENCODER 0 +#define CONFIG_V308_ENCODER 0 +#define CONFIG_V408_ENCODER 0 +#define CONFIG_V410_ENCODER 0 +#define CONFIG_VBN_ENCODER 0 +#define CONFIG_VC2_ENCODER 0 +#define CONFIG_WBMP_ENCODER 0 +#define CONFIG_WRAPPED_AVFRAME_ENCODER 0 +#define CONFIG_WMV1_ENCODER 0 +#define CONFIG_WMV2_ENCODER 0 +#define CONFIG_XBM_ENCODER 0 +#define CONFIG_XFACE_ENCODER 0 +#define CONFIG_XWD_ENCODER 0 +#define CONFIG_Y41P_ENCODER 0 +#define CONFIG_YUV4_ENCODER 0 +#define CONFIG_ZLIB_ENCODER 0 +#define CONFIG_ZMBV_ENCODER 0 +#define CONFIG_AAC_ENCODER 0 +#define CONFIG_AC3_ENCODER 0 +#define CONFIG_AC3_FIXED_ENCODER 0 +#define CONFIG_ALAC_ENCODER 0 +#define CONFIG_APTX_ENCODER 0 +#define CONFIG_APTX_HD_ENCODER 0 +#define CONFIG_DCA_ENCODER 0 +#define CONFIG_DFPWM_ENCODER 0 +#define CONFIG_EAC3_ENCODER 0 +#define CONFIG_FLAC_ENCODER 0 +#define CONFIG_G723_1_ENCODER 0 +#define CONFIG_HDR_ENCODER 0 +#define CONFIG_MLP_ENCODER 0 +#define CONFIG_MP2_ENCODER 0 +#define CONFIG_MP2FIXED_ENCODER 0 +#define CONFIG_NELLYMOSER_ENCODER 0 +#define CONFIG_OPUS_ENCODER 0 +#define CONFIG_RA_144_ENCODER 0 +#define CONFIG_SBC_ENCODER 0 +#define CONFIG_SONIC_ENCODER 0 +#define CONFIG_SONIC_LS_ENCODER 0 +#define CONFIG_TRUEHD_ENCODER 0 +#define CONFIG_TTA_ENCODER 0 +#define CONFIG_VORBIS_ENCODER 0 +#define CONFIG_WAVPACK_ENCODER 0 +#define CONFIG_WMAV1_ENCODER 0 +#define CONFIG_WMAV2_ENCODER 0 +#define CONFIG_PCM_ALAW_ENCODER 0 +#define CONFIG_PCM_BLURAY_ENCODER 0 +#define CONFIG_PCM_DVD_ENCODER 0 +#define CONFIG_PCM_F32BE_ENCODER 0 +#define CONFIG_PCM_F32LE_ENCODER 0 +#define CONFIG_PCM_F64BE_ENCODER 0 +#define CONFIG_PCM_F64LE_ENCODER 0 +#define CONFIG_PCM_MULAW_ENCODER 0 +#define CONFIG_PCM_S8_ENCODER 0 +#define CONFIG_PCM_S8_PLANAR_ENCODER 0 +#define CONFIG_PCM_S16BE_ENCODER 0 +#define CONFIG_PCM_S16BE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S16LE_ENCODER 0 +#define CONFIG_PCM_S16LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S24BE_ENCODER 0 +#define CONFIG_PCM_S24DAUD_ENCODER 0 +#define CONFIG_PCM_S24LE_ENCODER 0 +#define CONFIG_PCM_S24LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S32BE_ENCODER 0 +#define CONFIG_PCM_S32LE_ENCODER 0 +#define CONFIG_PCM_S32LE_PLANAR_ENCODER 0 +#define CONFIG_PCM_S64BE_ENCODER 0 +#define CONFIG_PCM_S64LE_ENCODER 0 +#define CONFIG_PCM_U8_ENCODER 0 +#define CONFIG_PCM_U16BE_ENCODER 0 +#define CONFIG_PCM_U16LE_ENCODER 0 +#define CONFIG_PCM_U24BE_ENCODER 0 +#define CONFIG_PCM_U24LE_ENCODER 0 +#define CONFIG_PCM_U32BE_ENCODER 0 +#define CONFIG_PCM_U32LE_ENCODER 0 +#define CONFIG_PCM_VIDC_ENCODER 0 +#define CONFIG_ROQ_DPCM_ENCODER 0 +#define CONFIG_ADPCM_ADX_ENCODER 0 +#define CONFIG_ADPCM_ARGO_ENCODER 0 +#define CONFIG_ADPCM_G722_ENCODER 0 +#define CONFIG_ADPCM_G726_ENCODER 0 +#define CONFIG_ADPCM_G726LE_ENCODER 0 +#define CONFIG_ADPCM_IMA_AMV_ENCODER 0 +#define CONFIG_ADPCM_IMA_ALP_ENCODER 0 +#define CONFIG_ADPCM_IMA_APM_ENCODER 0 +#define CONFIG_ADPCM_IMA_QT_ENCODER 0 +#define CONFIG_ADPCM_IMA_SSI_ENCODER 0 +#define CONFIG_ADPCM_IMA_WAV_ENCODER 0 +#define CONFIG_ADPCM_IMA_WS_ENCODER 0 +#define CONFIG_ADPCM_MS_ENCODER 0 +#define CONFIG_ADPCM_SWF_ENCODER 0 +#define CONFIG_ADPCM_YAMAHA_ENCODER 0 +#define CONFIG_SSA_ENCODER 0 +#define CONFIG_ASS_ENCODER 0 +#define CONFIG_DVBSUB_ENCODER 0 +#define CONFIG_DVDSUB_ENCODER 0 +#define CONFIG_MOVTEXT_ENCODER 0 +#define CONFIG_SRT_ENCODER 0 +#define CONFIG_SUBRIP_ENCODER 0 +#define CONFIG_TEXT_ENCODER 0 +#define CONFIG_TTML_ENCODER 0 +#define CONFIG_WEBVTT_ENCODER 0 +#define CONFIG_XSUB_ENCODER 0 +#define CONFIG_AAC_AT_ENCODER 0 +#define CONFIG_ALAC_AT_ENCODER 0 +#define CONFIG_ILBC_AT_ENCODER 0 +#define CONFIG_PCM_ALAW_AT_ENCODER 0 +#define CONFIG_PCM_MULAW_AT_ENCODER 0 +#define CONFIG_LIBAOM_AV1_ENCODER 0 +#define CONFIG_LIBCODEC2_ENCODER 0 +#define CONFIG_LIBFDK_AAC_ENCODER 0 +#define CONFIG_LIBGSM_ENCODER 0 +#define CONFIG_LIBGSM_MS_ENCODER 0 +#define CONFIG_LIBILBC_ENCODER 0 +#define CONFIG_LIBJXL_ENCODER 0 +#define CONFIG_LIBMP3LAME_ENCODER 0 +#define CONFIG_LIBOPENCORE_AMRNB_ENCODER 0 +#define CONFIG_LIBOPENJPEG_ENCODER 0 +#define CONFIG_LIBOPUS_ENCODER 0 +#define CONFIG_LIBRAV1E_ENCODER 0 +#define CONFIG_LIBSHINE_ENCODER 0 +#define CONFIG_LIBSPEEX_ENCODER 0 +#define CONFIG_LIBSVTAV1_ENCODER 0 +#define CONFIG_LIBTHEORA_ENCODER 0 +#define CONFIG_LIBTWOLAME_ENCODER 0 +#define CONFIG_LIBVO_AMRWBENC_ENCODER 0 +#define CONFIG_LIBVORBIS_ENCODER 0 +#define CONFIG_LIBVPX_VP8_ENCODER 0 +#define CONFIG_LIBVPX_VP9_ENCODER 0 +#define CONFIG_LIBWEBP_ANIM_ENCODER 0 +#define CONFIG_LIBWEBP_ENCODER 0 +#define CONFIG_LIBX262_ENCODER 0 +#define CONFIG_LIBX264_ENCODER 0 +#define CONFIG_LIBX264RGB_ENCODER 0 +#define CONFIG_LIBX265_ENCODER 0 +#define CONFIG_LIBXAVS_ENCODER 0 +#define CONFIG_LIBXAVS2_ENCODER 0 +#define CONFIG_LIBXVID_ENCODER 0 +#define CONFIG_AAC_MF_ENCODER 0 +#define CONFIG_AC3_MF_ENCODER 0 +#define CONFIG_H263_V4L2M2M_ENCODER 0 +#define CONFIG_AV1_NVENC_ENCODER 0 +#define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 +#define CONFIG_LIBOPENH264_ENCODER 0 +#define CONFIG_H264_AMF_ENCODER 0 +#define CONFIG_H264_MF_ENCODER 0 +#define CONFIG_H264_NVENC_ENCODER 0 +#define CONFIG_H264_OMX_ENCODER 0 +#define CONFIG_H264_QSV_ENCODER 0 +#define CONFIG_H264_V4L2M2M_ENCODER 0 +#define CONFIG_H264_VAAPI_ENCODER 0 +#define CONFIG_H264_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_HEVC_AMF_ENCODER 0 +#define CONFIG_HEVC_MEDIACODEC_ENCODER 0 +#define CONFIG_HEVC_MF_ENCODER 0 +#define CONFIG_HEVC_NVENC_ENCODER 0 +#define CONFIG_HEVC_QSV_ENCODER 0 +#define CONFIG_HEVC_V4L2M2M_ENCODER 0 +#define CONFIG_HEVC_VAAPI_ENCODER 0 +#define CONFIG_HEVC_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_LIBKVAZAAR_ENCODER 0 +#define CONFIG_MJPEG_QSV_ENCODER 0 +#define CONFIG_MJPEG_VAAPI_ENCODER 0 +#define CONFIG_MP3_MF_ENCODER 0 +#define CONFIG_MPEG2_QSV_ENCODER 0 +#define CONFIG_MPEG2_VAAPI_ENCODER 0 +#define CONFIG_MPEG4_OMX_ENCODER 0 +#define CONFIG_MPEG4_V4L2M2M_ENCODER 0 +#define CONFIG_PRORES_VIDEOTOOLBOX_ENCODER 0 +#define CONFIG_VP8_V4L2M2M_ENCODER 0 +#define CONFIG_VP8_VAAPI_ENCODER 0 +#define CONFIG_VP9_VAAPI_ENCODER 0 +#define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 +#define CONFIG_AV1_D3D11VA_HWACCEL 0 +#define CONFIG_AV1_D3D11VA2_HWACCEL 0 +#define CONFIG_AV1_DXVA2_HWACCEL 0 +#define CONFIG_AV1_NVDEC_HWACCEL 0 +#define CONFIG_AV1_VAAPI_HWACCEL 0 +#define CONFIG_AV1_VDPAU_HWACCEL 0 +#define CONFIG_H263_VAAPI_HWACCEL 0 +#define CONFIG_H263_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_H264_D3D11VA_HWACCEL 0 +#define CONFIG_H264_D3D11VA2_HWACCEL 0 +#define CONFIG_H264_DXVA2_HWACCEL 0 +#define CONFIG_H264_NVDEC_HWACCEL 0 +#define CONFIG_H264_VAAPI_HWACCEL 0 +#define CONFIG_H264_VDPAU_HWACCEL 0 +#define CONFIG_H264_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_HEVC_D3D11VA_HWACCEL 0 +#define CONFIG_HEVC_D3D11VA2_HWACCEL 0 +#define CONFIG_HEVC_DXVA2_HWACCEL 0 +#define CONFIG_HEVC_NVDEC_HWACCEL 0 +#define CONFIG_HEVC_VAAPI_HWACCEL 0 +#define CONFIG_HEVC_VDPAU_HWACCEL 0 +#define CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MJPEG_NVDEC_HWACCEL 0 +#define CONFIG_MJPEG_VAAPI_HWACCEL 0 +#define CONFIG_MPEG1_NVDEC_HWACCEL 0 +#define CONFIG_MPEG1_VDPAU_HWACCEL 0 +#define CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MPEG2_D3D11VA_HWACCEL 0 +#define CONFIG_MPEG2_D3D11VA2_HWACCEL 0 +#define CONFIG_MPEG2_NVDEC_HWACCEL 0 +#define CONFIG_MPEG2_DXVA2_HWACCEL 0 +#define CONFIG_MPEG2_VAAPI_HWACCEL 0 +#define CONFIG_MPEG2_VDPAU_HWACCEL 0 +#define CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_MPEG4_NVDEC_HWACCEL 0 +#define CONFIG_MPEG4_VAAPI_HWACCEL 0 +#define CONFIG_MPEG4_VDPAU_HWACCEL 0 +#define CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_VC1_D3D11VA_HWACCEL 0 +#define CONFIG_VC1_D3D11VA2_HWACCEL 0 +#define CONFIG_VC1_DXVA2_HWACCEL 0 +#define CONFIG_VC1_NVDEC_HWACCEL 0 +#define CONFIG_VC1_VAAPI_HWACCEL 0 +#define CONFIG_VC1_VDPAU_HWACCEL 0 +#define CONFIG_VP8_NVDEC_HWACCEL 0 +#define CONFIG_VP8_VAAPI_HWACCEL 0 +#define CONFIG_VP9_D3D11VA_HWACCEL 0 +#define CONFIG_VP9_D3D11VA2_HWACCEL 0 +#define CONFIG_VP9_DXVA2_HWACCEL 0 +#define CONFIG_VP9_NVDEC_HWACCEL 0 +#define CONFIG_VP9_VAAPI_HWACCEL 0 +#define CONFIG_VP9_VDPAU_HWACCEL 0 +#define CONFIG_VP9_VIDEOTOOLBOX_HWACCEL 0 +#define CONFIG_WMV3_D3D11VA_HWACCEL 0 +#define CONFIG_WMV3_D3D11VA2_HWACCEL 0 +#define CONFIG_WMV3_DXVA2_HWACCEL 0 +#define CONFIG_WMV3_NVDEC_HWACCEL 0 +#define CONFIG_WMV3_VAAPI_HWACCEL 0 +#define CONFIG_WMV3_VDPAU_HWACCEL 0 +#define CONFIG_AAC_PARSER 0 +#define CONFIG_AAC_LATM_PARSER 0 +#define CONFIG_AC3_PARSER 0 +#define CONFIG_ADX_PARSER 0 +#define CONFIG_AMR_PARSER 0 +#define CONFIG_AV1_PARSER 0 +#define CONFIG_AVS2_PARSER 0 +#define CONFIG_AVS3_PARSER 0 +#define CONFIG_BMP_PARSER 0 +#define CONFIG_CAVSVIDEO_PARSER 0 +#define CONFIG_COOK_PARSER 0 +#define CONFIG_CRI_PARSER 0 +#define CONFIG_DCA_PARSER 0 +#define CONFIG_DIRAC_PARSER 0 +#define CONFIG_DNXHD_PARSER 0 +#define CONFIG_DOLBY_E_PARSER 0 +#define CONFIG_DPX_PARSER 0 +#define CONFIG_DVAUDIO_PARSER 0 +#define CONFIG_DVBSUB_PARSER 0 +#define CONFIG_DVDSUB_PARSER 0 +#define CONFIG_DVD_NAV_PARSER 0 +#define CONFIG_FLAC_PARSER 1 +#define CONFIG_FTR_PARSER 0 +#define CONFIG_G723_1_PARSER 0 +#define CONFIG_G729_PARSER 0 +#define CONFIG_GIF_PARSER 0 +#define CONFIG_GSM_PARSER 0 +#define CONFIG_H261_PARSER 0 +#define CONFIG_H263_PARSER 0 +#define CONFIG_H264_PARSER 0 +#define CONFIG_HEVC_PARSER 1 +#define CONFIG_HDR_PARSER 0 +#define CONFIG_IPU_PARSER 0 +#define CONFIG_JPEG2000_PARSER 0 +#define CONFIG_MISC4_PARSER 0 +#define CONFIG_MJPEG_PARSER 0 +#define CONFIG_MLP_PARSER 0 +#define CONFIG_MPEG4VIDEO_PARSER 0 +#define CONFIG_MPEGAUDIO_PARSER 1 +#define CONFIG_MPEGVIDEO_PARSER 0 +#define CONFIG_OPUS_PARSER 1 +#define CONFIG_PNG_PARSER 0 +#define CONFIG_PNM_PARSER 0 +#define CONFIG_QOI_PARSER 0 +#define CONFIG_RV30_PARSER 0 +#define CONFIG_RV40_PARSER 0 +#define CONFIG_SBC_PARSER 0 +#define CONFIG_SIPR_PARSER 0 +#define CONFIG_TAK_PARSER 0 +#define CONFIG_VC1_PARSER 0 +#define CONFIG_VORBIS_PARSER 1 +#define CONFIG_VP3_PARSER 1 +#define CONFIG_VP8_PARSER 1 +#define CONFIG_VP9_PARSER 1 +#define CONFIG_WEBP_PARSER 0 +#define CONFIG_XBM_PARSER 0 +#define CONFIG_XMA_PARSER 0 +#define CONFIG_XWD_PARSER 0 +#define CONFIG_ALSA_INDEV 0 +#define CONFIG_ANDROID_CAMERA_INDEV 0 +#define CONFIG_AVFOUNDATION_INDEV 0 +#define CONFIG_BKTR_INDEV 0 +#define CONFIG_DECKLINK_INDEV 0 +#define CONFIG_DSHOW_INDEV 0 +#define CONFIG_FBDEV_INDEV 0 +#define CONFIG_GDIGRAB_INDEV 0 +#define CONFIG_IEC61883_INDEV 0 +#define CONFIG_JACK_INDEV 0 +#define CONFIG_KMSGRAB_INDEV 0 +#define CONFIG_LAVFI_INDEV 0 +#define CONFIG_OPENAL_INDEV 0 +#define CONFIG_OSS_INDEV 0 +#define CONFIG_PULSE_INDEV 0 +#define CONFIG_SNDIO_INDEV 0 +#define CONFIG_V4L2_INDEV 0 +#define CONFIG_VFWCAP_INDEV 0 +#define CONFIG_XCBGRAB_INDEV 0 +#define CONFIG_LIBCDIO_INDEV 0 +#define CONFIG_LIBDC1394_INDEV 0 +#define CONFIG_ALSA_OUTDEV 0 +#define CONFIG_AUDIOTOOLBOX_OUTDEV 0 +#define CONFIG_CACA_OUTDEV 0 +#define CONFIG_DECKLINK_OUTDEV 0 +#define CONFIG_FBDEV_OUTDEV 0 +#define CONFIG_OPENGL_OUTDEV 0 +#define CONFIG_OSS_OUTDEV 0 +#define CONFIG_PULSE_OUTDEV 0 +#define CONFIG_SDL2_OUTDEV 0 +#define CONFIG_SNDIO_OUTDEV 0 +#define CONFIG_V4L2_OUTDEV 0 +#define CONFIG_XV_OUTDEV 0 +#define CONFIG_ABENCH_FILTER 0 +#define CONFIG_ACOMPRESSOR_FILTER 0 +#define CONFIG_ACONTRAST_FILTER 0 +#define CONFIG_ACOPY_FILTER 0 +#define CONFIG_ACUE_FILTER 0 +#define CONFIG_ACROSSFADE_FILTER 0 +#define CONFIG_ACROSSOVER_FILTER 0 +#define CONFIG_ACRUSHER_FILTER 0 +#define CONFIG_ADECLICK_FILTER 0 +#define CONFIG_ADECLIP_FILTER 0 +#define CONFIG_ADECORRELATE_FILTER 0 +#define CONFIG_ADELAY_FILTER 0 +#define CONFIG_ADENORM_FILTER 0 +#define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 +#define CONFIG_ADYNAMICEQUALIZER_FILTER 0 +#define CONFIG_ADYNAMICSMOOTH_FILTER 0 +#define CONFIG_AECHO_FILTER 0 +#define CONFIG_AEMPHASIS_FILTER 0 +#define CONFIG_AEVAL_FILTER 0 +#define CONFIG_AEXCITER_FILTER 0 +#define CONFIG_AFADE_FILTER 0 +#define CONFIG_AFFTDN_FILTER 0 +#define CONFIG_AFFTFILT_FILTER 0 +#define CONFIG_AFIR_FILTER 0 +#define CONFIG_AFORMAT_FILTER 0 +#define CONFIG_AFREQSHIFT_FILTER 0 +#define CONFIG_AFWTDN_FILTER 0 +#define CONFIG_AGATE_FILTER 0 +#define CONFIG_AIIR_FILTER 0 +#define CONFIG_AINTEGRAL_FILTER 0 +#define CONFIG_AINTERLEAVE_FILTER 0 +#define CONFIG_ALATENCY_FILTER 0 +#define CONFIG_ALIMITER_FILTER 0 +#define CONFIG_ALLPASS_FILTER 0 +#define CONFIG_ALOOP_FILTER 0 +#define CONFIG_AMERGE_FILTER 0 +#define CONFIG_AMETADATA_FILTER 0 +#define CONFIG_AMIX_FILTER 0 +#define CONFIG_AMULTIPLY_FILTER 0 +#define CONFIG_ANEQUALIZER_FILTER 0 +#define CONFIG_ANLMDN_FILTER 0 +#define CONFIG_ANLMF_FILTER 0 +#define CONFIG_ANLMS_FILTER 0 +#define CONFIG_ANULL_FILTER 0 +#define CONFIG_APAD_FILTER 0 +#define CONFIG_APERMS_FILTER 0 +#define CONFIG_APHASER_FILTER 0 +#define CONFIG_APHASESHIFT_FILTER 0 +#define CONFIG_APSYCLIP_FILTER 0 +#define CONFIG_APULSATOR_FILTER 0 +#define CONFIG_AREALTIME_FILTER 0 +#define CONFIG_ARESAMPLE_FILTER 0 +#define CONFIG_AREVERSE_FILTER 0 +#define CONFIG_ARNNDN_FILTER 0 +#define CONFIG_ASDR_FILTER 0 +#define CONFIG_ASEGMENT_FILTER 0 +#define CONFIG_ASELECT_FILTER 0 +#define CONFIG_ASENDCMD_FILTER 0 +#define CONFIG_ASETNSAMPLES_FILTER 0 +#define CONFIG_ASETPTS_FILTER 0 +#define CONFIG_ASETRATE_FILTER 0 +#define CONFIG_ASETTB_FILTER 0 +#define CONFIG_ASHOWINFO_FILTER 0 +#define CONFIG_ASIDEDATA_FILTER 0 +#define CONFIG_ASOFTCLIP_FILTER 0 +#define CONFIG_ASPECTRALSTATS_FILTER 0 +#define CONFIG_ASPLIT_FILTER 0 +#define CONFIG_ASR_FILTER 0 +#define CONFIG_ASTATS_FILTER 0 +#define CONFIG_ASTREAMSELECT_FILTER 0 +#define CONFIG_ASUBBOOST_FILTER 0 +#define CONFIG_ASUBCUT_FILTER 0 +#define CONFIG_ASUPERCUT_FILTER 0 +#define CONFIG_ASUPERPASS_FILTER 0 +#define CONFIG_ASUPERSTOP_FILTER 0 +#define CONFIG_ATEMPO_FILTER 0 +#define CONFIG_ATILT_FILTER 0 +#define CONFIG_ATRIM_FILTER 0 +#define CONFIG_AXCORRELATE_FILTER 0 +#define CONFIG_AZMQ_FILTER 0 +#define CONFIG_BANDPASS_FILTER 0 +#define CONFIG_BANDREJECT_FILTER 0 +#define CONFIG_BASS_FILTER 0 +#define CONFIG_BIQUAD_FILTER 0 +#define CONFIG_BS2B_FILTER 0 +#define CONFIG_CHANNELMAP_FILTER 0 +#define CONFIG_CHANNELSPLIT_FILTER 0 +#define CONFIG_CHORUS_FILTER 0 +#define CONFIG_COMPAND_FILTER 0 +#define CONFIG_COMPENSATIONDELAY_FILTER 0 +#define CONFIG_CROSSFEED_FILTER 0 +#define CONFIG_CRYSTALIZER_FILTER 0 +#define CONFIG_DCSHIFT_FILTER 0 +#define CONFIG_DEESSER_FILTER 0 +#define CONFIG_DIALOGUENHANCE_FILTER 0 +#define CONFIG_DRMETER_FILTER 0 +#define CONFIG_DYNAUDNORM_FILTER 0 +#define CONFIG_EARWAX_FILTER 0 +#define CONFIG_EBUR128_FILTER 0 +#define CONFIG_EQUALIZER_FILTER 0 +#define CONFIG_EXTRASTEREO_FILTER 0 +#define CONFIG_FIREQUALIZER_FILTER 0 +#define CONFIG_FLANGER_FILTER 0 +#define CONFIG_HAAS_FILTER 0 +#define CONFIG_HDCD_FILTER 0 +#define CONFIG_HEADPHONE_FILTER 0 +#define CONFIG_HIGHPASS_FILTER 0 +#define CONFIG_HIGHSHELF_FILTER 0 +#define CONFIG_JOIN_FILTER 0 +#define CONFIG_LADSPA_FILTER 0 +#define CONFIG_LOUDNORM_FILTER 0 +#define CONFIG_LOWPASS_FILTER 0 +#define CONFIG_LOWSHELF_FILTER 0 +#define CONFIG_LV2_FILTER 0 +#define CONFIG_MCOMPAND_FILTER 0 +#define CONFIG_PAN_FILTER 0 +#define CONFIG_REPLAYGAIN_FILTER 0 +#define CONFIG_RUBBERBAND_FILTER 0 +#define CONFIG_SIDECHAINCOMPRESS_FILTER 0 +#define CONFIG_SIDECHAINGATE_FILTER 0 +#define CONFIG_SILENCEDETECT_FILTER 0 +#define CONFIG_SILENCEREMOVE_FILTER 0 +#define CONFIG_SOFALIZER_FILTER 0 +#define CONFIG_SPEECHNORM_FILTER 0 +#define CONFIG_STEREOTOOLS_FILTER 0 +#define CONFIG_STEREOWIDEN_FILTER 0 +#define CONFIG_SUPEREQUALIZER_FILTER 0 +#define CONFIG_SURROUND_FILTER 0 +#define CONFIG_TILTSHELF_FILTER 0 +#define CONFIG_TREBLE_FILTER 0 +#define CONFIG_TREMOLO_FILTER 0 +#define CONFIG_VIBRATO_FILTER 0 +#define CONFIG_VIRTUALBASS_FILTER 0 +#define CONFIG_VOLUME_FILTER 0 +#define CONFIG_VOLUMEDETECT_FILTER 0 +#define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 +#define CONFIG_AFIRSRC_FILTER 0 +#define CONFIG_ANOISESRC_FILTER 0 +#define CONFIG_ANULLSRC_FILTER 0 +#define CONFIG_FLITE_FILTER 0 +#define CONFIG_HILBERT_FILTER 0 +#define CONFIG_SINC_FILTER 0 +#define CONFIG_SINE_FILTER 0 +#define CONFIG_ANULLSINK_FILTER 0 +#define CONFIG_ADDROI_FILTER 0 +#define CONFIG_ALPHAEXTRACT_FILTER 0 +#define CONFIG_ALPHAMERGE_FILTER 0 +#define CONFIG_AMPLIFY_FILTER 0 +#define CONFIG_ASS_FILTER 0 +#define CONFIG_ATADENOISE_FILTER 0 +#define CONFIG_AVGBLUR_FILTER 0 +#define CONFIG_AVGBLUR_OPENCL_FILTER 0 +#define CONFIG_AVGBLUR_VULKAN_FILTER 0 +#define CONFIG_BACKGROUNDKEY_FILTER 0 +#define CONFIG_BBOX_FILTER 0 +#define CONFIG_BENCH_FILTER 0 +#define CONFIG_BILATERAL_FILTER 0 +#define CONFIG_BILATERAL_CUDA_FILTER 0 +#define CONFIG_BITPLANENOISE_FILTER 0 +#define CONFIG_BLACKDETECT_FILTER 0 +#define CONFIG_BLACKFRAME_FILTER 0 +#define CONFIG_BLEND_FILTER 0 +#define CONFIG_BLEND_VULKAN_FILTER 0 +#define CONFIG_BLOCKDETECT_FILTER 0 +#define CONFIG_BLURDETECT_FILTER 0 +#define CONFIG_BM3D_FILTER 0 +#define CONFIG_BOXBLUR_FILTER 0 +#define CONFIG_BOXBLUR_OPENCL_FILTER 0 +#define CONFIG_BWDIF_FILTER 0 +#define CONFIG_CAS_FILTER 0 +#define CONFIG_CHROMABER_VULKAN_FILTER 0 +#define CONFIG_CHROMAHOLD_FILTER 0 +#define CONFIG_CHROMAKEY_FILTER 0 +#define CONFIG_CHROMAKEY_CUDA_FILTER 0 +#define CONFIG_CHROMANR_FILTER 0 +#define CONFIG_CHROMASHIFT_FILTER 0 +#define CONFIG_CIESCOPE_FILTER 0 +#define CONFIG_CODECVIEW_FILTER 0 +#define CONFIG_COLORBALANCE_FILTER 0 +#define CONFIG_COLORCHANNELMIXER_FILTER 0 +#define CONFIG_COLORCONTRAST_FILTER 0 +#define CONFIG_COLORCORRECT_FILTER 0 +#define CONFIG_COLORIZE_FILTER 0 +#define CONFIG_COLORKEY_FILTER 0 +#define CONFIG_COLORKEY_OPENCL_FILTER 0 +#define CONFIG_COLORHOLD_FILTER 0 +#define CONFIG_COLORLEVELS_FILTER 0 +#define CONFIG_COLORMAP_FILTER 0 +#define CONFIG_COLORMATRIX_FILTER 0 +#define CONFIG_COLORSPACE_FILTER 0 +#define CONFIG_COLORSPACE_CUDA_FILTER 0 +#define CONFIG_COLORTEMPERATURE_FILTER 0 +#define CONFIG_CONVOLUTION_FILTER 0 +#define CONFIG_CONVOLUTION_OPENCL_FILTER 0 +#define CONFIG_CONVOLVE_FILTER 0 +#define CONFIG_COPY_FILTER 0 +#define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 +#define CONFIG_COVER_RECT_FILTER 0 +#define CONFIG_CROP_FILTER 0 +#define CONFIG_CROPDETECT_FILTER 0 +#define CONFIG_CUE_FILTER 0 +#define CONFIG_CURVES_FILTER 0 +#define CONFIG_DATASCOPE_FILTER 0 +#define CONFIG_DBLUR_FILTER 0 +#define CONFIG_DCTDNOIZ_FILTER 0 +#define CONFIG_DEBAND_FILTER 0 +#define CONFIG_DEBLOCK_FILTER 0 +#define CONFIG_DECIMATE_FILTER 0 +#define CONFIG_DECONVOLVE_FILTER 0 +#define CONFIG_DEDOT_FILTER 0 +#define CONFIG_DEFLATE_FILTER 0 +#define CONFIG_DEFLICKER_FILTER 0 +#define CONFIG_DEINTERLACE_QSV_FILTER 0 +#define CONFIG_DEINTERLACE_VAAPI_FILTER 0 +#define CONFIG_DEJUDDER_FILTER 0 +#define CONFIG_DELOGO_FILTER 0 +#define CONFIG_DENOISE_VAAPI_FILTER 0 +#define CONFIG_DERAIN_FILTER 0 +#define CONFIG_DESHAKE_FILTER 0 +#define CONFIG_DESHAKE_OPENCL_FILTER 0 +#define CONFIG_DESPILL_FILTER 0 +#define CONFIG_DETELECINE_FILTER 0 +#define CONFIG_DILATION_FILTER 0 +#define CONFIG_DILATION_OPENCL_FILTER 0 +#define CONFIG_DISPLACE_FILTER 0 +#define CONFIG_DNN_CLASSIFY_FILTER 0 +#define CONFIG_DNN_DETECT_FILTER 0 +#define CONFIG_DNN_PROCESSING_FILTER 0 +#define CONFIG_DOUBLEWEAVE_FILTER 0 +#define CONFIG_DRAWBOX_FILTER 0 +#define CONFIG_DRAWGRAPH_FILTER 0 +#define CONFIG_DRAWGRID_FILTER 0 +#define CONFIG_DRAWTEXT_FILTER 0 +#define CONFIG_EDGEDETECT_FILTER 0 +#define CONFIG_ELBG_FILTER 0 +#define CONFIG_ENTROPY_FILTER 0 +#define CONFIG_EPX_FILTER 0 +#define CONFIG_EQ_FILTER 0 +#define CONFIG_EROSION_FILTER 0 +#define CONFIG_EROSION_OPENCL_FILTER 0 +#define CONFIG_ESTDIF_FILTER 0 +#define CONFIG_EXPOSURE_FILTER 0 +#define CONFIG_EXTRACTPLANES_FILTER 0 +#define CONFIG_FADE_FILTER 0 +#define CONFIG_FEEDBACK_FILTER 0 +#define CONFIG_FFTDNOIZ_FILTER 0 +#define CONFIG_FFTFILT_FILTER 0 +#define CONFIG_FIELD_FILTER 0 +#define CONFIG_FIELDHINT_FILTER 0 +#define CONFIG_FIELDMATCH_FILTER 0 +#define CONFIG_FIELDORDER_FILTER 0 +#define CONFIG_FILLBORDERS_FILTER 0 +#define CONFIG_FIND_RECT_FILTER 0 +#define CONFIG_FLIP_VULKAN_FILTER 0 +#define CONFIG_FLOODFILL_FILTER 0 +#define CONFIG_FORMAT_FILTER 0 +#define CONFIG_FPS_FILTER 0 +#define CONFIG_FRAMEPACK_FILTER 0 +#define CONFIG_FRAMERATE_FILTER 0 +#define CONFIG_FRAMESTEP_FILTER 0 +#define CONFIG_FREEZEDETECT_FILTER 0 +#define CONFIG_FREEZEFRAMES_FILTER 0 +#define CONFIG_FREI0R_FILTER 0 +#define CONFIG_FSPP_FILTER 0 +#define CONFIG_GBLUR_FILTER 0 +#define CONFIG_GBLUR_VULKAN_FILTER 0 +#define CONFIG_GEQ_FILTER 0 +#define CONFIG_GRADFUN_FILTER 0 +#define CONFIG_GRAPHMONITOR_FILTER 0 +#define CONFIG_GRAYWORLD_FILTER 0 +#define CONFIG_GREYEDGE_FILTER 0 +#define CONFIG_GUIDED_FILTER 0 +#define CONFIG_HALDCLUT_FILTER 0 +#define CONFIG_HFLIP_FILTER 0 +#define CONFIG_HFLIP_VULKAN_FILTER 0 +#define CONFIG_HISTEQ_FILTER 0 +#define CONFIG_HISTOGRAM_FILTER 0 +#define CONFIG_HQDN3D_FILTER 0 +#define CONFIG_HQX_FILTER 0 +#define CONFIG_HSTACK_FILTER 0 +#define CONFIG_HSVHOLD_FILTER 0 +#define CONFIG_HSVKEY_FILTER 0 +#define CONFIG_HUE_FILTER 0 +#define CONFIG_HUESATURATION_FILTER 0 +#define CONFIG_HWDOWNLOAD_FILTER 0 +#define CONFIG_HWMAP_FILTER 0 +#define CONFIG_HWUPLOAD_FILTER 0 +#define CONFIG_HWUPLOAD_CUDA_FILTER 0 +#define CONFIG_HYSTERESIS_FILTER 0 +#define CONFIG_ICCDETECT_FILTER 0 +#define CONFIG_ICCGEN_FILTER 0 +#define CONFIG_IDENTITY_FILTER 0 +#define CONFIG_IDET_FILTER 0 +#define CONFIG_IL_FILTER 0 +#define CONFIG_INFLATE_FILTER 0 +#define CONFIG_INTERLACE_FILTER 0 +#define CONFIG_INTERLEAVE_FILTER 0 +#define CONFIG_KERNDEINT_FILTER 0 +#define CONFIG_KIRSCH_FILTER 0 +#define CONFIG_LAGFUN_FILTER 0 +#define CONFIG_LATENCY_FILTER 0 +#define CONFIG_LENSCORRECTION_FILTER 0 +#define CONFIG_LENSFUN_FILTER 0 +#define CONFIG_LIBPLACEBO_FILTER 0 +#define CONFIG_LIBVMAF_FILTER 0 +#define CONFIG_LIMITDIFF_FILTER 0 +#define CONFIG_LIMITER_FILTER 0 +#define CONFIG_LOOP_FILTER 0 +#define CONFIG_LUMAKEY_FILTER 0 +#define CONFIG_LUT_FILTER 0 +#define CONFIG_LUT1D_FILTER 0 +#define CONFIG_LUT2_FILTER 0 +#define CONFIG_LUT3D_FILTER 0 +#define CONFIG_LUTRGB_FILTER 0 +#define CONFIG_LUTYUV_FILTER 0 +#define CONFIG_MASKEDCLAMP_FILTER 0 +#define CONFIG_MASKEDMAX_FILTER 0 +#define CONFIG_MASKEDMERGE_FILTER 0 +#define CONFIG_MASKEDMIN_FILTER 0 +#define CONFIG_MASKEDTHRESHOLD_FILTER 0 +#define CONFIG_MASKFUN_FILTER 0 +#define CONFIG_MCDEINT_FILTER 0 +#define CONFIG_MEDIAN_FILTER 0 +#define CONFIG_MERGEPLANES_FILTER 0 +#define CONFIG_MESTIMATE_FILTER 0 +#define CONFIG_METADATA_FILTER 0 +#define CONFIG_MIDEQUALIZER_FILTER 0 +#define CONFIG_MINTERPOLATE_FILTER 0 +#define CONFIG_MIX_FILTER 0 +#define CONFIG_MONOCHROME_FILTER 0 +#define CONFIG_MORPHO_FILTER 0 +#define CONFIG_MPDECIMATE_FILTER 0 +#define CONFIG_MSAD_FILTER 0 +#define CONFIG_MULTIPLY_FILTER 0 +#define CONFIG_NEGATE_FILTER 0 +#define CONFIG_NLMEANS_FILTER 0 +#define CONFIG_NLMEANS_OPENCL_FILTER 0 +#define CONFIG_NNEDI_FILTER 0 +#define CONFIG_NOFORMAT_FILTER 0 +#define CONFIG_NOISE_FILTER 0 +#define CONFIG_NORMALIZE_FILTER 0 +#define CONFIG_NULL_FILTER 0 +#define CONFIG_OCR_FILTER 0 +#define CONFIG_OCV_FILTER 0 +#define CONFIG_OSCILLOSCOPE_FILTER 0 +#define CONFIG_OVERLAY_FILTER 0 +#define CONFIG_OVERLAY_OPENCL_FILTER 0 +#define CONFIG_OVERLAY_QSV_FILTER 0 +#define CONFIG_OVERLAY_VAAPI_FILTER 0 +#define CONFIG_OVERLAY_VULKAN_FILTER 0 +#define CONFIG_OVERLAY_CUDA_FILTER 0 +#define CONFIG_OWDENOISE_FILTER 0 +#define CONFIG_PAD_FILTER 0 +#define CONFIG_PAD_OPENCL_FILTER 0 +#define CONFIG_PALETTEGEN_FILTER 0 +#define CONFIG_PALETTEUSE_FILTER 0 +#define CONFIG_PERMS_FILTER 0 +#define CONFIG_PERSPECTIVE_FILTER 0 +#define CONFIG_PHASE_FILTER 0 +#define CONFIG_PHOTOSENSITIVITY_FILTER 0 +#define CONFIG_PIXDESCTEST_FILTER 0 +#define CONFIG_PIXELIZE_FILTER 0 +#define CONFIG_PIXSCOPE_FILTER 0 +#define CONFIG_PP_FILTER 0 +#define CONFIG_PP7_FILTER 0 +#define CONFIG_PREMULTIPLY_FILTER 0 +#define CONFIG_PREWITT_FILTER 0 +#define CONFIG_PREWITT_OPENCL_FILTER 0 +#define CONFIG_PROCAMP_VAAPI_FILTER 0 +#define CONFIG_PROGRAM_OPENCL_FILTER 0 +#define CONFIG_PSEUDOCOLOR_FILTER 0 +#define CONFIG_PSNR_FILTER 0 +#define CONFIG_PULLUP_FILTER 0 +#define CONFIG_QP_FILTER 0 +#define CONFIG_RANDOM_FILTER 0 +#define CONFIG_READEIA608_FILTER 0 +#define CONFIG_READVITC_FILTER 0 +#define CONFIG_REALTIME_FILTER 0 +#define CONFIG_REMAP_FILTER 0 +#define CONFIG_REMAP_OPENCL_FILTER 0 +#define CONFIG_REMOVEGRAIN_FILTER 0 +#define CONFIG_REMOVELOGO_FILTER 0 +#define CONFIG_REPEATFIELDS_FILTER 0 +#define CONFIG_REVERSE_FILTER 0 +#define CONFIG_RGBASHIFT_FILTER 0 +#define CONFIG_ROBERTS_FILTER 0 +#define CONFIG_ROBERTS_OPENCL_FILTER 0 +#define CONFIG_ROTATE_FILTER 0 +#define CONFIG_SAB_FILTER 0 +#define CONFIG_SCALE_FILTER 0 +#define CONFIG_SCALE_CUDA_FILTER 0 +#define CONFIG_SCALE_NPP_FILTER 0 +#define CONFIG_SCALE_QSV_FILTER 0 +#define CONFIG_SCALE_VAAPI_FILTER 0 +#define CONFIG_SCALE_VULKAN_FILTER 0 +#define CONFIG_SCALE2REF_FILTER 0 +#define CONFIG_SCALE2REF_NPP_FILTER 0 +#define CONFIG_SCDET_FILTER 0 +#define CONFIG_SCHARR_FILTER 0 +#define CONFIG_SCROLL_FILTER 0 +#define CONFIG_SEGMENT_FILTER 0 +#define CONFIG_SELECT_FILTER 0 +#define CONFIG_SELECTIVECOLOR_FILTER 0 +#define CONFIG_SENDCMD_FILTER 0 +#define CONFIG_SEPARATEFIELDS_FILTER 0 +#define CONFIG_SETDAR_FILTER 0 +#define CONFIG_SETFIELD_FILTER 0 +#define CONFIG_SETPARAMS_FILTER 0 +#define CONFIG_SETPTS_FILTER 0 +#define CONFIG_SETRANGE_FILTER 0 +#define CONFIG_SETSAR_FILTER 0 +#define CONFIG_SETTB_FILTER 0 +#define CONFIG_SHARPEN_NPP_FILTER 0 +#define CONFIG_SHARPNESS_VAAPI_FILTER 0 +#define CONFIG_SHEAR_FILTER 0 +#define CONFIG_SHOWINFO_FILTER 0 +#define CONFIG_SHOWPALETTE_FILTER 0 +#define CONFIG_SHUFFLEFRAMES_FILTER 0 +#define CONFIG_SHUFFLEPIXELS_FILTER 0 +#define CONFIG_SHUFFLEPLANES_FILTER 0 +#define CONFIG_SIDEDATA_FILTER 0 +#define CONFIG_SIGNALSTATS_FILTER 0 +#define CONFIG_SIGNATURE_FILTER 0 +#define CONFIG_SITI_FILTER 0 +#define CONFIG_SMARTBLUR_FILTER 0 +#define CONFIG_SOBEL_FILTER 0 +#define CONFIG_SOBEL_OPENCL_FILTER 0 +#define CONFIG_SPLIT_FILTER 0 +#define CONFIG_SPP_FILTER 0 +#define CONFIG_SR_FILTER 0 +#define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 +#define CONFIG_STEREO3D_FILTER 0 +#define CONFIG_STREAMSELECT_FILTER 0 +#define CONFIG_SUBTITLES_FILTER 0 +#define CONFIG_SUPER2XSAI_FILTER 0 +#define CONFIG_SWAPRECT_FILTER 0 +#define CONFIG_SWAPUV_FILTER 0 +#define CONFIG_TBLEND_FILTER 0 +#define CONFIG_TELECINE_FILTER 0 +#define CONFIG_THISTOGRAM_FILTER 0 +#define CONFIG_THRESHOLD_FILTER 0 +#define CONFIG_THUMBNAIL_FILTER 0 +#define CONFIG_THUMBNAIL_CUDA_FILTER 0 +#define CONFIG_TILE_FILTER 0 +#define CONFIG_TINTERLACE_FILTER 0 +#define CONFIG_TLUT2_FILTER 0 +#define CONFIG_TMEDIAN_FILTER 0 +#define CONFIG_TMIDEQUALIZER_FILTER 0 +#define CONFIG_TMIX_FILTER 0 +#define CONFIG_TONEMAP_FILTER 0 +#define CONFIG_TONEMAP_OPENCL_FILTER 0 +#define CONFIG_TONEMAP_VAAPI_FILTER 0 +#define CONFIG_TPAD_FILTER 0 +#define CONFIG_TRANSPOSE_FILTER 0 +#define CONFIG_TRANSPOSE_NPP_FILTER 0 +#define CONFIG_TRANSPOSE_OPENCL_FILTER 0 +#define CONFIG_TRANSPOSE_VAAPI_FILTER 0 +#define CONFIG_TRANSPOSE_VULKAN_FILTER 0 +#define CONFIG_TRIM_FILTER 0 +#define CONFIG_UNPREMULTIPLY_FILTER 0 +#define CONFIG_UNSHARP_FILTER 0 +#define CONFIG_UNSHARP_OPENCL_FILTER 0 +#define CONFIG_UNTILE_FILTER 0 +#define CONFIG_USPP_FILTER 0 +#define CONFIG_V360_FILTER 0 +#define CONFIG_VAGUEDENOISER_FILTER 0 +#define CONFIG_VARBLUR_FILTER 0 +#define CONFIG_VECTORSCOPE_FILTER 0 +#define CONFIG_VFLIP_FILTER 0 +#define CONFIG_VFLIP_VULKAN_FILTER 0 +#define CONFIG_VFRDET_FILTER 0 +#define CONFIG_VIBRANCE_FILTER 0 +#define CONFIG_VIDSTABDETECT_FILTER 0 +#define CONFIG_VIDSTABTRANSFORM_FILTER 0 +#define CONFIG_VIF_FILTER 0 +#define CONFIG_VIGNETTE_FILTER 0 +#define CONFIG_VMAFMOTION_FILTER 0 +#define CONFIG_VPP_QSV_FILTER 0 +#define CONFIG_VSTACK_FILTER 0 +#define CONFIG_W3FDIF_FILTER 0 +#define CONFIG_WAVEFORM_FILTER 0 +#define CONFIG_WEAVE_FILTER 0 +#define CONFIG_XBR_FILTER 0 +#define CONFIG_XCORRELATE_FILTER 0 +#define CONFIG_XFADE_FILTER 0 +#define CONFIG_XFADE_OPENCL_FILTER 0 +#define CONFIG_XMEDIAN_FILTER 0 +#define CONFIG_XSTACK_FILTER 0 +#define CONFIG_YADIF_FILTER 0 +#define CONFIG_YADIF_CUDA_FILTER 0 +#define CONFIG_YADIF_VIDEOTOOLBOX_FILTER 0 +#define CONFIG_YAEPBLUR_FILTER 0 +#define CONFIG_ZMQ_FILTER 0 +#define CONFIG_ZOOMPAN_FILTER 0 +#define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 +#define CONFIG_ALLRGB_FILTER 0 +#define CONFIG_ALLYUV_FILTER 0 +#define CONFIG_CELLAUTO_FILTER 0 +#define CONFIG_COLOR_FILTER 0 +#define CONFIG_COLORCHART_FILTER 0 +#define CONFIG_COLORSPECTRUM_FILTER 0 +#define CONFIG_COREIMAGESRC_FILTER 0 +#define CONFIG_DDAGRAB_FILTER 0 +#define CONFIG_FREI0R_SRC_FILTER 0 +#define CONFIG_GRADIENTS_FILTER 0 +#define CONFIG_HALDCLUTSRC_FILTER 0 +#define CONFIG_LIFE_FILTER 0 +#define CONFIG_MANDELBROT_FILTER 0 +#define CONFIG_MPTESTSRC_FILTER 0 +#define CONFIG_NULLSRC_FILTER 0 +#define CONFIG_OPENCLSRC_FILTER 0 +#define CONFIG_PAL75BARS_FILTER 0 +#define CONFIG_PAL100BARS_FILTER 0 +#define CONFIG_RGBTESTSRC_FILTER 0 +#define CONFIG_SIERPINSKI_FILTER 0 +#define CONFIG_SMPTEBARS_FILTER 0 +#define CONFIG_SMPTEHDBARS_FILTER 0 +#define CONFIG_TESTSRC_FILTER 0 +#define CONFIG_TESTSRC2_FILTER 0 +#define CONFIG_YUVTESTSRC_FILTER 0 +#define CONFIG_NULLSINK_FILTER 0 +#define CONFIG_A3DSCOPE_FILTER 0 +#define CONFIG_ABITSCOPE_FILTER 0 +#define CONFIG_ADRAWGRAPH_FILTER 0 +#define CONFIG_AGRAPHMONITOR_FILTER 0 +#define CONFIG_AHISTOGRAM_FILTER 0 +#define CONFIG_APHASEMETER_FILTER 0 +#define CONFIG_AVECTORSCOPE_FILTER 0 +#define CONFIG_CONCAT_FILTER 0 +#define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 +#define CONFIG_SHOWFREQS_FILTER 0 +#define CONFIG_SHOWSPATIAL_FILTER 0 +#define CONFIG_SHOWSPECTRUM_FILTER 0 +#define CONFIG_SHOWSPECTRUMPIC_FILTER 0 +#define CONFIG_SHOWVOLUME_FILTER 0 +#define CONFIG_SHOWWAVES_FILTER 0 +#define CONFIG_SHOWWAVESPIC_FILTER 0 +#define CONFIG_SPECTRUMSYNTH_FILTER 0 +#define CONFIG_AVSYNCTEST_FILTER 0 +#define CONFIG_AMOVIE_FILTER 0 +#define CONFIG_MOVIE_FILTER 0 +#define CONFIG_AFIFO_FILTER 0 +#define CONFIG_FIFO_FILTER 0 +#define CONFIG_AA_DEMUXER 0 +#define CONFIG_AAC_DEMUXER 0 +#define CONFIG_AAX_DEMUXER 0 +#define CONFIG_AC3_DEMUXER 0 +#define CONFIG_ACE_DEMUXER 0 +#define CONFIG_ACM_DEMUXER 0 +#define CONFIG_ACT_DEMUXER 0 +#define CONFIG_ADF_DEMUXER 0 +#define CONFIG_ADP_DEMUXER 0 +#define CONFIG_ADS_DEMUXER 0 +#define CONFIG_ADX_DEMUXER 0 +#define CONFIG_AEA_DEMUXER 0 +#define CONFIG_AFC_DEMUXER 0 +#define CONFIG_AIFF_DEMUXER 0 +#define CONFIG_AIX_DEMUXER 0 +#define CONFIG_ALP_DEMUXER 0 +#define CONFIG_AMR_DEMUXER 0 +#define CONFIG_AMRNB_DEMUXER 0 +#define CONFIG_AMRWB_DEMUXER 0 +#define CONFIG_ANM_DEMUXER 0 +#define CONFIG_APAC_DEMUXER 0 +#define CONFIG_APC_DEMUXER 0 +#define CONFIG_APE_DEMUXER 0 +#define CONFIG_APM_DEMUXER 0 +#define CONFIG_APNG_DEMUXER 0 +#define CONFIG_APTX_DEMUXER 0 +#define CONFIG_APTX_HD_DEMUXER 0 +#define CONFIG_AQTITLE_DEMUXER 0 +#define CONFIG_ARGO_ASF_DEMUXER 0 +#define CONFIG_ARGO_BRP_DEMUXER 0 +#define CONFIG_ARGO_CVG_DEMUXER 0 +#define CONFIG_ASF_DEMUXER 0 +#define CONFIG_ASF_O_DEMUXER 0 +#define CONFIG_ASS_DEMUXER 0 +#define CONFIG_AST_DEMUXER 0 +#define CONFIG_AU_DEMUXER 0 +#define CONFIG_AV1_DEMUXER 0 +#define CONFIG_AVI_DEMUXER 0 +#define CONFIG_AVISYNTH_DEMUXER 0 +#define CONFIG_AVR_DEMUXER 0 +#define CONFIG_AVS_DEMUXER 0 +#define CONFIG_AVS2_DEMUXER 0 +#define CONFIG_AVS3_DEMUXER 0 +#define CONFIG_BETHSOFTVID_DEMUXER 0 +#define CONFIG_BFI_DEMUXER 0 +#define CONFIG_BINTEXT_DEMUXER 0 +#define CONFIG_BINK_DEMUXER 0 +#define CONFIG_BINKA_DEMUXER 0 +#define CONFIG_BIT_DEMUXER 0 +#define CONFIG_BITPACKED_DEMUXER 0 +#define CONFIG_BMV_DEMUXER 0 +#define CONFIG_BFSTM_DEMUXER 0 +#define CONFIG_BRSTM_DEMUXER 0 +#define CONFIG_BOA_DEMUXER 0 +#define CONFIG_BONK_DEMUXER 0 +#define CONFIG_C93_DEMUXER 0 +#define CONFIG_CAF_DEMUXER 0 +#define CONFIG_CAVSVIDEO_DEMUXER 0 +#define CONFIG_CDG_DEMUXER 0 +#define CONFIG_CDXL_DEMUXER 0 +#define CONFIG_CINE_DEMUXER 0 +#define CONFIG_CODEC2_DEMUXER 0 +#define CONFIG_CODEC2RAW_DEMUXER 0 +#define CONFIG_CONCAT_DEMUXER 0 +#define CONFIG_DASH_DEMUXER 0 +#define CONFIG_DATA_DEMUXER 0 +#define CONFIG_DAUD_DEMUXER 0 +#define CONFIG_DCSTR_DEMUXER 0 +#define CONFIG_DERF_DEMUXER 0 +#define CONFIG_DFA_DEMUXER 0 +#define CONFIG_DFPWM_DEMUXER 0 +#define CONFIG_DHAV_DEMUXER 0 +#define CONFIG_DIRAC_DEMUXER 0 +#define CONFIG_DNXHD_DEMUXER 0 +#define CONFIG_DSF_DEMUXER 0 +#define CONFIG_DSICIN_DEMUXER 0 +#define CONFIG_DSS_DEMUXER 0 +#define CONFIG_DTS_DEMUXER 0 +#define CONFIG_DTSHD_DEMUXER 0 +#define CONFIG_DV_DEMUXER 0 +#define CONFIG_DVBSUB_DEMUXER 0 +#define CONFIG_DVBTXT_DEMUXER 0 +#define CONFIG_DXA_DEMUXER 0 +#define CONFIG_EA_DEMUXER 0 +#define CONFIG_EA_CDATA_DEMUXER 0 +#define CONFIG_EAC3_DEMUXER 0 +#define CONFIG_EPAF_DEMUXER 0 +#define CONFIG_FFMETADATA_DEMUXER 0 +#define CONFIG_FILMSTRIP_DEMUXER 0 +#define CONFIG_FITS_DEMUXER 0 +#define CONFIG_FLAC_DEMUXER 1 +#define CONFIG_FLIC_DEMUXER 0 +#define CONFIG_FLV_DEMUXER 0 +#define CONFIG_LIVE_FLV_DEMUXER 0 +#define CONFIG_FOURXM_DEMUXER 0 +#define CONFIG_FRM_DEMUXER 0 +#define CONFIG_FSB_DEMUXER 0 +#define CONFIG_FWSE_DEMUXER 0 +#define CONFIG_G722_DEMUXER 0 +#define CONFIG_G723_1_DEMUXER 0 +#define CONFIG_G726_DEMUXER 0 +#define CONFIG_G726LE_DEMUXER 0 +#define CONFIG_G729_DEMUXER 0 +#define CONFIG_GDV_DEMUXER 0 +#define CONFIG_GENH_DEMUXER 0 +#define CONFIG_GIF_DEMUXER 0 +#define CONFIG_GSM_DEMUXER 0 +#define CONFIG_GXF_DEMUXER 0 +#define CONFIG_H261_DEMUXER 0 +#define CONFIG_H263_DEMUXER 0 +#define CONFIG_H264_DEMUXER 0 +#define CONFIG_HCA_DEMUXER 0 +#define CONFIG_HCOM_DEMUXER 0 +#define CONFIG_HEVC_DEMUXER 0 +#define CONFIG_HLS_DEMUXER 0 +#define CONFIG_HNM_DEMUXER 0 +#define CONFIG_ICO_DEMUXER 0 +#define CONFIG_IDCIN_DEMUXER 0 +#define CONFIG_IDF_DEMUXER 0 +#define CONFIG_IFF_DEMUXER 0 +#define CONFIG_IFV_DEMUXER 0 +#define CONFIG_ILBC_DEMUXER 0 +#define CONFIG_IMAGE2_DEMUXER 0 +#define CONFIG_IMAGE2PIPE_DEMUXER 0 +#define CONFIG_IMAGE2_ALIAS_PIX_DEMUXER 0 +#define CONFIG_IMAGE2_BRENDER_PIX_DEMUXER 0 +#define CONFIG_IMF_DEMUXER 0 +#define CONFIG_INGENIENT_DEMUXER 0 +#define CONFIG_IPMOVIE_DEMUXER 0 +#define CONFIG_IPU_DEMUXER 0 +#define CONFIG_IRCAM_DEMUXER 0 +#define CONFIG_ISS_DEMUXER 0 +#define CONFIG_IV8_DEMUXER 0 +#define CONFIG_IVF_DEMUXER 0 +#define CONFIG_IVR_DEMUXER 0 +#define CONFIG_JACOSUB_DEMUXER 0 +#define CONFIG_JV_DEMUXER 0 +#define CONFIG_KUX_DEMUXER 0 +#define CONFIG_KVAG_DEMUXER 0 +#define CONFIG_LAF_DEMUXER 0 +#define CONFIG_LMLM4_DEMUXER 0 +#define CONFIG_LOAS_DEMUXER 0 +#define CONFIG_LUODAT_DEMUXER 0 +#define CONFIG_LRC_DEMUXER 0 +#define CONFIG_LVF_DEMUXER 0 +#define CONFIG_LXF_DEMUXER 0 +#define CONFIG_M4V_DEMUXER 0 +#define CONFIG_MCA_DEMUXER 0 +#define CONFIG_MCC_DEMUXER 0 +#define CONFIG_MATROSKA_DEMUXER 1 +#define CONFIG_MGSTS_DEMUXER 0 +#define CONFIG_MICRODVD_DEMUXER 0 +#define CONFIG_MJPEG_DEMUXER 0 +#define CONFIG_MJPEG_2000_DEMUXER 0 +#define CONFIG_MLP_DEMUXER 0 +#define CONFIG_MLV_DEMUXER 0 +#define CONFIG_MM_DEMUXER 0 +#define CONFIG_MMF_DEMUXER 0 +#define CONFIG_MODS_DEMUXER 0 +#define CONFIG_MOFLEX_DEMUXER 0 +#define CONFIG_MOV_DEMUXER 1 +#define CONFIG_MP3_DEMUXER 1 +#define CONFIG_MPC_DEMUXER 0 +#define CONFIG_MPC8_DEMUXER 0 +#define CONFIG_MPEGPS_DEMUXER 0 +#define CONFIG_MPEGTS_DEMUXER 0 +#define CONFIG_MPEGTSRAW_DEMUXER 0 +#define CONFIG_MPEGVIDEO_DEMUXER 0 +#define CONFIG_MPJPEG_DEMUXER 0 +#define CONFIG_MPL2_DEMUXER 0 +#define CONFIG_MPSUB_DEMUXER 0 +#define CONFIG_MSF_DEMUXER 0 +#define CONFIG_MSNWC_TCP_DEMUXER 0 +#define CONFIG_MSP_DEMUXER 0 +#define CONFIG_MTAF_DEMUXER 0 +#define CONFIG_MTV_DEMUXER 0 +#define CONFIG_MUSX_DEMUXER 0 +#define CONFIG_MV_DEMUXER 0 +#define CONFIG_MVI_DEMUXER 0 +#define CONFIG_MXF_DEMUXER 0 +#define CONFIG_MXG_DEMUXER 0 +#define CONFIG_NC_DEMUXER 0 +#define CONFIG_NISTSPHERE_DEMUXER 0 +#define CONFIG_NSP_DEMUXER 0 +#define CONFIG_NSV_DEMUXER 0 +#define CONFIG_NUT_DEMUXER 0 +#define CONFIG_NUV_DEMUXER 0 +#define CONFIG_OBU_DEMUXER 0 +#define CONFIG_OGG_DEMUXER 1 +#define CONFIG_OMA_DEMUXER 0 +#define CONFIG_PAF_DEMUXER 0 +#define CONFIG_PCM_ALAW_DEMUXER 0 +#define CONFIG_PCM_MULAW_DEMUXER 0 +#define CONFIG_PCM_VIDC_DEMUXER 0 +#define CONFIG_PCM_F64BE_DEMUXER 0 +#define CONFIG_PCM_F64LE_DEMUXER 0 +#define CONFIG_PCM_F32BE_DEMUXER 0 +#define CONFIG_PCM_F32LE_DEMUXER 0 +#define CONFIG_PCM_S32BE_DEMUXER 0 +#define CONFIG_PCM_S32LE_DEMUXER 0 +#define CONFIG_PCM_S24BE_DEMUXER 0 +#define CONFIG_PCM_S24LE_DEMUXER 0 +#define CONFIG_PCM_S16BE_DEMUXER 0 +#define CONFIG_PCM_S16LE_DEMUXER 0 +#define CONFIG_PCM_S8_DEMUXER 0 +#define CONFIG_PCM_U32BE_DEMUXER 0 +#define CONFIG_PCM_U32LE_DEMUXER 0 +#define CONFIG_PCM_U24BE_DEMUXER 0 +#define CONFIG_PCM_U24LE_DEMUXER 0 +#define CONFIG_PCM_U16BE_DEMUXER 0 +#define CONFIG_PCM_U16LE_DEMUXER 0 +#define CONFIG_PCM_U8_DEMUXER 0 +#define CONFIG_PJS_DEMUXER 0 +#define CONFIG_PMP_DEMUXER 0 +#define CONFIG_PP_BNK_DEMUXER 0 +#define CONFIG_PVA_DEMUXER 0 +#define CONFIG_PVF_DEMUXER 0 +#define CONFIG_QCP_DEMUXER 0 +#define CONFIG_R3D_DEMUXER 0 +#define CONFIG_RAWVIDEO_DEMUXER 0 +#define CONFIG_REALTEXT_DEMUXER 0 +#define CONFIG_REDSPARK_DEMUXER 0 +#define CONFIG_RL2_DEMUXER 0 +#define CONFIG_RM_DEMUXER 0 +#define CONFIG_ROQ_DEMUXER 0 +#define CONFIG_RPL_DEMUXER 0 +#define CONFIG_RSD_DEMUXER 0 +#define CONFIG_RSO_DEMUXER 0 +#define CONFIG_RTP_DEMUXER 0 +#define CONFIG_RTSP_DEMUXER 0 +#define CONFIG_S337M_DEMUXER 0 +#define CONFIG_SAMI_DEMUXER 0 +#define CONFIG_SAP_DEMUXER 0 +#define CONFIG_SBC_DEMUXER 0 +#define CONFIG_SBG_DEMUXER 0 +#define CONFIG_SCC_DEMUXER 0 +#define CONFIG_SCD_DEMUXER 0 +#define CONFIG_SDP_DEMUXER 0 +#define CONFIG_SDR2_DEMUXER 0 +#define CONFIG_SDS_DEMUXER 0 +#define CONFIG_SDX_DEMUXER 0 +#define CONFIG_SEGAFILM_DEMUXER 0 +#define CONFIG_SER_DEMUXER 0 +#define CONFIG_SGA_DEMUXER 0 +#define CONFIG_SHORTEN_DEMUXER 0 +#define CONFIG_SIFF_DEMUXER 0 +#define CONFIG_SIMBIOSIS_IMX_DEMUXER 0 +#define CONFIG_SLN_DEMUXER 0 +#define CONFIG_SMACKER_DEMUXER 0 +#define CONFIG_SMJPEG_DEMUXER 0 +#define CONFIG_SMUSH_DEMUXER 0 +#define CONFIG_SOL_DEMUXER 0 +#define CONFIG_SOX_DEMUXER 0 +#define CONFIG_SPDIF_DEMUXER 0 +#define CONFIG_SRT_DEMUXER 0 +#define CONFIG_STR_DEMUXER 0 +#define CONFIG_STL_DEMUXER 0 +#define CONFIG_SUBVIEWER1_DEMUXER 0 +#define CONFIG_SUBVIEWER_DEMUXER 0 +#define CONFIG_SUP_DEMUXER 0 +#define CONFIG_SVAG_DEMUXER 0 +#define CONFIG_SVS_DEMUXER 0 +#define CONFIG_SWF_DEMUXER 0 +#define CONFIG_TAK_DEMUXER 0 +#define CONFIG_TEDCAPTIONS_DEMUXER 0 +#define CONFIG_THP_DEMUXER 0 +#define CONFIG_THREEDOSTR_DEMUXER 0 +#define CONFIG_TIERTEXSEQ_DEMUXER 0 +#define CONFIG_TMV_DEMUXER 0 +#define CONFIG_TRUEHD_DEMUXER 0 +#define CONFIG_TTA_DEMUXER 0 +#define CONFIG_TXD_DEMUXER 0 +#define CONFIG_TTY_DEMUXER 0 +#define CONFIG_TY_DEMUXER 0 +#define CONFIG_V210_DEMUXER 0 +#define CONFIG_V210X_DEMUXER 0 +#define CONFIG_VAG_DEMUXER 0 +#define CONFIG_VC1_DEMUXER 0 +#define CONFIG_VC1T_DEMUXER 0 +#define CONFIG_VIVIDAS_DEMUXER 0 +#define CONFIG_VIVO_DEMUXER 0 +#define CONFIG_VMD_DEMUXER 0 +#define CONFIG_VOBSUB_DEMUXER 0 +#define CONFIG_VOC_DEMUXER 0 +#define CONFIG_VPK_DEMUXER 0 +#define CONFIG_VPLAYER_DEMUXER 0 +#define CONFIG_VQF_DEMUXER 0 +#define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 +#define CONFIG_WAV_DEMUXER 1 +#define CONFIG_WC3_DEMUXER 0 +#define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 +#define CONFIG_WEBVTT_DEMUXER 0 +#define CONFIG_WSAUD_DEMUXER 0 +#define CONFIG_WSD_DEMUXER 0 +#define CONFIG_WSVQA_DEMUXER 0 +#define CONFIG_WTV_DEMUXER 0 +#define CONFIG_WVE_DEMUXER 0 +#define CONFIG_WV_DEMUXER 0 +#define CONFIG_XA_DEMUXER 0 +#define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 +#define CONFIG_XMV_DEMUXER 0 +#define CONFIG_XVAG_DEMUXER 0 +#define CONFIG_XWMA_DEMUXER 0 +#define CONFIG_YOP_DEMUXER 0 +#define CONFIG_YUV4MPEGPIPE_DEMUXER 0 +#define CONFIG_IMAGE_BMP_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_CRI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_DDS_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_DPX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_EXR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_GEM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_GIF_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_HDR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_J2K_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEGLS_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PAM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PBM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PCX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PFM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGMYUV_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PGX_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PHM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PHOTOCD_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PICTOR_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PNG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PPM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_PSD_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_QDRAW_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_QOI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SGI_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SVG_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_TIFF_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_VBN_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_WEBP_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XBM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XPM_PIPE_DEMUXER 0 +#define CONFIG_IMAGE_XWD_PIPE_DEMUXER 0 +#define CONFIG_LIBGME_DEMUXER 0 +#define CONFIG_LIBMODPLUG_DEMUXER 0 +#define CONFIG_LIBOPENMPT_DEMUXER 0 +#define CONFIG_VAPOURSYNTH_DEMUXER 0 +#define CONFIG_A64_MUXER 0 +#define CONFIG_AC3_MUXER 0 +#define CONFIG_ADTS_MUXER 0 +#define CONFIG_ADX_MUXER 0 +#define CONFIG_AIFF_MUXER 0 +#define CONFIG_ALP_MUXER 0 +#define CONFIG_AMR_MUXER 0 +#define CONFIG_AMV_MUXER 0 +#define CONFIG_APM_MUXER 0 +#define CONFIG_APNG_MUXER 0 +#define CONFIG_APTX_MUXER 0 +#define CONFIG_APTX_HD_MUXER 0 +#define CONFIG_ARGO_ASF_MUXER 0 +#define CONFIG_ARGO_CVG_MUXER 0 +#define CONFIG_ASF_MUXER 0 +#define CONFIG_ASS_MUXER 0 +#define CONFIG_AST_MUXER 0 +#define CONFIG_ASF_STREAM_MUXER 0 +#define CONFIG_AU_MUXER 0 +#define CONFIG_AVI_MUXER 0 +#define CONFIG_AVIF_MUXER 0 +#define CONFIG_AVM2_MUXER 0 +#define CONFIG_AVS2_MUXER 0 +#define CONFIG_AVS3_MUXER 0 +#define CONFIG_BIT_MUXER 0 +#define CONFIG_CAF_MUXER 0 +#define CONFIG_CAVSVIDEO_MUXER 0 +#define CONFIG_CODEC2_MUXER 0 +#define CONFIG_CODEC2RAW_MUXER 0 +#define CONFIG_CRC_MUXER 0 +#define CONFIG_DASH_MUXER 0 +#define CONFIG_DATA_MUXER 0 +#define CONFIG_DAUD_MUXER 0 +#define CONFIG_DFPWM_MUXER 0 +#define CONFIG_DIRAC_MUXER 0 +#define CONFIG_DNXHD_MUXER 0 +#define CONFIG_DTS_MUXER 0 +#define CONFIG_DV_MUXER 0 +#define CONFIG_EAC3_MUXER 0 +#define CONFIG_F4V_MUXER 0 +#define CONFIG_FFMETADATA_MUXER 0 +#define CONFIG_FIFO_MUXER 0 +#define CONFIG_FIFO_TEST_MUXER 0 +#define CONFIG_FILMSTRIP_MUXER 0 +#define CONFIG_FITS_MUXER 0 +#define CONFIG_FLAC_MUXER 0 +#define CONFIG_FLV_MUXER 0 +#define CONFIG_FRAMECRC_MUXER 0 +#define CONFIG_FRAMEHASH_MUXER 0 +#define CONFIG_FRAMEMD5_MUXER 0 +#define CONFIG_G722_MUXER 0 +#define CONFIG_G723_1_MUXER 0 +#define CONFIG_G726_MUXER 0 +#define CONFIG_G726LE_MUXER 0 +#define CONFIG_GIF_MUXER 0 +#define CONFIG_GSM_MUXER 0 +#define CONFIG_GXF_MUXER 0 +#define CONFIG_H261_MUXER 0 +#define CONFIG_H263_MUXER 0 +#define CONFIG_H264_MUXER 0 +#define CONFIG_HASH_MUXER 0 +#define CONFIG_HDS_MUXER 0 +#define CONFIG_HEVC_MUXER 0 +#define CONFIG_HLS_MUXER 0 +#define CONFIG_ICO_MUXER 0 +#define CONFIG_ILBC_MUXER 0 +#define CONFIG_IMAGE2_MUXER 0 +#define CONFIG_IMAGE2PIPE_MUXER 0 +#define CONFIG_IPOD_MUXER 0 +#define CONFIG_IRCAM_MUXER 0 +#define CONFIG_ISMV_MUXER 0 +#define CONFIG_IVF_MUXER 0 +#define CONFIG_JACOSUB_MUXER 0 +#define CONFIG_KVAG_MUXER 0 +#define CONFIG_LATM_MUXER 0 +#define CONFIG_LRC_MUXER 0 +#define CONFIG_M4V_MUXER 0 +#define CONFIG_MD5_MUXER 0 +#define CONFIG_MATROSKA_MUXER 0 +#define CONFIG_MATROSKA_AUDIO_MUXER 0 +#define CONFIG_MICRODVD_MUXER 0 +#define CONFIG_MJPEG_MUXER 0 +#define CONFIG_MLP_MUXER 0 +#define CONFIG_MMF_MUXER 0 +#define CONFIG_MOV_MUXER 0 +#define CONFIG_MP2_MUXER 0 +#define CONFIG_MP3_MUXER 0 +#define CONFIG_MP4_MUXER 0 +#define CONFIG_MPEG1SYSTEM_MUXER 0 +#define CONFIG_MPEG1VCD_MUXER 0 +#define CONFIG_MPEG1VIDEO_MUXER 0 +#define CONFIG_MPEG2DVD_MUXER 0 +#define CONFIG_MPEG2SVCD_MUXER 0 +#define CONFIG_MPEG2VIDEO_MUXER 0 +#define CONFIG_MPEG2VOB_MUXER 0 +#define CONFIG_MPEGTS_MUXER 0 +#define CONFIG_MPJPEG_MUXER 0 +#define CONFIG_MXF_MUXER 0 +#define CONFIG_MXF_D10_MUXER 0 +#define CONFIG_MXF_OPATOM_MUXER 0 +#define CONFIG_NULL_MUXER 0 +#define CONFIG_NUT_MUXER 0 +#define CONFIG_OBU_MUXER 0 +#define CONFIG_OGA_MUXER 0 +#define CONFIG_OGG_MUXER 0 +#define CONFIG_OGV_MUXER 0 +#define CONFIG_OMA_MUXER 0 +#define CONFIG_OPUS_MUXER 0 +#define CONFIG_PCM_ALAW_MUXER 0 +#define CONFIG_PCM_MULAW_MUXER 0 +#define CONFIG_PCM_VIDC_MUXER 0 +#define CONFIG_PCM_F64BE_MUXER 0 +#define CONFIG_PCM_F64LE_MUXER 0 +#define CONFIG_PCM_F32BE_MUXER 0 +#define CONFIG_PCM_F32LE_MUXER 0 +#define CONFIG_PCM_S32BE_MUXER 0 +#define CONFIG_PCM_S32LE_MUXER 0 +#define CONFIG_PCM_S24BE_MUXER 0 +#define CONFIG_PCM_S24LE_MUXER 0 +#define CONFIG_PCM_S16BE_MUXER 0 +#define CONFIG_PCM_S16LE_MUXER 0 +#define CONFIG_PCM_S8_MUXER 0 +#define CONFIG_PCM_U32BE_MUXER 0 +#define CONFIG_PCM_U32LE_MUXER 0 +#define CONFIG_PCM_U24BE_MUXER 0 +#define CONFIG_PCM_U24LE_MUXER 0 +#define CONFIG_PCM_U16BE_MUXER 0 +#define CONFIG_PCM_U16LE_MUXER 0 +#define CONFIG_PCM_U8_MUXER 0 +#define CONFIG_PSP_MUXER 0 +#define CONFIG_RAWVIDEO_MUXER 0 +#define CONFIG_RM_MUXER 0 +#define CONFIG_ROQ_MUXER 0 +#define CONFIG_RSO_MUXER 0 +#define CONFIG_RTP_MUXER 0 +#define CONFIG_RTP_MPEGTS_MUXER 0 +#define CONFIG_RTSP_MUXER 0 +#define CONFIG_SAP_MUXER 0 +#define CONFIG_SBC_MUXER 0 +#define CONFIG_SCC_MUXER 0 +#define CONFIG_SEGAFILM_MUXER 0 +#define CONFIG_SEGMENT_MUXER 0 +#define CONFIG_STREAM_SEGMENT_MUXER 0 +#define CONFIG_SMJPEG_MUXER 0 +#define CONFIG_SMOOTHSTREAMING_MUXER 0 +#define CONFIG_SOX_MUXER 0 +#define CONFIG_SPX_MUXER 0 +#define CONFIG_SPDIF_MUXER 0 +#define CONFIG_SRT_MUXER 0 +#define CONFIG_STREAMHASH_MUXER 0 +#define CONFIG_SUP_MUXER 0 +#define CONFIG_SWF_MUXER 0 +#define CONFIG_TEE_MUXER 0 +#define CONFIG_TG2_MUXER 0 +#define CONFIG_TGP_MUXER 0 +#define CONFIG_MKVTIMESTAMP_V2_MUXER 0 +#define CONFIG_TRUEHD_MUXER 0 +#define CONFIG_TTA_MUXER 0 +#define CONFIG_TTML_MUXER 0 +#define CONFIG_UNCODEDFRAMECRC_MUXER 0 +#define CONFIG_VC1_MUXER 0 +#define CONFIG_VC1T_MUXER 0 +#define CONFIG_VOC_MUXER 0 +#define CONFIG_W64_MUXER 0 +#define CONFIG_WAV_MUXER 0 +#define CONFIG_WEBM_MUXER 0 +#define CONFIG_WEBM_DASH_MANIFEST_MUXER 0 +#define CONFIG_WEBM_CHUNK_MUXER 0 +#define CONFIG_WEBP_MUXER 0 +#define CONFIG_WEBVTT_MUXER 0 +#define CONFIG_WSAUD_MUXER 0 +#define CONFIG_WTV_MUXER 0 +#define CONFIG_WV_MUXER 0 +#define CONFIG_YUV4MPEGPIPE_MUXER 0 +#define CONFIG_CHROMAPRINT_MUXER 0 +#define CONFIG_ASYNC_PROTOCOL 0 +#define CONFIG_BLURAY_PROTOCOL 0 +#define CONFIG_CACHE_PROTOCOL 0 +#define CONFIG_CONCAT_PROTOCOL 0 +#define CONFIG_CONCATF_PROTOCOL 0 +#define CONFIG_CRYPTO_PROTOCOL 0 +#define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 +#define CONFIG_FFRTMPCRYPT_PROTOCOL 0 +#define CONFIG_FFRTMPHTTP_PROTOCOL 0 +#define CONFIG_FILE_PROTOCOL 0 +#define CONFIG_FTP_PROTOCOL 0 +#define CONFIG_GOPHER_PROTOCOL 0 +#define CONFIG_GOPHERS_PROTOCOL 0 +#define CONFIG_HLS_PROTOCOL 0 +#define CONFIG_HTTP_PROTOCOL 0 +#define CONFIG_HTTPPROXY_PROTOCOL 0 +#define CONFIG_HTTPS_PROTOCOL 0 +#define CONFIG_ICECAST_PROTOCOL 0 +#define CONFIG_MMSH_PROTOCOL 0 +#define CONFIG_MMST_PROTOCOL 0 +#define CONFIG_MD5_PROTOCOL 0 +#define CONFIG_PIPE_PROTOCOL 0 +#define CONFIG_PROMPEG_PROTOCOL 0 +#define CONFIG_RTMP_PROTOCOL 0 +#define CONFIG_RTMPE_PROTOCOL 0 +#define CONFIG_RTMPS_PROTOCOL 0 +#define CONFIG_RTMPT_PROTOCOL 0 +#define CONFIG_RTMPTE_PROTOCOL 0 +#define CONFIG_RTMPTS_PROTOCOL 0 +#define CONFIG_RTP_PROTOCOL 0 +#define CONFIG_SCTP_PROTOCOL 0 +#define CONFIG_SRTP_PROTOCOL 0 +#define CONFIG_SUBFILE_PROTOCOL 0 +#define CONFIG_TEE_PROTOCOL 0 +#define CONFIG_TCP_PROTOCOL 0 +#define CONFIG_TLS_PROTOCOL 0 +#define CONFIG_UDP_PROTOCOL 0 +#define CONFIG_UDPLITE_PROTOCOL 0 +#define CONFIG_UNIX_PROTOCOL 0 +#define CONFIG_LIBAMQP_PROTOCOL 0 +#define CONFIG_LIBRIST_PROTOCOL 0 +#define CONFIG_LIBRTMP_PROTOCOL 0 +#define CONFIG_LIBRTMPE_PROTOCOL 0 +#define CONFIG_LIBRTMPS_PROTOCOL 0 +#define CONFIG_LIBRTMPT_PROTOCOL 0 +#define CONFIG_LIBRTMPTE_PROTOCOL 0 +#define CONFIG_LIBSRT_PROTOCOL 0 +#define CONFIG_LIBSSH_PROTOCOL 0 +#define CONFIG_LIBSMBCLIENT_PROTOCOL 0 +#define CONFIG_LIBZMQ_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 +#endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/bsf_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/bsf_list.c new file mode 100644 index 00000000..7ff70c6e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/bsf_list.c @@ -0,0 +1,2 @@ +static const FFBitStreamFilter * const bitstream_filters[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/codec_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/codec_list.c new file mode 100644 index 00000000..9181e1cb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/codec_list.c @@ -0,0 +1,19 @@ +static const FFCodec * const codec_list[] = { + &ff_theora_decoder, + &ff_vp3_decoder, + &ff_vp8_decoder, + &ff_flac_decoder, + &ff_mp3_decoder, + &ff_vorbis_decoder, + &ff_pcm_alaw_decoder, + &ff_pcm_f32le_decoder, + &ff_pcm_mulaw_decoder, + &ff_pcm_s16be_decoder, + &ff_pcm_s16le_decoder, + &ff_pcm_s24be_decoder, + &ff_pcm_s24le_decoder, + &ff_pcm_s32le_decoder, + &ff_pcm_u8_decoder, + &ff_libopus_decoder, + &ff_hevc_decoder, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/parser_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/parser_list.c new file mode 100644 index 00000000..2d65b7d8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavcodec/parser_list.c @@ -0,0 +1,10 @@ +static const AVCodecParser * const parser_list[] = { + &ff_flac_parser, + &ff_mpegaudio_parser, + &ff_opus_parser, + &ff_vorbis_parser, + &ff_vp3_parser, + &ff_vp8_parser, + &ff_vp9_parser, + &ff_hevc_parser, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/demuxer_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/demuxer_list.c new file mode 100644 index 00000000..1908ba19 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/demuxer_list.c @@ -0,0 +1,8 @@ +static const AVInputFormat * const demuxer_list[] = { + &ff_flac_demuxer, + &ff_matroska_demuxer, + &ff_mov_demuxer, + &ff_mp3_demuxer, + &ff_ogg_demuxer, + &ff_wav_demuxer, + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/muxer_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/muxer_list.c new file mode 100644 index 00000000..f36d9499 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/muxer_list.c @@ -0,0 +1,2 @@ +static const AVOutputFormat * const muxer_list[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/protocol_list.c b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/protocol_list.c new file mode 100644 index 00000000..247e1e4c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavformat/protocol_list.c @@ -0,0 +1,2 @@ +static const URLProtocol * const url_protocols[] = { + NULL }; diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/avconfig.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/avconfig.h new file mode 100644 index 00000000..c289fbb5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/avconfig.h @@ -0,0 +1,6 @@ +/* Generated by ffmpeg configure */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#define AV_HAVE_FAST_UNALIGNED 1 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/ffversion.h new file mode 100644 index 00000000..52669657 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/ios/arm64/libavutil/ffversion.h @@ -0,0 +1,5 @@ +/* Automatically generated by version.sh, do not manually edit! */ +#ifndef AVUTIL_FFVERSION_H +#define AVUTIL_FFVERSION_H +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" +#endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config.h index 5f0937fe..36b794b4 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --disable-asm --disable-inline-asm --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 0 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux-noasm/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config.h index 9671f0a0..46635d7e 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --enable-neon --extra-cflags='-mfpu=neon' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm-neon/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config.h index 14f05509..a2678068 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp --enable-thumb --extra-cflags='-march=armv7-a' --enable-cross-compile --target-os=linux --extra-cflags='--target=arm-linux-gnueabihf' --extra-ldflags='--target=arm-linux-gnueabihf' --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm-sysroot --extra-cflags='-mtune=cortex-a8' --extra-cflags='-mfloat-abi=hard' --extra-cflags=-O2 --disable-neon --extra-cflags='-mfpu=vfpv3-d16' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config.h index 33038f5c..1aca957e 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/tguilbert/Code/chromium/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-cross-compile --cross-prefix=/usr/bin/aarch64-linux-gnu- --extra-cflags='--target=aarch64-linux-gnu' --extra-ldflags='--target=aarch64-linux-gnu' --target-os=linux --sysroot=/usr/local/google/home/liberato/src/release_chrome/src/build/linux/debian_bullseye_arm64-sysroot --arch=aarch64 --enable-armv8 --extra-cflags='-march=armv8-a' --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.asm index 0e10a0da..0de658c2 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.h index 343111ef..ec558afd 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --arch=i686 --extra-cflags='\"-m32\"' --extra-ldflags='\"-m32\"' --enable-pic --cc=clang --cxx=clang++ --ld=clang" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.asm index 9b1d41a4..38e39e9c 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 1 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 0 +%define CONFIG_HEVC_SEI 0 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.h index 74b4eac7..0f7ec2a3 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-lto --arch=x86_64 --target-os=linux --enable-pic --cc=clang --cxx=clang++ --ld=clang --extra-ldflags='-fuse-ld=lld'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME linux #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/linux/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config.h index 2dad67d0..c90abc8c 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=arm64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=arm64 --extra-cflags='-arch arm64' --extra-ldflags='-arch arm64'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME darwin #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 1 -#define HAVE_CEXP 1 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.asm index 75de6f58..65d1f0eb 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 0 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 1 -%define HAVE_CEXP 1 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.h index a41e7bd6..a3cda071 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=x86_64-apple-macosx' --extra-cflags=-F/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/tguilbert/Code/chromium/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/tguilbert/Code/chromium/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=x86_64 --extra-cflags=-m64 --extra-ldflags='-arch x86_64'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --enable-pic --cc=clang --cxx=clang++ --ld=clang --enable-cross-compile --cc=clang --ld=ld64.lld --nm=llvm-nm --ar=llvm-ar --target-os=darwin --extra-cflags='--target=x86_64-apple-macosx' --extra-cflags=-F/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks --extra-cflags='-mmacosx-version-min=10.10' --extra-cflags=-fblocks --extra-cflags=-nostdinc --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include --extra-cflags=-isystem/usr/local/google/home/liberato/src/release_chrome/src/third_party/llvm-build/Release+Asserts/lib/clang/16/include --extra-ldflags=-syslibroot --extra-ldflags=/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk --extra-ldflags=-L/usr/local/google/home/liberato/src/release_chrome/src/build/mac_files/xcode_binaries/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib --extra-ldflags=-lSystem --extra-ldflags=-macosx_version_min --extra-ldflags=10.10 --extra-ldflags=-sdk_version --extra-ldflags=10.10 --extra-ldflags=-platform_version --extra-ldflags=macos --extra-ldflags=10.10 --extra-ldflags=10.10 --arch=x86_64 --extra-cflags=-m64 --extra-ldflags='-arch x86_64'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME darwin #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 1 -#define HAVE_CEXP 1 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/mac/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config.h index d0d83c14..93b1a4bf 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --arch=aarch64 --as=clang-cl --extra-cflags='--target=arm64-windows' --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --arch=aarch64 --as=clang-cl --extra-cflags='--target=arm64-windows' --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win32 #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 0 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 0 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/arm64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.asm index 836c2325..47f68291 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 1 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.h index e4c9c405..d8f4dd95 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=-m32 --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=-m32 --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win32 #define av_restrict restrict #define EXTERN_PREFIX "_" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 1 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/ia32/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.asm b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.asm index 429986a0..fd23141e 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.asm +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.asm @@ -190,8 +190,6 @@ %define HAVE_RDTSC 1 %define HAVE_SEM_TIMEDWAIT 0 %define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -%define HAVE_CABS 0 -%define HAVE_CEXP 0 %define HAVE_INLINE_ASM 1 %define HAVE_SYMVER 0 %define HAVE_X86ASM 1 @@ -433,6 +431,7 @@ %define CONFIG_TRANSCODING_EXAMPLE 0 %define CONFIG_VAAPI_ENCODE_EXAMPLE 0 %define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +%define CONFIG_QSV_TRANSCODE_EXAMPLE 0 %define CONFIG_AVISYNTH 0 %define CONFIG_FREI0R 0 %define CONFIG_LIBCDIO 0 @@ -669,7 +668,9 @@ %define CONFIG_H264PARSE 0 %define CONFIG_H264PRED 1 %define CONFIG_H264QPEL 0 +%define CONFIG_H264_SEI 0 %define CONFIG_HEVCPARSE 1 +%define CONFIG_HEVC_SEI 1 %define CONFIG_HPELDSP 1 %define CONFIG_HUFFMAN 0 %define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.h index e92d9d67..26c18b2c 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config.h @@ -1,12 +1,12 @@ /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H #define FFMPEG_CONFIG_H -/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/tguilbert/Code/chromium/src/third_party/ffmpeg/chromium/include/win --target-os=win64 --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=/winsysroot/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/tguilbert/Code/chromium/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ +/* #define FFMPEG_CONFIGURATION "--disable-everything --disable-all --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-static --enable-avcodec --enable-avformat --enable-avutil --enable-fft --enable-rdft --enable-static --enable-libopus --disable-debug --disable-bzlib --disable-error-resilience --disable-iconv --disable-network --disable-schannel --disable-sdl2 --disable-symver --disable-xlib --disable-zlib --disable-securetransport --disable-faan --disable-alsa --disable-autodetect --enable-decoder='vorbis,libopus,flac' --enable-decoder='pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3' --enable-decoder='pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw' --enable-demuxer='ogg,matroska,wav,flac,mp3,mov' --enable-parser='opus,vorbis,flac,mpegaudio,vp9' --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/opus/src/include --disable-linux-perf --x86asmexe=nasm --optflags='\"-O2\"' --enable-decoder='theora,vp8' --enable-parser='vp3,vp8' --toolchain=msvc --extra-cflags=-I/usr/local/google/home/liberato/src/release_chrome/src/third_party/ffmpeg/chromium/include/win --target-os=win64 --enable-cross-compile --cc=clang-cl --ld=lld-link --nm=llvm-nm --ar=llvm-ar --extra-cflags=-O2 --extra-cflags=/winsysroot/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82 --extra-ldflags='/winsysroot:/usr/local/google/home/liberato/src/release_chrome/src/third_party/depot_tools/win_toolchain/vs_files/1023ce2e82'" -- elide long configuration string from binary */ #define FFMPEG_LICENSE "LGPL version 2.1 or later" -#define CONFIG_THIS_YEAR 2022 +#define CONFIG_THIS_YEAR 2023 #define FFMPEG_DATADIR "/usr/local/share/ffmpeg" #define AVCONV_DATADIR "/usr/local/share/ffmpeg" -#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 094c0eccdf959c3b9c85219e33c3fcfbab024b61)" +#define CC_IDENT "clang version 16.0.0 (https://chromium.googlesource.com/a/external/github.com/llvm/llvm-project 39da55e8f548a11f7dadefa73ea73d809a5f1729)" #define OS_NAME win64 #define av_restrict restrict #define EXTERN_PREFIX "" @@ -206,8 +206,6 @@ #define HAVE_RDTSC 1 #define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SYNC_VAL_COMPARE_AND_SWAP 1 -#define HAVE_CABS 0 -#define HAVE_CEXP 0 #define HAVE_INLINE_ASM 1 #define HAVE_SYMVER 0 #define HAVE_X86ASM 1 @@ -449,6 +447,7 @@ #define CONFIG_TRANSCODING_EXAMPLE 0 #define CONFIG_VAAPI_ENCODE_EXAMPLE 0 #define CONFIG_VAAPI_TRANSCODE_EXAMPLE 0 +#define CONFIG_QSV_TRANSCODE_EXAMPLE 0 #define CONFIG_AVISYNTH 0 #define CONFIG_FREI0R 0 #define CONFIG_LIBCDIO 0 @@ -685,7 +684,9 @@ #define CONFIG_H264PARSE 0 #define CONFIG_H264PRED 1 #define CONFIG_H264QPEL 0 +#define CONFIG_H264_SEI 0 #define CONFIG_HEVCPARSE 1 +#define CONFIG_HEVC_SEI 1 #define CONFIG_HPELDSP 1 #define CONFIG_HUFFMAN 0 #define CONFIG_HUFFYUVDSP 0 diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config_components.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config_components.h index 4edcd1a3..397677d9 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config_components.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/config_components.h @@ -20,6 +20,7 @@ #define CONFIG_HEVC_METADATA_BSF 0 #define CONFIG_HEVC_MP4TOANNEXB_BSF 0 #define CONFIG_IMX_DUMP_HEADER_BSF 0 +#define CONFIG_MEDIA100_TO_MJPEGB_BSF 0 #define CONFIG_MJPEG2JPEG_BSF 0 #define CONFIG_MJPEGA_DUMP_HEADER_BSF 0 #define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0 @@ -469,6 +470,7 @@ #define CONFIG_PCM_U32BE_DECODER 0 #define CONFIG_PCM_U32LE_DECODER 0 #define CONFIG_PCM_VIDC_DECODER 0 +#define CONFIG_CBD2_DPCM_DECODER 0 #define CONFIG_DERF_DPCM_DECODER 0 #define CONFIG_GREMLIN_DPCM_DECODER 0 #define CONFIG_INTERPLAY_DPCM_DECODER 0 @@ -476,6 +478,7 @@ #define CONFIG_SDX2_DPCM_DECODER 0 #define CONFIG_SOL_DPCM_DECODER 0 #define CONFIG_XAN_DPCM_DECODER 0 +#define CONFIG_WADY_DPCM_DECODER 0 #define CONFIG_ADPCM_4XM_DECODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 @@ -525,6 +528,7 @@ #define CONFIG_ADPCM_THP_LE_DECODER 0 #define CONFIG_ADPCM_VIMA_DECODER 0 #define CONFIG_ADPCM_XA_DECODER 0 +#define CONFIG_ADPCM_XMD_DECODER 0 #define CONFIG_ADPCM_YAMAHA_DECODER 0 #define CONFIG_ADPCM_ZORK_DECODER 0 #define CONFIG_SSA_DECODER 0 @@ -591,6 +595,7 @@ #define CONFIG_LIBAOM_AV1_DECODER 0 #define CONFIG_AV1_DECODER 0 #define CONFIG_AV1_CUVID_DECODER 0 +#define CONFIG_AV1_MEDIACODEC_DECODER 0 #define CONFIG_AV1_QSV_DECODER 0 #define CONFIG_LIBOPENH264_DECODER 0 #define CONFIG_H264_CUVID_DECODER 0 @@ -609,6 +614,8 @@ #define CONFIG_VP9_CUVID_DECODER 0 #define CONFIG_VP9_MEDIACODEC_DECODER 0 #define CONFIG_VP9_QSV_DECODER 0 +#define CONFIG_VNULL_DECODER 0 +#define CONFIG_ANULL_DECODER 0 #define CONFIG_A64MULTI_ENCODER 0 #define CONFIG_A64MULTI5_ENCODER 0 #define CONFIG_ALIAS_PIX_ENCODER 0 @@ -826,6 +833,7 @@ #define CONFIG_H263_V4L2M2M_ENCODER 0 #define CONFIG_AV1_NVENC_ENCODER 0 #define CONFIG_AV1_QSV_ENCODER 0 +#define CONFIG_AV1_AMF_ENCODER 0 #define CONFIG_LIBOPENH264_ENCODER 0 #define CONFIG_H264_AMF_ENCODER 0 #define CONFIG_H264_MF_ENCODER 0 @@ -856,6 +864,8 @@ #define CONFIG_VP8_VAAPI_ENCODER 0 #define CONFIG_VP9_VAAPI_ENCODER 0 #define CONFIG_VP9_QSV_ENCODER 0 +#define CONFIG_VNULL_ENCODER 0 +#define CONFIG_ANULL_ENCODER 0 #define CONFIG_AV1_D3D11VA_HWACCEL 0 #define CONFIG_AV1_D3D11VA2_HWACCEL 0 #define CONFIG_AV1_DXVA2_HWACCEL 0 @@ -1021,6 +1031,7 @@ #define CONFIG_ADELAY_FILTER 0 #define CONFIG_ADENORM_FILTER 0 #define CONFIG_ADERIVATIVE_FILTER 0 +#define CONFIG_ADRC_FILTER 0 #define CONFIG_ADYNAMICEQUALIZER_FILTER 0 #define CONFIG_ADYNAMICSMOOTH_FILTER 0 #define CONFIG_AECHO_FILTER 0 @@ -1143,6 +1154,7 @@ #define CONFIG_VOLUME_FILTER 0 #define CONFIG_VOLUMEDETECT_FILTER 0 #define CONFIG_AEVALSRC_FILTER 0 +#define CONFIG_AFDELAYSRC_FILTER 0 #define CONFIG_AFIRSRC_FILTER 0 #define CONFIG_ANOISESRC_FILTER 0 #define CONFIG_ANULLSRC_FILTER 0 @@ -1204,6 +1216,7 @@ #define CONFIG_CONVOLVE_FILTER 0 #define CONFIG_COPY_FILTER 0 #define CONFIG_COREIMAGE_FILTER 0 +#define CONFIG_CORR_FILTER 0 #define CONFIG_COVER_RECT_FILTER 0 #define CONFIG_CROP_FILTER 0 #define CONFIG_CROPDETECT_FILTER 0 @@ -1438,6 +1451,7 @@ #define CONFIG_SPP_FILTER 0 #define CONFIG_SR_FILTER 0 #define CONFIG_SSIM_FILTER 0 +#define CONFIG_SSIM360_FILTER 0 #define CONFIG_STEREO3D_FILTER 0 #define CONFIG_STREAMSELECT_FILTER 0 #define CONFIG_SUBTITLES_FILTER 0 @@ -1502,6 +1516,9 @@ #define CONFIG_ZMQ_FILTER 0 #define CONFIG_ZOOMPAN_FILTER 0 #define CONFIG_ZSCALE_FILTER 0 +#define CONFIG_HSTACK_VAAPI_FILTER 0 +#define CONFIG_VSTACK_VAAPI_FILTER 0 +#define CONFIG_XSTACK_VAAPI_FILTER 0 #define CONFIG_ALLRGB_FILTER 0 #define CONFIG_ALLYUV_FILTER 0 #define CONFIG_CELLAUTO_FILTER 0 @@ -1537,6 +1554,7 @@ #define CONFIG_AVECTORSCOPE_FILTER 0 #define CONFIG_CONCAT_FILTER 0 #define CONFIG_SHOWCQT_FILTER 0 +#define CONFIG_SHOWCWT_FILTER 0 #define CONFIG_SHOWFREQS_FILTER 0 #define CONFIG_SHOWSPATIAL_FILTER 0 #define CONFIG_SHOWSPECTRUM_FILTER 0 @@ -1838,6 +1856,7 @@ #define CONFIG_VPLAYER_DEMUXER 0 #define CONFIG_VQF_DEMUXER 0 #define CONFIG_W64_DEMUXER 0 +#define CONFIG_WADY_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1 #define CONFIG_WC3_DEMUXER 0 #define CONFIG_WEBM_DASH_MANIFEST_DEMUXER 0 @@ -1850,6 +1869,7 @@ #define CONFIG_WV_DEMUXER 0 #define CONFIG_XA_DEMUXER 0 #define CONFIG_XBIN_DEMUXER 0 +#define CONFIG_XMD_DEMUXER 0 #define CONFIG_XMV_DEMUXER 0 #define CONFIG_XVAG_DEMUXER 0 #define CONFIG_XWMA_DEMUXER 0 @@ -2077,6 +2097,7 @@ #define CONFIG_CONCATF_PROTOCOL 0 #define CONFIG_CRYPTO_PROTOCOL 0 #define CONFIG_DATA_PROTOCOL 0 +#define CONFIG_FD_PROTOCOL 0 #define CONFIG_FFRTMPCRYPT_PROTOCOL 0 #define CONFIG_FFRTMPHTTP_PROTOCOL 0 #define CONFIG_FILE_PROTOCOL 0 @@ -2120,6 +2141,6 @@ #define CONFIG_LIBSSH_PROTOCOL 0 #define CONFIG_LIBSMBCLIENT_PROTOCOL 0 #define CONFIG_LIBZMQ_PROTOCOL 0 -#define CONFIG_IPFS_PROTOCOL 0 -#define CONFIG_IPNS_PROTOCOL 0 +#define CONFIG_IPFS_GATEWAY_PROTOCOL 0 +#define CONFIG_IPNS_GATEWAY_PROTOCOL 0 #endif /* FFMPEG_CONFIG_COMPONENTS_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/libavutil/ffversion.h b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/libavutil/ffversion.h index b9e3a544..52669657 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/libavutil/ffversion.h +++ b/arm/raspi/third_party/ffmpeg/chromium/config/Chromium/win/x64/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-110326-g0bb5dd59ec" +#define FFMPEG_VERSION "N-110926-gd5ac4d1dc0" #endif /* AVUTIL_FFVERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/chromium/patches/README b/arm/raspi/third_party/ffmpeg/chromium/patches/README index 6bedda92..ae648c7b 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/patches/README +++ b/arm/raspi/third_party/ffmpeg/chromium/patches/README @@ -913,19 +913,22 @@ Affects: libavcodec/ac3_parser.c ------------------------------------------------------------------ -commit 6a1468ead6b2b0c611f16ed6c7609eaa30e13d74 -Author: Thomas Guilbert -Date: Tue Nov 29 14:10:29 2022 -0800 +commit c9b87a3225e1422d281ce4454415e5c96b452aa7 +Merge: a249b21db6 2c3107c3e9 +Author: John Rummell +Date: Wed Jan 25 16:02:14 2023 -0800 - Remove tx_double.c and tx_int32.c - - Ffmpeg is in the process of moving their FFT implementation to - libavutil/tx.h. This causes a jump in binary size, from including - precomputed tables. - - For now, chromium doesn't use the INT32 and DOUBLE variations. - This commit removes the references which force the linker to - include them. + Merge remote-tracking branch 'upstream/master' into sushi-2023-01-25-15-58-26 + +Affects: + libavutil/tx.c + +------------------------------------------------------------------ +commit cbc47d6b462ccd4f431dacad782ac14faba67ab0 +Author: John Rummell +Date: Wed Jan 25 16:20:19 2023 -0800 + + Update python scripts Affects: libavutil/tx.c diff --git a/arm/raspi/third_party/ffmpeg/chromium/patches/config_flag_changes.txt b/arm/raspi/third_party/ffmpeg/chromium/patches/config_flag_changes.txt index fe960a7a..b78fb09d 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/patches/config_flag_changes.txt +++ b/arm/raspi/third_party/ffmpeg/chromium/patches/config_flag_changes.txt @@ -1,20 +1,15 @@ -+ CONFIG_AMRNB_DECODER 0 -+ CONFIG_AMRWB_DECODER 0 -+ CONFIG_AMR_DEMUXER 0 -+ CONFIG_AV1_NVENC_ENCODER 0 -+ CONFIG_BACKGROUNDKEY_FILTER 0 -+ CONFIG_GSM_MS_DECODER 0 -+ CONFIG_GSM_PARSER 0 -+ CONFIG_H264_MEDIACODEC_ENCODER 0 -+ CONFIG_HEVC_MEDIACODEC_ENCODER 0 -+ CONFIG_LSP 0 -+ CONFIG_MDCT 0 -- CONFIG_AMRNB_DECODER 1 -- CONFIG_AMRWB_DECODER 1 -- CONFIG_AMR_DEMUXER 1 -- CONFIG_GSM_MS_DECODER 1 -- CONFIG_GSM_PARSER 1 -- CONFIG_LSP 1 -- CONFIG_MDCT 1 -- CONFIG_MDCT15 0 -- CONFIG_MDCT15 1 ++ CONFIG_ADPCM_XMD_DECODER 0 ++ CONFIG_ANULL_DECODER 0 ++ CONFIG_ANULL_ENCODER 0 ++ CONFIG_AV1_AMF_ENCODER 0 ++ CONFIG_CBD2_DPCM_DECODER 0 ++ CONFIG_HSTACK_VAAPI_FILTER 0 ++ CONFIG_MEDIA100_TO_MJPEGB_BSF 0 ++ CONFIG_SSIM360_FILTER 0 ++ CONFIG_VNULL_DECODER 0 ++ CONFIG_VNULL_ENCODER 0 ++ CONFIG_VSTACK_VAAPI_FILTER 0 ++ CONFIG_XMD_DEMUXER 0 ++ CONFIG_XSTACK_VAAPI_FILTER 0 ++ HAVE_VALGRIND_VALGRIND_H 0 ; HAVE_VALGRIND_VALGRIND_H 0 -- forced to 0. See https://crbug.com/590440 +- HAVE_VALGRIND_VALGRIND_H 0 ; HAVE_VALGRIND_VALGRIND_H 1 -- forced to 0. See https://crbug.com/590440 diff --git a/arm/raspi/third_party/ffmpeg/chromium/scripts/build_ffmpeg.py b/arm/raspi/third_party/ffmpeg/chromium/scripts/build_ffmpeg.py index 87f8e25f..ea982043 100755 --- a/arm/raspi/third_party/ffmpeg/chromium/scripts/build_ffmpeg.py +++ b/arm/raspi/third_party/ffmpeg/chromium/scripts/build_ffmpeg.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # # Copyright 2023 The Chromium Authors, Alex313031, and Midzer. All rights reserved. # Use of this source code is governed by a BSD-style license that can be @@ -339,7 +339,7 @@ def SetupWindowsCrossCompileToolchain(target_arch): # Use those paths with a second script which will tell us the proper lib paths # to specify for ldflags. output = subprocess.check_output([ - 'python', + 'python3', os.path.join(CHROMIUM_ROOT_DIR, 'build', 'toolchain', 'win', 'setup_toolchain.py'), win_dirs['vs_path'], win_dirs['sdk_path'], win_dirs['runtime_dirs'], 'win', target_arch, 'none' @@ -746,9 +746,6 @@ def ConfigureAndBuild(target_arch, target_os, host_os, host_arch, parallel_jobs, configure_flags['Common'].extend([ '--enable-lto', '--extra-cflags=-O3', - '--extra-cflags=-mavx', - '--extra-cflags=-maes', - '--extra-cflags=-mpclmul', '--arch=x86_64', '--target-os=linux', ]) @@ -1008,8 +1005,8 @@ def ConfigureAndBuild(target_arch, target_os, host_os, host_arch, parallel_jobs, # Google Chrome & ChromeOS specific configuration. configure_flags['Chrome'].extend([ - '--enable-decoder=aac,h264,hevc', - '--enable-demuxer=aac', + '--enable-decoder=aac,h264,mp3,hevc', + '--enable-demuxer=aac,mp3', '--enable-parser=aac,h264,hevc', ]) diff --git a/arm/raspi/third_party/ffmpeg/chromium/scripts/copy_config.sh b/arm/raspi/third_party/ffmpeg/chromium/scripts/copy_config.sh index 4db59d20..a18048cf 100755 --- a/arm/raspi/third_party/ffmpeg/chromium/scripts/copy_config.sh +++ b/arm/raspi/third_party/ffmpeg/chromium/scripts/copy_config.sh @@ -20,6 +20,16 @@ for os in android linux linux-noasm mac win; do [ -e $FROM ] && cp -v $FROM $TO done done + # Since we cannot cross-compile for ios, we just duplicate the mac config + # for this platform. + if [ "$os" = "mac" ]; then + FROM="chromium/config/$target/$os/" + if [ -d $FROM ]; then + TO="chromium/config/$target/ios/" + if [ ! -d $TO ]; then mkdir -p $TO; fi + cp -v -r $FROM/* $TO + fi + fi done done diff --git a/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn.py b/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn.py index a3867949..d36b0a22 100755 --- a/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn.py +++ b/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn.py @@ -336,6 +336,8 @@ class SourceSet(object): platform_condition = None elif condition.PLATFORM == 'linux': platform_condition = 'use_linux_config' + elif condition.PLATFORM == 'mac': + platform_condition = 'is_apple' else: platform_condition = 'is_%s' % condition.PLATFORM diff --git a/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn_unittest.py b/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn_unittest.py index 113cbe4e..77245a24 100755 --- a/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn_unittest.py +++ b/arm/raspi/third_party/ffmpeg/chromium/scripts/generate_gn_unittest.py @@ -193,6 +193,12 @@ class SourceSetUnittest(unittest.TestCase): e_stanza.index(('use_linux_config && current_cpu == "x64"' ' && ffmpeg_branding == "Chromium"')) + # mac should imply is_apple. + f = SourceSet( + set(['a']), set([SourceListCondition('arm64', 'Chromium', 'mac')])) + f_stanza = f.GenerateGnStanza() + f_stanza.index('is_apple') + def testComplexSourceListConditions(self): # Create 2 sets with intersecting source 'a', but setup such that 'a' # is only valid for combinations (x86 && windows) || (x64 && linux). The diff --git a/arm/raspi/third_party/ffmpeg/chromium/scripts/robo_lib/config.py b/arm/raspi/third_party/ffmpeg/chromium/scripts/robo_lib/config.py index e00c5933..f3121085 100644 --- a/arm/raspi/third_party/ffmpeg/chromium/scripts/robo_lib/config.py +++ b/arm/raspi/third_party/ffmpeg/chromium/scripts/robo_lib/config.py @@ -46,6 +46,7 @@ class RoboConfiguration: "llvm-build", "Release+Asserts", "bin") self.EnsurePathContainsLLVM() + self.EnsureNoMakeInfo() shell.log("Using chrome src: %s" % self.chrome_src()) self.EnsureFFmpegHome() shell.log("Using ffmpeg home: %s" % self.ffmpeg_home()) @@ -182,8 +183,16 @@ class RoboConfiguration: "llvm-build", "Release+Asserts", "bin") if self.llvm_path() not in os.environ["PATH"]: raise errors.UserInstructions( - "Please add:\n%s\nto the beginning of $PATH" % - self.llvm_path()) + "Please add:\n%s\nto the beginning of $PATH\nExample: export PATH=%s:$PATH" % + (self.llvm_path(), self.llvm_path())) + + def EnsureNoMakeInfo(self): + """Ensure that makeinfo is not available.""" + if os.system("makeinfo --version > /dev/null 2>&1") == 0: + raise errors.UserInstructions( + "makeinfo is available and we don't need it, so please remove it\nExample: sudo apt-get remove texinfo" + ) + def llvm_path(self): return self._llvm_path diff --git a/arm/raspi/third_party/ffmpeg/ffmpeg_generated.gni b/arm/raspi/third_party/ffmpeg/ffmpeg_generated.gni index 0cba1634..52b9e696 100644 --- a/arm/raspi/third_party/ffmpeg/ffmpeg_generated.gni +++ b/arm/raspi/third_party/ffmpeg/ffmpeg_generated.gni @@ -1,4 +1,4 @@ -# Copyright 2022 The Chromium Authors. All rights reserved. +# Copyright 2023 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -14,7 +14,7 @@ ffmpeg_asm_sources = [] use_linux_config = is_linux || is_chromeos || is_fuchsia -if ((is_android && current_cpu == "arm" && arm_use_neon) || (is_android && current_cpu == "arm64") || (is_android && current_cpu == "x64") || (is_android && current_cpu == "x86") || (is_mac) || (is_win) || (use_linux_config)) { +if ((is_android && current_cpu == "arm" && arm_use_neon) || (is_android && current_cpu == "arm64") || (is_android && current_cpu == "x64") || (is_android && current_cpu == "x86") || (is_apple) || (is_win) || (use_linux_config)) { ffmpeg_c_sources += [ "libavcodec/ac3_channel_layout_tab.c", "libavcodec/ac3_parser.c", @@ -142,6 +142,7 @@ if ((is_android && current_cpu == "arm" && arm_use_neon) || (is_android && curre "libavformat/wavdec.c", "libavutil/aes.c", "libavutil/aes_ctr.c", + "libavutil/ambient_viewing_environment.c", "libavutil/autorename_libavutil_cpu.c", "libavutil/autorename_libavutil_fixed_dsp.c", "libavutil/autorename_libavutil_float_dsp.c", @@ -241,7 +242,7 @@ if (use_linux_config && ffmpeg_branding == "ChromeOS") { ] } -if ((is_mac && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "ChromeOS")) { +if ((is_apple && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "ChromeOS")) { ffmpeg_c_sources += [ "libavcodec/autorename_libavcodec_bswapdsp.c", @@ -266,6 +267,9 @@ if ((is_mac && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Ch "libavcodec/atsc_a53.c", "libavcodec/cabac.c", "libavcodec/h2645_parse.c", + "libavcodec/h2645_sei.c", + "libavcodec/h2645_vui.c", + "libavcodec/h2645data.c", "libavcodec/h264_cabac.c", "libavcodec/h264_cavlc.c", "libavcodec/h264_direct.c", @@ -289,7 +293,7 @@ if ((is_mac && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Ch ] } -if ((current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_android && current_cpu == "arm" && arm_use_neon && ffmpeg_branding == "Chrome") || (is_android && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (is_mac && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "ChromeOS")) { +if ((current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_android && current_cpu == "arm" && arm_use_neon && ffmpeg_branding == "Chrome") || (is_android && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (is_apple && ffmpeg_branding == "Chrome") || (is_win && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "Chrome") || (use_linux_config && ffmpeg_branding == "ChromeOS")) { ffmpeg_c_sources += [ "libavcodec/aac_ac3_parser.c", "libavcodec/aac_parser.c", @@ -310,30 +314,7 @@ if ((current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (current_cpu == " ] } -if ((use_linux_config && current_cpu == "x64" && ffmpeg_branding == "ChromeOS") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "ChromeOS")) { - ffmpeg_c_sources += [ - "libavcodec/x86/autorename_libavcodec_x86_mpegvideo.c", - "libavcodec/x86/blockdsp_init.c", - "libavcodec/x86/h263dsp_init.c", - "libavcodec/x86/idctdsp_init.c", - "libavcodec/x86/me_cmp_init.c", - "libavcodec/x86/mpeg4videodsp.c", - "libavcodec/x86/qpeldsp_init.c", - "libavcodec/x86/xvididct_init.c", - ] - ffmpeg_asm_sources += [ - "libavcodec/x86/blockdsp.asm", - "libavcodec/x86/h263_loopfilter.asm", - "libavcodec/x86/idctdsp.asm", - "libavcodec/x86/me_cmp.asm", - "libavcodec/x86/qpeldsp.asm", - "libavcodec/x86/simple_idct.asm", - "libavcodec/x86/simple_idct10.asm", - "libavcodec/x86/xvididct.asm", - ] -} - -if ((is_mac && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { +if ((is_apple && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { ffmpeg_c_sources += [ "libavcodec/x86/autorename_libavcodec_x86_videodsp_init.c", "libavcodec/x86/h264_intrapred_init.c", @@ -377,7 +358,7 @@ if ((use_linux_config && current_cpu == "arm" && arm_use_neon && ffmpeg_branding ] } -if ((is_mac && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x64" && ffmpeg_branding == "ChromeOS") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "ChromeOS")) { +if ((is_apple && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x64" && ffmpeg_branding == "ChromeOS") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "ChromeOS")) { ffmpeg_c_sources += [ "libavcodec/x86/bswapdsp_init.c", @@ -414,6 +395,27 @@ if ((is_mac && current_cpu == "x64" && ffmpeg_branding == "Chrome") || (is_win & ] } +if ((use_linux_config && current_cpu == "x64" && ffmpeg_branding == "ChromeOS") || (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "ChromeOS")) { + ffmpeg_c_sources += [ + "libavcodec/x86/autorename_libavcodec_x86_mpegvideo.c", + "libavcodec/x86/blockdsp_init.c", + "libavcodec/x86/h263dsp_init.c", + "libavcodec/x86/idctdsp_init.c", + "libavcodec/x86/me_cmp_init.c", + "libavcodec/x86/mpeg4videodsp.c", + "libavcodec/x86/qpeldsp_init.c", + "libavcodec/x86/xvididct_init.c", + ] + ffmpeg_asm_sources += [ + "libavcodec/x86/blockdsp.asm", + "libavcodec/x86/h263_loopfilter.asm", + "libavcodec/x86/idctdsp.asm", + "libavcodec/x86/me_cmp.asm", + "libavcodec/x86/qpeldsp.asm", + "libavcodec/x86/xvididct.asm", + ] +} + if ((use_linux_config && current_cpu == "arm" && arm_use_neon) || (use_linux_config && current_cpu == "arm")) { ffmpeg_c_sources += [ "libavcodec/arm/h264pred_init_arm.c", @@ -434,7 +436,7 @@ if ((use_linux_config && current_cpu == "arm" && arm_use_neon) || (use_linux_con ] } -if ((is_android && current_cpu == "x64") || (is_mac && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { +if ((is_android && current_cpu == "x64") || (is_apple && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { ffmpeg_c_sources += [ "libavutil/x86/autorename_libavutil_x86_tx_float_init.c", ] @@ -472,7 +474,7 @@ if ((is_android && current_cpu == "arm" && arm_use_neon) || (use_linux_config && ] } -if ((is_android && current_cpu == "x64") || (is_android && current_cpu == "x86") || (is_mac && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { +if ((is_android && current_cpu == "x64") || (is_android && current_cpu == "x86") || (is_apple && current_cpu == "x64") || (is_win && current_cpu == "x64") || (is_win && current_cpu == "x86") || (use_linux_config && current_cpu == "x64") || (use_linux_config && current_cpu == "x86")) { ffmpeg_c_sources += [ "libavcodec/x86/autorename_libavcodec_x86_vorbisdsp_init.c", "libavcodec/x86/constants.c", @@ -488,7 +490,7 @@ if ((is_android && current_cpu == "x64") || (is_android && current_cpu == "x86") ] } -if ((is_android && current_cpu == "arm64") || (is_mac && current_cpu == "arm64") || (is_win && current_cpu == "arm64") || (use_linux_config && current_cpu == "arm64")) { +if ((is_android && current_cpu == "arm64") || (is_apple && current_cpu == "arm64") || (is_win && current_cpu == "arm64") || (use_linux_config && current_cpu == "arm64")) { ffmpeg_c_sources += [ "libavcodec/aarch64/fft_init_aarch64.c", "libavcodec/aarch64/mpegaudiodsp_init.c", @@ -506,7 +508,7 @@ if ((is_android && current_cpu == "arm64") || (is_mac && current_cpu == "arm64") ] } -if ((is_mac) || (is_win) || (use_linux_config)) { +if ((is_apple) || (is_win) || (use_linux_config)) { ffmpeg_c_sources += [ "libavcodec/autorename_libavcodec_videodsp.c", "libavcodec/h264pred.c", @@ -522,7 +524,7 @@ if ((is_mac) || (is_win) || (use_linux_config)) { ] } -if ((is_mac && current_cpu == "arm64") || (is_win && current_cpu == "arm64") || (use_linux_config && current_cpu == "arm64")) { +if ((is_apple && current_cpu == "arm64") || (is_win && current_cpu == "arm64") || (use_linux_config && current_cpu == "arm64")) { ffmpeg_c_sources += [ "libavcodec/aarch64/h264pred_init.c", "libavcodec/aarch64/hpeldsp_init_aarch64.c", @@ -537,7 +539,7 @@ if ((is_mac && current_cpu == "arm64") || (is_win && current_cpu == "arm64") || ] } -if ((is_mac && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "arm64" && ffmpeg_branding == "ChromeOS")) { +if ((is_apple && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (is_win && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "arm64" && ffmpeg_branding == "Chrome") || (use_linux_config && current_cpu == "arm64" && ffmpeg_branding == "ChromeOS")) { ffmpeg_c_sources += [ "libavcodec/aarch64/hevcdsp_init_aarch64.c" @@ -700,3 +702,15 @@ if ((use_linux_config && current_cpu == "arm" && arm_use_neon && ffmpeg_branding ] } +if (use_linux_config && current_cpu == "x86" && ffmpeg_branding == "ChromeOS") { + ffmpeg_asm_sources += [ + "libavcodec/x86/simple_idct.asm", + ] +} + +if (use_linux_config && current_cpu == "x64" && ffmpeg_branding == "ChromeOS") { + ffmpeg_asm_sources += [ + "libavcodec/x86/simple_idct10.asm", + ] +} + diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/012v.c b/arm/raspi/third_party/ffmpeg/libavcodec/012v.c index 2d89a86b..f0197cd8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/012v.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/012v.c @@ -131,8 +131,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic, u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]); v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]); memcpy(y, y_temp, sizeof(*y) * (width - x)); - memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2); - memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2); + memcpy(u, u_temp, sizeof(*u) * ((width - x + 1) / 2)); + memcpy(v, v_temp, sizeof(*v) * ((width - x + 1) / 2)); } line_end += stride; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/Makefile b/arm/raspi/third_party/ffmpeg/libavcodec/Makefile index 0bc7943d..1fb963f8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/Makefile +++ b/arm/raspi/third_party/ffmpeg/libavcodec/Makefile @@ -96,10 +96,14 @@ OBJS-$(CONFIG_GOLOMB) += golomb.o OBJS-$(CONFIG_H263DSP) += h263dsp.o OBJS-$(CONFIG_H264CHROMA) += h264chroma.o OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o -OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o +OBJS-$(CONFIG_H264PARSE) += h264_parse.o h264_ps.o h2645data.o \ + h2645_parse.o h2645_vui.o OBJS-$(CONFIG_H264PRED) += h264pred.o OBJS-$(CONFIG_H264QPEL) += h264qpel.o -OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o \ +OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o +OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \ + h2645data.o h2645_parse.o h2645_vui.o +OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \ dynamic_hdr10_plus.o dynamic_hdr_vivid.o OBJS-$(CONFIG_HPELDSP) += hpeldsp.o OBJS-$(CONFIG_HUFFMAN) += huffman.o @@ -159,6 +163,7 @@ OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o OBJS-$(CONFIG_TPELDSP) += tpeldsp.o OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o +OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o OBJS-$(CONFIG_VC1DSP) += vc1dsp.o OBJS-$(CONFIG_VIDEODSP) += videodsp.o OBJS-$(CONFIG_VP3DSP) += vp3dsp.o @@ -214,6 +219,8 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \ acelp_pitch_delay.o OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o OBJS-$(CONFIG_ANM_DECODER) += anm.o +OBJS-$(CONFIG_ANULL_DECODER) += null.o +OBJS-$(CONFIG_ANULL_ENCODER) += null.o OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o OBJS-$(CONFIG_APAC_DECODER) += apac.o OBJS-$(CONFIG_APE_DECODER) += apedec.o @@ -245,6 +252,7 @@ OBJS-$(CONFIG_AURA_DECODER) += cyuv.o OBJS-$(CONFIG_AURA2_DECODER) += aura.o OBJS-$(CONFIG_AV1_DECODER) += av1dec.o OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o @@ -272,6 +280,7 @@ OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o OBJS-$(CONFIG_C93_DECODER) += c93.o OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \ cavsdata.o +OBJS-$(CONFIG_CBD2_DECODER) += dpcm.o OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o ass.o OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o @@ -391,7 +400,7 @@ OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ h264_direct.o h264_loopfilter.o \ h264_mb.o h264_picture.o \ - h264_refs.o h264_sei.o \ + h264_refs.o \ h264_slice.o h264data.o h274.o OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o @@ -404,7 +413,8 @@ OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o -OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o +OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o \ + h2645data.o OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o @@ -428,7 +438,8 @@ OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o -OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o +OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \ + h2645data.o OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o @@ -474,7 +485,7 @@ OBJS-$(CONFIG_MACE6_DECODER) += mace.o OBJS-$(CONFIG_MAGICYUV_DECODER) += magicyuv.o OBJS-$(CONFIG_MAGICYUV_ENCODER) += magicyuvenc.o OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o -OBJS-$(CONFIG_MEDIA100_DECODER) += media100.o +OBJS-$(CONFIG_MEDIA100_DECODER) += mjpegbdec.o OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o twinvq.o OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o @@ -738,6 +749,8 @@ OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o +OBJS-$(CONFIG_VNULL_DECODER) += null.o +OBJS-$(CONFIG_VNULL_ENCODER) += null.o OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \ vorbis_data.o OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \ @@ -767,6 +780,7 @@ OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_VQC_DECODER) += vqcdec.o +OBJS-$(CONFIG_WADY_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o OBJS-$(CONFIG_WBMP_DECODER) += wbmpdec.o @@ -949,6 +963,7 @@ OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_THP_LE_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_VIMA_DECODER) += vima.o adpcm_data.o OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_XMD_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_ZORK_DECODER) += adpcm.o adpcm_data.o @@ -1148,7 +1163,7 @@ OBJS-$(CONFIG_GIF_PARSER) += gif_parser.o OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o OBJS-$(CONFIG_H261_PARSER) += h261_parser.o OBJS-$(CONFIG_H263_PARSER) += h263_parser.o -OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o +OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264data.o OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o OBJS-$(CONFIG_HDR_PARSER) += hdr_parser.o OBJS-$(CONFIG_IPU_PARSER) += ipu_parser.o @@ -1196,13 +1211,16 @@ OBJS-$(CONFIG_EAC3_CORE_BSF) += eac3_core_bsf.o OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \ av1_parse.o h2645_parse.o OBJS-$(CONFIG_FILTER_UNITS_BSF) += filter_units_bsf.o -OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o +OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o \ + h2645data.o OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += h264_redundant_pps_bsf.o OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += hapqa_extract_bsf.o hap.o -OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o +OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o \ + h2645data.o OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o +OBJS-$(CONFIG_MEDIA100_TO_MJPEGB_BSF) += media100_to_mjpegb_bsf.o OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF) += mpeg4_unpack_bframes_bsf.o @@ -1243,6 +1261,7 @@ SKIPHEADERS += %_tablegen.h \ aaccoder_trellis.h \ aacenc_quantization.h \ aacenc_quantization_misc.h \ + bitstream_template.h \ $(ARCH)/vpx_arith.h \ SKIPHEADERS-$(CONFIG_AMF) += amfenc.h @@ -1269,6 +1288,8 @@ SKIPHEADERS-$(CONFIG_ZLIB) += zlib_wrapper.h TESTPROGS = avcodec \ avpacket \ + bitstream_be \ + bitstream_le \ celp_math \ codec_desc \ htmlsubtitles \ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ac3.h b/arm/raspi/third_party/ffmpeg/libavcodec/ac3.h index 24304caa..2386c15a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ac3.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ac3.h @@ -53,6 +53,7 @@ #define AC3_DYNAMIC_RANGE1 0 typedef int INTFLOAT; +typedef unsigned int UINTFLOAT; typedef int16_t SHORTFLOAT; #else /* USE_FIXED */ @@ -73,6 +74,7 @@ typedef int16_t SHORTFLOAT; #define AC3_DYNAMIC_RANGE1 1.0f typedef float INTFLOAT; +typedef float UINTFLOAT; typedef float SHORTFLOAT; #endif /* USE_FIXED */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ac3dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/ac3dec.c index 1f2949dc..0b120e61 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ac3dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ac3dec.c @@ -1716,6 +1716,11 @@ skip: avctx->bit_rate = s->bit_rate + s->prev_bit_rate; } + if (!avctx->sample_rate) { + av_log(avctx, AV_LOG_ERROR, "Could not determine the sample rate\n"); + return AVERROR_INVALIDDATA; + } + for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) extended_channel_map[ch] = ch; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_fixed.c b/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_fixed.c index 5a5f1cc2..88dfd66b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_fixed.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_fixed.c @@ -112,7 +112,7 @@ const FFCodec ff_ac3_fixed_encoder = { CODEC_LONG_NAME("ATSC A/52A (AC-3)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_AC3, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AC3EncodeContext), .init = ac3_fixed_encode_init, FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_float.c b/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_float.c index 4c4d18ce..ae351a53 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_float.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ac3enc_float.c @@ -116,7 +116,7 @@ const FFCodec ff_ac3_encoder = { CODEC_LONG_NAME("ATSC A/52A (AC-3)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_AC3, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AC3EncodeContext), .init = ff_ac3_float_encode_init, FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/adpcm.c b/arm/raspi/third_party/ffmpeg/libavcodec/adpcm.c index 841538b1..45169693 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/adpcm.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/adpcm.c @@ -324,6 +324,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_IMA_WAV: case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_XA: + case AV_CODEC_ID_ADPCM_XMD: case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_EA_R3: @@ -1043,6 +1044,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_XA: nb_samples = (buf_size / 128) * 224 / ch; break; + case AV_CODEC_ID_ADPCM_XMD: + nb_samples = buf_size / (21 * ch) * 32; + break; case AV_CODEC_ID_ADPCM_DTK: case AV_CODEC_ID_ADPCM_PSX: nb_samples = buf_size / (16 * ch) * 28; @@ -1553,6 +1557,45 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, } bytestream2_seek(&gb, 0, SEEK_END); ) /* End of CASE */ + CASE(ADPCM_XMD, + int bytes_remaining, block = 0; + while (bytestream2_get_bytes_left(&gb) >= 21 * channels) { + for (int channel = 0; channel < channels; channel++) { + int16_t *out = samples_p[channel] + block * 32; + int16_t history[2]; + uint16_t scale; + + history[1] = sign_extend(bytestream2_get_le16(&gb), 16); + history[0] = sign_extend(bytestream2_get_le16(&gb), 16); + scale = bytestream2_get_le16(&gb); + + out[0] = history[1]; + out[1] = history[0]; + + for (int n = 0; n < 15; n++) { + unsigned byte = bytestream2_get_byte(&gb); + int32_t nibble[2]; + + nibble[0] = sign_extend(byte & 15, 4); + nibble[1] = sign_extend(byte >> 4, 4); + + out[2+n*2] = (nibble[0]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14; + history[1] = history[0]; + history[0] = out[2+n*2]; + + out[2+n*2+1] = (nibble[1]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14; + history[1] = history[0]; + history[0] = out[2+n*2+1]; + } + } + + block++; + } + bytes_remaining = bytestream2_get_bytes_left(&gb); + if (bytes_remaining > 0) { + bytestream2_skip(&gb, bytes_remaining); + } + ) /* End of CASE */ CASE(ADPCM_XA, int16_t *out0 = samples_p[0]; int16_t *out1 = samples_p[1]; @@ -2350,5 +2393,6 @@ ADPCM_DECODER(ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Sho ADPCM_DECODER(ADPCM_THP_LE, sample_fmts_s16p, adpcm_thp_le, "ADPCM Nintendo THP (little-endian)") ADPCM_DECODER(ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo THP") ADPCM_DECODER(ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA") +ADPCM_DECODER(ADPCM_XMD, sample_fmts_s16p, adpcm_xmd, "ADPCM Konami XMD") ADPCM_DECODER(ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha") ADPCM_DECODER(ADPCM_ZORK, sample_fmts_s16, adpcm_zork, "ADPCM Zork") diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/adpcmenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/adpcmenc.c index 57709b19..63afffc5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/adpcmenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/adpcmenc.c @@ -1003,7 +1003,8 @@ const FFCodec ff_ ## name_ ## _encoder = { \ .p.id = id_, \ .p.sample_fmts = sample_fmts_, \ .p.ch_layouts = ch_layouts, \ - .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1, \ + .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1 | \ + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, \ .p.priv_class = &adpcm_encoder_class, \ .priv_data_size = sizeof(ADPCMEncodeContext), \ .init = adpcm_encode_init, \ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/adxenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/adxenc.c index 153c91b8..796efdab 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/adxenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/adxenc.c @@ -183,8 +183,6 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, dst += BLOCK_SIZE; } - avpkt->pts = frame->pts; - avpkt->duration = frame->nb_samples; *got_packet_ptr = 1; return 0; } @@ -194,10 +192,12 @@ const FFCodec ff_adpcm_adx_encoder = { CODEC_LONG_NAME("SEGA CRI ADX ADPCM"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ADPCM_ADX, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(ADXContext), .init = adx_encode_init, FF_CODEC_ENCODE_CB(adx_encode_frame), .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/alacenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/alacenc.c index 0f685d71..9598e586 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/alacenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/alacenc.c @@ -653,7 +653,8 @@ const FFCodec ff_alac_encoder = { CODEC_LONG_NAME("ALAC (Apple Lossless Audio Codec)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ALAC, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AlacEncodeContext), .p.priv_class = &alacenc_class, .init = alac_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/aliaspixenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/aliaspixenc.c index 6593d3f0..90d2a633 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/aliaspixenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/aliaspixenc.c @@ -106,7 +106,7 @@ const FFCodec ff_alias_pix_encoder = { CODEC_LONG_NAME("Alias/Wavefront PIX image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ALIAS_PIX, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/allcodecs.c b/arm/raspi/third_party/ffmpeg/libavcodec/allcodecs.c index d5a6c427..ff82423a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/allcodecs.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/allcodecs.c @@ -620,6 +620,7 @@ extern const FFCodec ff_pcm_vidc_encoder; extern const FFCodec ff_pcm_vidc_decoder; /* DPCM codecs */ +extern const FFCodec ff_cbd2_dpcm_decoder; extern const FFCodec ff_derf_dpcm_decoder; extern const FFCodec ff_gremlin_dpcm_decoder; extern const FFCodec ff_interplay_dpcm_decoder; @@ -628,6 +629,7 @@ extern const FFCodec ff_roq_dpcm_decoder; extern const FFCodec ff_sdx2_dpcm_decoder; extern const FFCodec ff_sol_dpcm_decoder; extern const FFCodec ff_xan_dpcm_decoder; +extern const FFCodec ff_wady_dpcm_decoder; /* ADPCM codecs */ extern const FFCodec ff_adpcm_4xm_decoder; @@ -693,6 +695,7 @@ extern const FFCodec ff_adpcm_thp_decoder; extern const FFCodec ff_adpcm_thp_le_decoder; extern const FFCodec ff_adpcm_vima_decoder; extern const FFCodec ff_adpcm_xa_decoder; +extern const FFCodec ff_adpcm_xmd_decoder; extern const FFCodec ff_adpcm_yamaha_encoder; extern const FFCodec ff_adpcm_yamaha_decoder; extern const FFCodec ff_adpcm_zork_decoder; @@ -828,9 +831,11 @@ extern const FFCodec ff_libaom_av1_decoder; /* hwaccel hooks only, so prefer external decoders */ extern const FFCodec ff_av1_decoder; extern const FFCodec ff_av1_cuvid_decoder; +extern const FFCodec ff_av1_mediacodec_decoder; extern const FFCodec ff_av1_nvenc_encoder; extern const FFCodec ff_av1_qsv_decoder; extern const FFCodec ff_av1_qsv_encoder; +extern const FFCodec ff_av1_amf_encoder; extern const FFCodec ff_libopenh264_encoder; extern const FFCodec ff_libopenh264_decoder; extern const FFCodec ff_h264_amf_encoder; @@ -879,6 +884,12 @@ extern const FFCodec ff_vp9_qsv_decoder; extern const FFCodec ff_vp9_vaapi_encoder; extern const FFCodec ff_vp9_qsv_encoder; +// null codecs +extern const FFCodec ff_vnull_decoder; +extern const FFCodec ff_vnull_encoder; +extern const FFCodec ff_anull_decoder; +extern const FFCodec ff_anull_encoder; + // The iterate API is not usable with ossfuzz due to the excessive size of binaries created #if CONFIG_OSSFUZZ const FFCodec * codec_list[] = { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.c index a033e122..c487fc48 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.c @@ -349,6 +349,9 @@ static int amf_init_encoder(AVCodecContext *avctx) case AV_CODEC_ID_HEVC: codec_id = AMFVideoEncoder_HEVC; break; + case AV_CODEC_ID_AV1 : + codec_id = AMFVideoEncoder_AV1; + break; default: break; } @@ -460,6 +463,11 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff pkt->flags = AV_PKT_FLAG_KEY; } break; + case AV_CODEC_ID_AV1: + buffer->pVtbl->GetProperty(buffer, AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE, &var); + if (var.int64Value == AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_KEY) { + pkt->flags = AV_PKT_FLAG_KEY; + } default: break; } @@ -681,6 +689,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) case AV_CODEC_ID_HEVC: AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!ctx->aud); break; + //case AV_CODEC_ID_AV1 not supported default: break; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.h b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.h index 1ab98d2f..66e06807 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc.h @@ -23,6 +23,7 @@ #include #include +#include #include "libavutil/fifo.h" @@ -116,6 +117,11 @@ typedef struct AmfContext { int min_qp_p; int max_qp_p; int tier; + + // AV1 - specific options + + enum AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM align; + } AmfContext; extern const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[]; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/amfenc_av1.c b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc_av1.c new file mode 100644 index 00000000..8093cb73 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/amfenc_av1.c @@ -0,0 +1,361 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "amfenc.h" +#include "codec_internal.h" +#include "internal.h" + +#define OFFSET(x) offsetof(AmfContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, "usage" }, + { "transcoding", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, "usage" }, + { "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" }, + + { "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{.i64 = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, "profile" }, + { "main", "", 0, AV_OPT_TYPE_CONST,{.i64 = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, "profile" }, + + { "level", "Set the encoding level (default auto)", OFFSET(level), AV_OPT_TYPE_INT,{.i64 = 0 }, 0, AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, "level" }, + { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, VE, "level" }, + { "2.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_0 }, 0, 0, VE, "level" }, + { "2.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_1 }, 0, 0, VE, "level" }, + { "2.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_2 }, 0, 0, VE, "level" }, + { "2.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_2_3 }, 0, 0, VE, "level" }, + { "3.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_0 }, 0, 0, VE, "level" }, + { "3.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_1 }, 0, 0, VE, "level" }, + { "3.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_2 }, 0, 0, VE, "level" }, + { "3.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_3_3 }, 0, 0, VE, "level" }, + { "4.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_0 }, 0, 0, VE, "level" }, + { "4.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_1 }, 0, 0, VE, "level" }, + { "4.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_2 }, 0, 0, VE, "level" }, + { "4.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_4_3 }, 0, 0, VE, "level" }, + { "5.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_0 }, 0, 0, VE, "level" }, + { "5.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_1 }, 0, 0, VE, "level" }, + { "5.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_2 }, 0, 0, VE, "level" }, + { "5.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_5_3 }, 0, 0, VE, "level" }, + { "6.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_0 }, 0, 0, VE, "level" }, + { "6.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_1 }, 0, 0, VE, "level" }, + { "6.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_2 }, 0, 0, VE, "level" }, + { "6.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_6_3 }, 0, 0, VE, "level" }, + { "7.0", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_0 }, 0, 0, VE, "level" }, + { "7.1", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_1 }, 0, 0, VE, "level" }, + { "7.2", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_2 }, 0, 0, VE, "level" }, + { "7.3", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_LEVEL_7_3 }, 0, 0, VE, "level" }, + + { "quality", "Set the encoding quality", OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, "quality" }, + { "balanced", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_BALANCED }, 0, 0, VE, "quality" }, + { "speed", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, 0, 0, VE, "quality" }, + { "quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY }, 0, 0, VE, "quality" }, + { "high_quality", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY }, 0, 0, VE, "quality" }, + + { "rc", "Set the rate control mode", OFFSET(rate_control_mode), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN }, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR, VE, "rc" }, + { "cqp", "Constant Quantization Parameter", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP }, 0, 0, VE, "rc" }, + { "vbr_latency", "Latency Constrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0, 0, VE, "rc" }, + { "vbr_peak", "Peak Contrained Variable Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR }, 0, 0, VE, "rc" }, + { "cbr", "Constant Bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR }, 0, 0, VE, "rc" }, + + { "header_insertion_mode", "Set header insertion mode", OFFSET(header_insertion_mode), AV_OPT_TYPE_INT,{.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE }, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED, VE, "hdrmode" }, + { "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_NONE }, 0, 0, VE, "hdrmode" }, + { "gop", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, "hdrmode" }, + { "frame", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED }, 0, 0, VE, "hdrmode" }, + + { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE}, + { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE}, + { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE}, + + // min_qp_i -> min_qp_intra, min_qp_p -> min_qp_inter + { "min_qp_i", "min quantization parameter for I-frame", OFFSET(min_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "max_qp_i", "max quantization parameter for I-frame", OFFSET(max_qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "min_qp_p", "min quantization parameter for P-frame", OFFSET(min_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "max_qp_p", "max quantization parameter for P-frame", OFFSET(max_qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "qp_p", "quantization parameter for P-frame", OFFSET(qp_p), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "qp_i", "quantization parameter for I-frame", OFFSET(qp_i), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 255, VE }, + { "skip_frame", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE }, + + { "align", "alignment mode", OFFSET(align), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS, VE, "align" }, + { "64x16", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY }, 0, 0, VE, "align" }, + { "1080p", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082 }, 0, 0, VE, "align" }, + { "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, 0, 0, VE, "align" }, + + { NULL } + +}; + +static av_cold int amf_encode_init_av1(AVCodecContext* avctx) +{ + int ret = 0; + AMF_RESULT res = AMF_OK; + AmfContext* ctx = avctx->priv_data; + AMFVariantStruct var = { 0 }; + amf_int64 profile = 0; + amf_int64 profile_level = 0; + AMFBuffer* buffer; + AMFGuid guid; + AMFRate framerate; + AMFSize framesize = AMFConstructSize(avctx->width, avctx->height); + + + + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { + framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den); + } + else { + framerate = AMFConstructRate(avctx->time_base.den, avctx->time_base.num * avctx->ticks_per_frame); + } + + if ((ret = ff_amf_encode_init(avctx)) < 0) + return ret; + + // init static parameters + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_USAGE, ctx->usage); + + AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMESIZE, framesize); + + AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FRAMERATE, framerate); + + switch (avctx->profile) { + case FF_PROFILE_AV1_MAIN: + profile = AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN; + break; + default: + break; + } + if (profile == 0) { + profile = ctx->profile; + } + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PROFILE, profile); + + profile_level = avctx->level; + if (profile_level == FF_LEVEL_UNKNOWN) { + profile_level = ctx->level; + } + if (profile_level != 0) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_LEVEL, profile_level); + } + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET, ctx->quality); + + // Maximum Reference Frames + if (avctx->refs != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_NUM_REFRAMES, avctx->refs); + } + + // Picture control properties + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size); + + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE, ctx->header_insertion_mode); + + // Rate control + // autodetect rate control method + if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_UNKNOWN) { + if (ctx->min_qp_i != -1 || ctx->max_qp_i != -1 || + ctx->min_qp_p != -1 || ctx->max_qp_p != -1 || + ctx->qp_i != -1 || ctx->qp_p != -1) { + ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP; + av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CQP\n"); + } + else if (avctx->rc_max_rate > 0) { + ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; + av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n"); + } + else { + ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR; + av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n"); + } + } + + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD, ctx->rate_control_mode); + if (avctx->rc_buffer_size) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_VBV_BUFFER_SIZE, avctx->rc_buffer_size); + + if (avctx->rc_initial_buffer_occupancy != 0) { + int amf_buffer_fullness = avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size; + if (amf_buffer_fullness > 64) + amf_buffer_fullness = 64; + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness); + } + } + + // Pre-Pass, Pre-Analysis, Two-Pass + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE, ctx->preanalysis); + + // init dynamic rate control params + if (ctx->max_au_size) + ctx->enforce_hrd = 1; + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENFORCE_HRD, ctx->enforce_hrd); + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_FILLER_DATA, ctx->filler_data); + + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_TARGET_BITRATE, avctx->bit_rate); + + if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->bit_rate); + } + if (avctx->rc_max_rate) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->rc_max_rate); + } + else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) { + av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n"); + } + if (avctx->bit_rate > 0) { + ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR; + av_log(ctx, AV_LOG_DEBUG, "Rate control turned to CBR\n"); + } + + switch (ctx->align) + { + case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY: + if (avctx->width / 64 * 64 != avctx->width || avctx->height / 16 * 16 != avctx->height) + { + res = AMF_NOT_SUPPORTED; + av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n"); + return AVERROR_EXIT; + } + break; + case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082: + if ((avctx->width / 64 * 64 == avctx->width && avctx->height / 16 * 16 == avctx->height) || (avctx->width == 1920 && avctx->height == 1080)) + { + res = AMF_OK; + } + else + { + res = AMF_NOT_SUPPORTED; + av_log(ctx, AV_LOG_ERROR, "Resolution incorrect for alignment mode\n"); + return AVERROR_EXIT; + } + break; + case AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS: + res = AMF_OK; + break; + default: + res = AMF_NOT_SUPPORTED; + av_log(ctx, AV_LOG_ERROR, "Invalid alignment mode\n"); + return AVERROR_EXIT; + } + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE, ctx->align); + + + // init encoder + res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height); + AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res); + + // init dynamic picture control params + if (ctx->min_qp_i != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, ctx->min_qp_i); + } + else if (avctx->qmin != -1) { + int qval = avctx->qmin > 255 ? 255 : avctx->qmin; + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTRA, qval); + } + if (ctx->max_qp_i != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, ctx->max_qp_i); + } + else if (avctx->qmax != -1) { + int qval = avctx->qmax > 255 ? 255 : avctx->qmax; + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTRA, qval); + } + if (ctx->min_qp_p != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, ctx->min_qp_p); + } + else if (avctx->qmin != -1) { + int qval = avctx->qmin > 255 ? 255 : avctx->qmin; + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MIN_Q_INDEX_INTER, qval); + } + if (ctx->max_qp_p != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, ctx->max_qp_p); + } + else if (avctx->qmax != -1) { + int qval = avctx->qmax > 255 ? 255 : avctx->qmax; + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_Q_INDEX_INTER, qval); + } + + if (ctx->qp_p != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER, ctx->qp_p); + } + if (ctx->qp_i != -1) { + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTRA, ctx->qp_i); + } + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_SKIP_FRAME, ctx->skip_frame); + + + // fill extradata + res = AMFVariantInit(&var); + AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "AMFVariantInit() failed with error %d\n", res); + + res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_EXTRA_DATA, &var); + AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n", res); + AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG, "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n"); + + guid = IID_AMFBuffer(); + + res = var.pInterface->pVtbl->QueryInterface(var.pInterface, &guid, (void**)&buffer); // query for buffer interface + if (res != AMF_OK) { + var.pInterface->pVtbl->Release(var.pInterface); + } + AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "QueryInterface(IID_AMFBuffer) failed with error %d\n", res); + + avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer); + avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + buffer->pVtbl->Release(buffer); + var.pInterface->pVtbl->Release(var.pInterface); + return AVERROR(ENOMEM); + } + memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer), avctx->extradata_size); + + buffer->pVtbl->Release(buffer); + var.pInterface->pVtbl->Release(var.pInterface); + + return 0; +} + +static const FFCodecDefault defaults[] = { + { "refs", "-1" }, + { "aspect", "0" }, + { "b", "2M" }, + { "g", "250" }, + { "qmin", "-1" }, + { "qmax", "-1" }, + { NULL }, +}; + +static const AVClass av1_amf_class = { + .class_name = "av1_amf", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const FFCodec ff_av1_amf_encoder = { + .p.name = "av1_amf", + CODEC_LONG_NAME("AMD AMF AV1 encoder"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_AV1, + .init = amf_encode_init_av1, + FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet), + .close = ff_amf_encode_close, + .priv_data_size = sizeof(AmfContext), + .p.priv_class = &av1_amf_class, + .defaults = defaults, + .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | + AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .p.pix_fmts = ff_amf_pix_fmts, + .p.wrapper_name = "amf", + .hw_configs = ff_amfenc_hw_configs, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/amrwbdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/amrwbdec.c index b59066ad..9d75b972 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/amrwbdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/amrwbdec.c @@ -1304,6 +1304,6 @@ const FFCodec ff_amrwb_decoder = { .init = amrwb_decode_init, FF_CODEC_DECODE_CB(amrwb_decode_frame), .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, - .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/apac.c b/arm/raspi/third_party/ffmpeg/libavcodec/apac.c index e9f6a0dd..3408f752 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/apac.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/apac.c @@ -75,7 +75,10 @@ static av_cold int apac_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_U8P; if (avctx->ch_layout.nb_channels < 1 || - avctx->ch_layout.nb_channels > 2) + avctx->ch_layout.nb_channels > 2 || + avctx->bits_per_coded_sample < 8 || + avctx->bits_per_coded_sample > 16 + ) return AVERROR_INVALIDDATA; for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) { @@ -196,15 +199,19 @@ static int apac_decode(AVCodecContext *avctx, AVFrame *frame, return AVERROR_INVALIDDATA; } - if (get_bits_left(gb) < c->block_length * c->bit_length && pkt->size) { - c->have_code = 1; - s->cur_ch = ch; - goto end; + if (get_bits_left(gb) < c->block_length * c->bit_length) { + if (pkt->size) { + c->have_code = 1; + s->cur_ch = ch; + goto end; + } else { + break; + } } for (int i = 0; i < c->block_length; i++) { int val = get_bits_long(gb, c->bit_length); - int delta = (val & 1) ? ~(val >> 1) : (val >> 1); + unsigned delta = (val & 1) ? ~(val >> 1) : (val >> 1); int sample; delta += c->last_delta; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/aptxenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/aptxenc.c index 5fc0378f..6deebaf2 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/aptxenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/aptxenc.c @@ -271,7 +271,7 @@ const FFCodec ff_aptx_encoder = { CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_APTX, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AptXEncContext), .init = aptx_encode_init, FF_CODEC_ENCODE_CB(aptx_encode_frame), @@ -290,7 +290,7 @@ const FFCodec ff_aptx_hd_encoder = { CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_APTX_HD, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AptXEncContext), .init = aptx_encode_init, FF_CODEC_ENCODE_CB(aptx_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ass.c b/arm/raspi/third_party/ffmpeg/libavcodec/ass.c index 728cfb1a..5058dc83 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ass.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ass.c @@ -41,10 +41,11 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx, "PlayResX: %d\r\n" "PlayResY: %d\r\n" "ScaledBorderAndShadow: yes\r\n" + "YCbCr Matrix: None\r\n" "\r\n" "[V4+ Styles]\r\n" - /* ASSv4 header */ + /* ASS (v4+) header */ "Format: Name, " "Fontname, Fontsize, " "PrimaryColour, SecondaryColour, OutlineColour, BackColour, " @@ -64,7 +65,7 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx, "0,0," /* Spacing, Angle */ "%d,1,0," /* BorderStyle, Outline, Shadow */ "%d,10,10,10," /* Alignment, Margin[LRV] */ - "0\r\n" /* Encoding */ + "1\r\n" /* Encoding */ "\r\n" "[Events]\r\n" diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/asvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/asvenc.c index 9da7cbb9..4a14bcf8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/asvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/asvenc.c @@ -362,7 +362,7 @@ const FFCodec ff_asv1_encoder = { CODEC_LONG_NAME("ASUS V1"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ASV1, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(ASVEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), @@ -377,7 +377,7 @@ const FFCodec ff_asv2_encoder = { CODEC_LONG_NAME("ASUS V2"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ASV2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(ASVEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/av1_parser.c b/arm/raspi/third_party/ffmpeg/libavcodec/av1_parser.c index 4cbd7408..e57e3827 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/av1_parser.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/av1_parser.c @@ -162,6 +162,12 @@ static int av1_parser_parse(AVCodecParserContext *ctx, avctx->color_trc = (enum AVColorTransferCharacteristic) color->transfer_characteristics; avctx->color_range = color->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + if (seq->timing_info_present_flag) { + const AV1RawTimingInfo *timing = &seq->timing_info; + av_reduce(&avctx->framerate.den, &avctx->framerate.num, + timing->num_units_in_display_tick, timing->time_scale, INT_MAX); + } + if (avctx->framerate.num) avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/av1dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/av1dec.c index 0c24eac8..d83c902f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/av1dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/av1dec.c @@ -194,7 +194,7 @@ static uint8_t get_shear_params_valid(AV1DecContext *s, int idx) } /** -* update gm type/params, since cbs already implemented part of this funcation, +* update gm type/params, since cbs already implemented part of this function, * so we don't need to full implement spec. */ static void global_motion_params(AV1DecContext *s) @@ -567,7 +567,7 @@ static int get_pixel_format(AVCodecContext *avctx) * implemented in the future, need remove this check. */ if (!avctx->hwaccel) { - av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport" + av_log(avctx, AV_LOG_ERROR, "Your platform doesn't support" " hardware accelerated AV1 decoding.\n"); return AVERROR(ENOSYS); } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.c b/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.c index a85d3c23..efa76d27 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.c @@ -386,9 +386,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx) av_frame_unref(avci->recon_frame); } else { av_packet_unref(avci->last_pkt_props); - while (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) >= 0) - av_packet_unref(avci->last_pkt_props); - av_packet_unref(avci->in_pkt); avctx->pts_correction_last_pts = @@ -453,13 +450,6 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_freep(&avci->byte_buffer); av_frame_free(&avci->buffer_frame); av_packet_free(&avci->buffer_pkt); - if (avci->pkt_props) { - while (av_fifo_can_read(avci->pkt_props)) { - av_packet_unref(avci->last_pkt_props); - av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1); - } - av_fifo_freep2(&avci->pkt_props); - } av_packet_free(&avci->last_pkt_props); av_packet_free(&avci->in_pkt); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.h b/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.h index 3edd8e26..90b437cc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/avcodec.h @@ -232,15 +232,48 @@ typedef struct RcOverride{ */ #define AV_CODEC_FLAG_DROPCHANGED (1 << 5) /** - * Request the encoder to output reconstructed frames, i.e. frames that would be - * produced by decoding the encoded bistream. These frames may be retrieved by - * calling avcodec_receive_frame() immediately after a successful call to + * Request the encoder to output reconstructed frames, i.e.\ frames that would + * be produced by decoding the encoded bistream. These frames may be retrieved + * by calling avcodec_receive_frame() immediately after a successful call to * avcodec_receive_packet(). * * Should only be used with encoders flagged with the - * AV_CODEC_CAP_ENCODER_RECON_FRAME capability. + * @ref AV_CODEC_CAP_ENCODER_RECON_FRAME capability. */ #define AV_CODEC_FLAG_RECON_FRAME (1 << 6) +/** + * Request the encoder to propagate each frame's AVFrame.opaque and + * AVFrame.opaque_ref values to its corresponding output AVPacket. + * + * May only be set on encoders that have the + * @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag. + * + * @note + * While in typical cases one input frame produces exactly one output packet + * (perhaps after a delay), in general the mapping of frames to packets is + * M-to-N, so + * - Any number of input frames may be associated with any given output packet. + * This includes zero - e.g. some encoders may output packets that carry only + * metadata about the whole stream. + * - A given input frame may be associated with any number of output packets. + * Again this includes zero - e.g. some encoders may drop frames under certain + * conditions. + * . + * This implies that when using this flag, the caller must NOT assume that + * - a given input frame's opaques will necessarily appear on some output packet; + * - every output packet will have some non-NULL opaque value. + * . + * When an output packet contains multiple frames, the opaque values will be + * taken from the first of those. + */ +#define AV_CODEC_FLAG_COPY_OPAQUE (1 << 7) +/** + * Signal to the encoder that the values of AVFrame.duration are valid and + * should be used (typically for transferring them to output packets). + * + * If this flag is not set, frame durations are ignored. + */ +#define AV_CODEC_FLAG_FRAME_DURATION (1 << 8) /** * Use internal 2pass ratecontrol in first pass mode. */ @@ -2253,6 +2286,22 @@ typedef struct AVHWAccel { */ #define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) +/** + * Some hardware decoders (namely nvdec) can either output direct decoder + * surfaces, or make an on-device copy and return said copy. + * There is a hard limit on how many decoder surfaces there can be, and it + * cannot be accurately guessed ahead of time. + * For some processing chains, this can be okay, but others will run into the + * limit and in turn produce very confusing errors that require fine tuning of + * more or less obscure options by the user, or in extreme cases cannot be + * resolved at all without inserting an avfilter that forces a copy. + * + * Thus, the hwaccel will by default make a copy for safety and resilience. + * If a users really wants to minimize the amount of copies, they can set this + * flag and ensure their processing chain does not exhaust the surface pool. + */ +#define AV_HWACCEL_FLAG_UNSAFE_OUTPUT (1 << 3) + /** * @} */ @@ -2589,17 +2638,17 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, * still has frames buffered, it will return them after sending * a flush packet. * - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted in the current state - user - * must read output with avcodec_receive_frame() (once - * all output is read, the packet should be resent, and - * the call will not fail with EAGAIN). - * AVERROR_EOF: the decoder has been flushed, and no new packets can - * be sent to it (also returned if more than 1 flush - * packet is sent) - * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush - * AVERROR(ENOMEM): failed to add packet to internal queue, or similar - * other errors: legitimate decoding errors + * @retval 0 success + * @retval AVERROR(EAGAIN) input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, + * and the call will not fail with EAGAIN). + * @retval AVERROR_EOF the decoder has been flushed, and no new packets can be + * sent to it (also returned if more than 1 flush + * packet is sent) + * @retval AVERROR(EINVAL) codec not opened, it is an encoder, or requires flush + * @retval AVERROR(ENOMEM) failed to add packet to internal queue, or similar + * @retval "another negative error code" legitimate decoding errors */ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); @@ -2613,18 +2662,17 @@ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); * codec. Note that the function will always call * av_frame_unref(frame) before doing anything else. * - * @return - * 0: success, a frame was returned - * AVERROR(EAGAIN): output is not available in this state - user must try - * to send new input - * AVERROR_EOF: the codec has been fully flushed, and there will be - * no more output frames - * AVERROR(EINVAL): codec not opened, or it is an encoder without - * the AV_CODEC_FLAG_RECON_FRAME flag enabled - * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters - * with respect to first decoded frame. Applicable - * when flag AV_CODEC_FLAG_DROPCHANGED is set. - * other negative values: legitimate decoding errors + * @retval 0 success, a frame was returned + * @retval AVERROR(EAGAIN) output is not available in this state - user must + * try to send new input + * @retval AVERROR_EOF the codec has been fully flushed, and there will be + * no more output frames + * @retval AVERROR(EINVAL) codec not opened, or it is an encoder without the + * AV_CODEC_FLAG_RECON_FRAME flag enabled + * @retval AVERROR_INPUT_CHANGED current decoded frame has changed parameters with + * respect to first decoded frame. Applicable when flag + * AV_CODEC_FLAG_DROPCHANGED is set. + * @retval "other negative error code" legitimate decoding errors */ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); @@ -2651,16 +2699,16 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); * If it is not set, frame->nb_samples must be equal to * avctx->frame_size for all frames except the last. * The final frame may be smaller than avctx->frame_size. - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted in the current state - user - * must read output with avcodec_receive_packet() (once - * all output is read, the packet should be resent, and - * the call will not fail with EAGAIN). - * AVERROR_EOF: the encoder has been flushed, and no new frames can - * be sent to it - * AVERROR(EINVAL): codec not opened, it is a decoder, or requires flush - * AVERROR(ENOMEM): failed to add packet to internal queue, or similar - * other errors: legitimate encoding errors + * @retval 0 success + * @retval AVERROR(EAGAIN) input is not accepted in the current state - user must + * read output with avcodec_receive_packet() (once all + * output is read, the packet should be resent, and the + * call will not fail with EAGAIN). + * @retval AVERROR_EOF the encoder has been flushed, and no new frames can + * be sent to it + * @retval AVERROR(EINVAL) codec not opened, it is a decoder, or requires flush + * @retval AVERROR(ENOMEM) failed to add packet to internal queue, or similar + * @retval "another negative error code" legitimate encoding errors */ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); @@ -2671,13 +2719,13 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); * @param avpkt This will be set to a reference-counted packet allocated by the * encoder. Note that the function will always call * av_packet_unref(avpkt) before doing anything else. - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): output is not available in the current state - user - * must try to send input - * AVERROR_EOF: the encoder has been fully flushed, and there will be - * no more output packets - * AVERROR(EINVAL): codec not opened, or it is a decoder - * other errors: legitimate encoding errors + * @retval 0 success + * @retval AVERROR(EAGAIN) output is not available in the current state - user must + * try to send input + * @retval AVERROR_EOF the encoder has been fully flushed, and there will be no + * more output packets + * @retval AVERROR(EINVAL) codec not opened, or it is a decoder + * @retval "another negative error code" legitimate encoding errors */ int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/avpacket.c b/arm/raspi/third_party/ffmpeg/libavcodec/avpacket.c index bcbc4166..5fef65e9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/avpacket.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/avpacket.c @@ -316,7 +316,7 @@ uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size) const AVDictionaryEntry *t = NULL; size_t total_length = 0; - while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + while ((t = av_dict_iterate(dict, t))) { for (int i = 0; i < 2; i++) { const char *str = i ? t->value : t->key; const size_t len = strlen(str) + 1; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/avuienc.c b/arm/raspi/third_party/ffmpeg/libavcodec/avuienc.c index 0b82848c..8a093d3d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/avuienc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/avuienc.c @@ -96,7 +96,8 @@ const FFCodec ff_avui_encoder = { CODEC_LONG_NAME("Avid Meridien Uncompressed"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_AVUI, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE }, .init = avui_encode_init, FF_CODEC_ENCODE_CB(avui_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/binkaudio.c b/arm/raspi/third_party/ffmpeg/libavcodec/binkaudio.c index 43dca1f5..f28ecba7 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/binkaudio.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/binkaudio.c @@ -33,15 +33,14 @@ #include "libavutil/channel_layout.h" #include "libavutil/intfloat.h" #include "libavutil/mem_internal.h" +#include "libavutil/tx.h" #define BITSTREAM_READER_LE #include "avcodec.h" -#include "dct.h" #include "decode.h" #include "get_bits.h" #include "codec_internal.h" #include "internal.h" -#include "rdft.h" #include "wma_freqs.h" #define MAX_DCT_CHANNELS 6 @@ -63,10 +62,8 @@ typedef struct BinkAudioContext { float previous[MAX_DCT_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block float quant_table[96]; AVPacket *pkt; - union { - RDFTContext rdft; - DCTContext dct; - } trans; + AVTXContext *tx; + av_tx_fn tx_fn; } BinkAudioContext; @@ -138,12 +135,15 @@ static av_cold int decode_init(AVCodecContext *avctx) s->first = 1; - if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) - ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); - else if (CONFIG_BINKAUDIO_DCT_DECODER) - ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); - else + if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) { + float scale = 0.5; + ret = av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_RDFT, 1, 1 << frame_len_bits, &scale, 0); + } else if (CONFIG_BINKAUDIO_DCT_DECODER) { + float scale = 1.0 / (1 << frame_len_bits); + ret = av_tx_init(&s->tx, &s->tx_fn, AV_TX_FLOAT_DCT, 1, 1 << (frame_len_bits - 1), &scale, 0); + } else { av_assert0(0); + } if (ret < 0) return ret; @@ -177,13 +177,12 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct, float q, quant[25]; int width, coeff; GetBitContext *gb = &s->gb; + LOCAL_ALIGNED_32(float, coeffs, [4098]); if (use_dct) skip_bits(gb, 2); for (ch = 0; ch < channels; ch++) { - FFTSample *coeffs = out[ch + ch_offset]; - if (s->version_b) { if (get_bits_left(gb) < 64) return AVERROR_INVALIDDATA; @@ -251,10 +250,15 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct, if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) { coeffs[0] /= 0.5; - s->trans.dct.dct_calc(&s->trans.dct, coeffs); + s->tx_fn(s->tx, out[ch + ch_offset], coeffs, sizeof(float)); + } else if (CONFIG_BINKAUDIO_RDFT_DECODER) { + for (int i = 2; i < s->frame_len; i += 2) + coeffs[i + 1] *= -1; + + coeffs[s->frame_len + 0] = coeffs[1]; + coeffs[s->frame_len + 1] = coeffs[1] = 0; + s->tx_fn(s->tx, out[ch + ch_offset], coeffs, sizeof(AVComplexFloat)); } - else if (CONFIG_BINKAUDIO_RDFT_DECODER) - s->trans.rdft.rdft_calc(&s->trans.rdft, coeffs); } for (ch = 0; ch < channels; ch++) { @@ -278,11 +282,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct, static av_cold int decode_end(AVCodecContext *avctx) { BinkAudioContext * s = avctx->priv_data; - if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) - ff_rdft_end(&s->trans.rdft); - else if (CONFIG_BINKAUDIO_DCT_DECODER) - ff_dct_end(&s->trans.dct); - + av_tx_uninit(&s->tx); return 0; } @@ -296,9 +296,10 @@ static int binkaudio_receive_frame(AVCodecContext *avctx, AVFrame *frame) { BinkAudioContext *s = avctx->priv_data; GetBitContext *gb = &s->gb; - int ret; + int new_pkt, ret; again: + new_pkt = !s->pkt->data; if (!s->pkt->data) { ret = ff_decode_get_packet(avctx, s->pkt); if (ret < 0) { @@ -325,6 +326,8 @@ again: frame->nb_samples = s->frame_len; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; + if (!new_pkt) + frame->pts = AV_NOPTS_VALUE; } if (decode_block(s, (float **)frame->extended_data, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bitpacked_enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/bitpacked_enc.c index ca4d5c88..3c4e1129 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/bitpacked_enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bitpacked_enc.c @@ -110,7 +110,8 @@ const FFCodec ff_bitpacked_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_BITPACKED, .priv_data_size = sizeof(struct BitpackedContext), - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bitstream.h b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream.h new file mode 100644 index 00000000..b60f0c29 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream reader API header. + */ + +/* + * Bit order (endianness) is controlled by #defining BITSTREAM_BE and/or + * BITSTREAM_LE before #including this header. The corresponding bitreading + * functions are provided as bits_*_be()/bits_*_le() respectively. + * + * If neither or only BITSTREAM_BE is defined, then the default (unsuffixed) + * bits_*() will resolve to the big-endian implementation. If only BITSTREAM_LE + * is defined, little-endian will be the default. + * + * If both are defined, then the default can be controlled by defining at most + * one of BITSTREAM_DEFAULT_LE/BE. When BITSTREAM_DEFAULT_* is not defined, no + * default is provided and you must always explicitly use the _be() or _le() + * variants. + */ + +#ifndef AVCODEC_BITSTREAM_H +#define AVCODEC_BITSTREAM_H + +#include + +#include "config.h" + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" + +#include "mathops.h" +#include "vlc.h" + +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +// select the default endianness, if any +#if defined(BITSTREAM_LE) && defined(BITSTREAM_BE) + +# if defined(BITSTREAM_DEFAULT_BE) && defined(BITSTREAM_DEFAULT_LE) +# error "At most one of BITSTREAM_DEFAULT_BE/LE must be defined" +# elif defined(BITSTREAM_DEFAULT_BE) +# define BITS_DEFAULT_BE +# elif defined(BITSTREAM_DEFAULT_LE) +# define BITS_DEFAULT_LE +# endif + +#elif defined(BITSTREAM_LE) +# define BITS_DEFAULT_LE +#else // select BE if nothing is requested explicitly +# define BITS_DEFAULT_BE +# define BITSTREAM_WANT_BE +#endif + +#if defined(BITS_DEFAULT_LE) + +# define BitstreamContext BitstreamContextLE +# define bits_init bits_init_le +# define bits_init8 bits_init8_le +# define bits_tell bits_tell_le +# define bits_size bits_size_le +# define bits_left bits_left_le +# define bits_read_bit bits_read_bit_le +# define bits_read_nz bits_read_nz_le +# define bits_read bits_read_le +# define bits_read_63 bits_read_63_le +# define bits_read_64 bits_read_64_le +# define bits_read_signed bits_read_signed_le +# define bits_read_signed_nz bits_read_signed_nz_le +# define bits_peek_nz bits_peek_nz_le +# define bits_peek bits_peek_le +# define bits_peek_signed bits_peek_signed_le +# define bits_peek_signed_nz bits_peek_signed_nz_le +# define bits_skip bits_skip_le +# define bits_seek bits_seek_le +# define bits_align bits_align_le +# define bits_read_xbits bits_read_xbits_le +# define bits_decode012 bits_decode012_le +# define bits_decode210 bits_decode210_le +# define bits_apply_sign bits_apply_sign_le +# define bits_read_vlc bits_read_vlc_le + +#elif defined(BITS_DEFAULT_BE) + +# define BitstreamContext BitstreamContextBE +# define bits_init bits_init_be +# define bits_init8 bits_init8_be +# define bits_tell bits_tell_be +# define bits_size bits_size_be +# define bits_left bits_left_be +# define bits_read_bit bits_read_bit_be +# define bits_read_nz bits_read_nz_be +# define bits_read bits_read_be +# define bits_read_63 bits_read_63_be +# define bits_read_64 bits_read_64_be +# define bits_read_signed bits_read_signed_be +# define bits_read_signed_nz bits_read_signed_nz_be +# define bits_peek_nz bits_peek_nz_be +# define bits_peek bits_peek_be +# define bits_peek_signed bits_peek_signed_be +# define bits_peek_signed_nz bits_peek_signed_nz_be +# define bits_skip bits_skip_be +# define bits_seek bits_seek_be +# define bits_align bits_align_be +# define bits_read_xbits bits_read_xbits_be +# define bits_decode012 bits_decode012_be +# define bits_decode210 bits_decode210_be +# define bits_apply_sign bits_apply_sign_be +# define bits_read_vlc bits_read_vlc_be + +#endif + +#undef BITS_DEFAULT_LE +#undef BITS_DEFAULT_BE + +#define BITS_RL_VLC(level, run, bc, table, bits, max_depth) \ + do { \ + int n, nb_bits; \ + unsigned int index = bits_peek(bc, bits); \ + level = table[index].level; \ + n = table[index].len; \ + \ + if (max_depth > 1 && n < 0) { \ + bits_skip(bc, bits); \ + \ + nb_bits = -n; \ + \ + index = bits_peek(bc, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + if (max_depth > 2 && n < 0) { \ + bits_skip(bc, nb_bits); \ + nb_bits = -n; \ + \ + index = bits_peek(bc, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + } \ + } \ + run = table[index].run; \ + bits_skip(bc, n); \ + } while (0) + +#endif /* AVCODEC_BITSTREAM_H */ + +// the following is deliberately outside of the standard #include guards + +#if defined(BITSTREAM_LE) && !defined(BITSTREAM_WANT_LE) +# define BITSTREAM_WANT_LE +#endif + +#if defined(BITSTREAM_BE) && !defined(BITSTREAM_WANT_BE) +# define BITSTREAM_WANT_BE +#endif + +#if defined(BITSTREAM_WANT_LE) && !defined(AVCODEC_BITSTREAM_LE) +#define AVCODEC_BITSTREAM_LE + +#define BITSTREAM_TEMPLATE_LE +#include "bitstream_template.h" +#undef BITSTREAM_TEMPLATE_LE + +#endif + +#if defined(BITSTREAM_WANT_BE) && !defined(AVCODEC_BITSTREAM_BE) +#define AVCODEC_BITSTREAM_BE + +#include "bitstream_template.h" + +#endif + +#undef BITSTREAM_WANT_LE +#undef BITSTREAM_WANT_BE diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_filters.c b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_filters.c index a3bebefe..e8216819 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_filters.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_filters.c @@ -43,6 +43,7 @@ extern const FFBitStreamFilter ff_hapqa_extract_bsf; extern const FFBitStreamFilter ff_hevc_metadata_bsf; extern const FFBitStreamFilter ff_hevc_mp4toannexb_bsf; extern const FFBitStreamFilter ff_imx_dump_header_bsf; +extern const FFBitStreamFilter ff_media100_to_mjpegb_bsf; extern const FFBitStreamFilter ff_mjpeg2jpeg_bsf; extern const FFBitStreamFilter ff_mjpega_dump_header_bsf; extern const FFBitStreamFilter ff_mp3_header_decompress_bsf; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_template.h b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_template.h new file mode 100644 index 00000000..30bea84a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bitstream_template.h @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef BITSTREAM_TEMPLATE_LE +# define BS_SUFFIX_LOWER _le +# define BS_SUFFIX_UPPER LE +#else +# define BS_SUFFIX_LOWER _be +# define BS_SUFFIX_UPPER BE +#endif + +#define BS_JOIN(x, y, z) x ## y ## z +#define BS_JOIN3(x, y, z) BS_JOIN(x, y, z) +#define BS_FUNC(x) BS_JOIN3(bits_, x, BS_SUFFIX_LOWER) + +#define BSCTX BS_JOIN3(Bitstream, Context, BS_SUFFIX_UPPER) + +typedef struct BSCTX { + uint64_t bits; // stores bits read from the buffer + const uint8_t *buffer, *buffer_end; + const uint8_t *ptr; // pointer to the position inside a buffer + unsigned bits_valid; // number of bits left in bits field + unsigned size_in_bits; +} BSCTX; + +/** + * @return + * - 0 on successful refill + * - a negative number when bitstream end is hit + * + * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled. + */ +static inline int BS_FUNC(priv_refill_64)(BSCTX *bc) +{ +#if !UNCHECKED_BITSTREAM_READER + if (bc->ptr >= bc->buffer_end) + return -1; +#endif + +#ifdef BITSTREAM_TEMPLATE_LE + bc->bits = AV_RL64(bc->ptr); +#else + bc->bits = AV_RB64(bc->ptr); +#endif + bc->ptr += 8; + bc->bits_valid = 64; + + return 0; +} + +/** + * @return + * - 0 on successful refill + * - a negative number when bitstream end is hit + * + * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled. + */ +static inline int BS_FUNC(priv_refill_32)(BSCTX *bc) +{ +#if !UNCHECKED_BITSTREAM_READER + if (bc->ptr >= bc->buffer_end) + return -1; +#endif + +#ifdef BITSTREAM_TEMPLATE_LE + bc->bits |= (uint64_t)AV_RL32(bc->ptr) << bc->bits_valid; +#else + bc->bits |= (uint64_t)AV_RB32(bc->ptr) << (32 - bc->bits_valid); +#endif + bc->ptr += 4; + bc->bits_valid += 32; + + return 0; +} + +/** + * Initialize BitstreamContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end + * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int BS_FUNC(init)(BSCTX *bc, const uint8_t *buffer, + unsigned int bit_size) +{ + unsigned int buffer_size; + + if (bit_size > INT_MAX - 7 || !buffer) { + bc->buffer = NULL; + bc->ptr = NULL; + bc->bits_valid = 0; + return AVERROR_INVALIDDATA; + } + + buffer_size = (bit_size + 7) >> 3; + + bc->buffer = buffer; + bc->buffer_end = buffer + buffer_size; + bc->ptr = bc->buffer; + bc->size_in_bits = bit_size; + bc->bits_valid = 0; + bc->bits = 0; + + BS_FUNC(priv_refill_64)(bc); + + return 0; +} + +/** + * Initialize BitstreamContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end + * @param byte_size the size of the buffer in bytes + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow + */ +static inline int BS_FUNC(init8)(BSCTX *bc, const uint8_t *buffer, + unsigned int byte_size) +{ + if (byte_size > INT_MAX / 8) + return AVERROR_INVALIDDATA; + return BS_FUNC(init)(bc, buffer, byte_size * 8); +} + +/** + * Return number of bits already read. + */ +static inline int BS_FUNC(tell)(const BSCTX *bc) +{ + return (bc->ptr - bc->buffer) * 8 - bc->bits_valid; +} + +/** + * Return buffer size in bits. + */ +static inline int BS_FUNC(size)(const BSCTX *bc) +{ + return bc->size_in_bits; +} + +/** + * Return the number of the bits left in a buffer. + */ +static inline int BS_FUNC(left)(const BSCTX *bc) +{ + return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_valid; +} + +static inline uint64_t BS_FUNC(priv_val_show)(BSCTX *bc, unsigned int n) +{ + av_assert2(n > 0 && n <= 64); + +#ifdef BITSTREAM_TEMPLATE_LE + return bc->bits & (UINT64_MAX >> (64 - n)); +#else + return bc->bits >> (64 - n); +#endif +} + +static inline void BS_FUNC(priv_skip_remaining)(BSCTX *bc, unsigned int n) +{ +#ifdef BITSTREAM_TEMPLATE_LE + bc->bits >>= n; +#else + bc->bits <<= n; +#endif + bc->bits_valid -= n; +} + +static inline uint64_t BS_FUNC(priv_val_get)(BSCTX *bc, unsigned int n) +{ + uint64_t ret; + + av_assert2(n > 0 && n < 64); + + ret = BS_FUNC(priv_val_show)(bc, n); + BS_FUNC(priv_skip_remaining)(bc, n); + + return ret; +} + +/** + * Return one bit from the buffer. + */ +static inline unsigned int BS_FUNC(read_bit)(BSCTX *bc) +{ + if (!bc->bits_valid && BS_FUNC(priv_refill_64)(bc) < 0) + return 0; + + return BS_FUNC(priv_val_get)(bc, 1); +} + +/** + * Return n bits from the buffer, n has to be in the 1-32 range. + * May be faster than bits_read() when n is not a compile-time constant and is + * known to be non-zero; + */ +static inline uint32_t BS_FUNC(read_nz)(BSCTX *bc, unsigned int n) +{ + av_assert2(n > 0 && n <= 32); + + if (n > bc->bits_valid) { + if (BS_FUNC(priv_refill_32)(bc) < 0) + bc->bits_valid = n; + } + + return BS_FUNC(priv_val_get)(bc, n); +} + +/** + * Return n bits from the buffer, n has to be in the 0-32 range. + */ +static inline uint32_t BS_FUNC(read)(BSCTX *bc, unsigned int n) +{ + av_assert2(n <= 32); + + if (!n) + return 0; + + return BS_FUNC(read_nz)(bc, n); +} + +/** + * Return n bits from the buffer, n has to be in the 0-63 range. + */ +static inline uint64_t BS_FUNC(read_63)(BSCTX *bc, unsigned int n) +{ + uint64_t ret = 0; + unsigned left = 0; + + av_assert2(n <= 63); + + if (!n) + return 0; + + if (n > bc->bits_valid) { + left = bc->bits_valid; + n -= left; + + if (left) + ret = BS_FUNC(priv_val_get)(bc, left); + + if (BS_FUNC(priv_refill_64)(bc) < 0) + bc->bits_valid = n; + + } + +#ifdef BITSTREAM_TEMPLATE_LE + ret = BS_FUNC(priv_val_get)(bc, n) << left | ret; +#else + ret = BS_FUNC(priv_val_get)(bc, n) | ret << n; +#endif + + return ret; +} + +/** + * Return n bits from the buffer, n has to be in the 0-64 range. + */ +static inline uint64_t BS_FUNC(read_64)(BSCTX *bc, unsigned int n) +{ + av_assert2(n <= 64); + + if (n == 64) { + uint64_t ret = BS_FUNC(read_63)(bc, 63); +#ifdef BITSTREAM_TEMPLATE_LE + return ret | ((uint64_t)BS_FUNC(read_bit)(bc) << 63); +#else + return (ret << 1) | (uint64_t)BS_FUNC(read_bit)(bc); +#endif + } + return BS_FUNC(read_63)(bc, n); +} + +/** + * Return n bits from the buffer as a signed integer, n has to be in the 1-32 + * range. May be faster than bits_read_signed() when n is not a compile-time + * constant and is known to be non-zero; + */ +static inline int32_t BS_FUNC(read_signed_nz)(BSCTX *bc, unsigned int n) +{ + av_assert2(n > 0 && n <= 32); + return sign_extend(BS_FUNC(read_nz)(bc, n), n); +} + +/** + * Return n bits from the buffer as a signed integer. + * n has to be in the 0-32 range. + */ +static inline int32_t BS_FUNC(read_signed)(BSCTX *bc, unsigned int n) +{ + av_assert2(n <= 32); + + if (!n) + return 0; + + return BS_FUNC(read_signed_nz)(bc, n); +} + +/** + * Return n bits from the buffer but do not change the buffer state. + * n has to be in the 1-32 range. May + */ +static inline uint32_t BS_FUNC(peek_nz)(BSCTX *bc, unsigned int n) +{ + av_assert2(n > 0 && n <= 32); + + if (n > bc->bits_valid) + BS_FUNC(priv_refill_32)(bc); + + return BS_FUNC(priv_val_show)(bc, n); +} + +/** + * Return n bits from the buffer but do not change the buffer state. + * n has to be in the 0-32 range. + */ +static inline uint32_t BS_FUNC(peek)(BSCTX *bc, unsigned int n) +{ + av_assert2(n <= 32); + + if (!n) + return 0; + + return BS_FUNC(peek_nz)(bc, n); +} + +/** + * Return n bits from the buffer as a signed integer, do not change the buffer + * state. n has to be in the 1-32 range. May be faster than bits_peek_signed() + * when n is not a compile-time constant and is known to be non-zero; + */ +static inline int BS_FUNC(peek_signed_nz)(BSCTX *bc, unsigned int n) +{ + av_assert2(n > 0 && n <= 32); + return sign_extend(BS_FUNC(peek_nz)(bc, n), n); +} + +/** + * Return n bits from the buffer as a signed integer, + * do not change the buffer state. + * n has to be in the 0-32 range. + */ +static inline int BS_FUNC(peek_signed)(BSCTX *bc, unsigned int n) +{ + av_assert2(n <= 32); + + if (!n) + return 0; + + return BS_FUNC(peek_signed_nz)(bc, n); +} + +/** + * Skip n bits in the buffer. + */ +static inline void BS_FUNC(skip)(BSCTX *bc, unsigned int n) +{ + if (n < bc->bits_valid) + BS_FUNC(priv_skip_remaining)(bc, n); + else { + n -= bc->bits_valid; + bc->bits = 0; + bc->bits_valid = 0; + + if (n >= 64) { + unsigned int skip = n / 8; + + n -= skip * 8; + bc->ptr += skip; + } + BS_FUNC(priv_refill_64)(bc); + if (n) + BS_FUNC(priv_skip_remaining)(bc, n); + } +} + +/** + * Seek to the given bit position. + */ +static inline void BS_FUNC(seek)(BSCTX *bc, unsigned pos) +{ + bc->ptr = bc->buffer; + bc->bits = 0; + bc->bits_valid = 0; + + BS_FUNC(skip)(bc, pos); +} + +/** + * Skip bits to a byte boundary. + */ +static inline const uint8_t *BS_FUNC(align)(BSCTX *bc) +{ + unsigned int n = -BS_FUNC(tell)(bc) & 7; + if (n) + BS_FUNC(skip)(bc, n); + return bc->buffer + (BS_FUNC(tell)(bc) >> 3); +} + +/** + * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). + * If MSB not set it is negative. + * @param n length in bits + */ +static inline int BS_FUNC(read_xbits)(BSCTX *bc, unsigned int n) +{ + int32_t cache = BS_FUNC(peek)(bc, 32); + int sign = ~cache >> 31; + BS_FUNC(priv_skip_remaining)(bc, n); + + return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; +} + +/** + * Return decoded truncated unary code for the values 0, 1, 2. + */ +static inline int BS_FUNC(decode012)(BSCTX *bc) +{ + if (!BS_FUNC(read_bit)(bc)) + return 0; + else + return BS_FUNC(read_bit)(bc) + 1; +} + +/** + * Return decoded truncated unary code for the values 2, 1, 0. + */ +static inline int BS_FUNC(decode210)(BSCTX *bc) +{ + if (BS_FUNC(read_bit)(bc)) + return 0; + else + return 2 - BS_FUNC(read_bit)(bc); +} + +/* Read sign bit and flip the sign of the provided value accordingly. */ +static inline int BS_FUNC(apply_sign)(BSCTX *bc, int val) +{ + int sign = BS_FUNC(read_signed)(bc, 1); + return (val ^ sign) - sign; +} + +static inline int BS_FUNC(skip_1stop_8data)(BSCTX *s) +{ + if (BS_FUNC(left)(s) <= 0) + return AVERROR_INVALIDDATA; + + while (BS_FUNC(read_bit)(s)) { + BS_FUNC(skip)(s, 8); + if (BS_FUNC(left)(s) <= 0) + return AVERROR_INVALIDDATA; + } + + return 0; +} + +/** + * Return the LUT element for the given bitstream configuration. + */ +static inline int BS_FUNC(priv_set_idx)(BSCTX *bc, int code, int *n, + int *nb_bits, const VLCElem *table) +{ + unsigned idx; + + *nb_bits = -*n; + idx = BS_FUNC(peek)(bc, *nb_bits) + code; + *n = table[idx].len; + + return table[idx].sym; +} + +/** + * Parse a vlc code. + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be read to completely + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + * If the vlc code is invalid and max_depth=1, then no bits will be removed. + * If the vlc code is invalid and max_depth>1, then the number of bits removed + * is undefined. + */ +static inline int BS_FUNC(read_vlc)(BSCTX *bc, const VLCElem *table, + int bits, int max_depth) +{ + int nb_bits; + unsigned idx = BS_FUNC(peek)(bc, bits); + int code = table[idx].sym; + int n = table[idx].len; + + if (max_depth > 1 && n < 0) { + BS_FUNC(priv_skip_remaining)(bc, bits); + code = BS_FUNC(priv_set_idx)(bc, code, &n, &nb_bits, table); + if (max_depth > 2 && n < 0) { + BS_FUNC(priv_skip_remaining)(bc, nb_bits); + code = BS_FUNC(priv_set_idx)(bc, code, &n, &nb_bits, table); + } + } + BS_FUNC(priv_skip_remaining)(bc, n); + + return code; +} + +#undef BSCTX +#undef BS_FUNC +#undef BS_JOIN3 +#undef BS_JOIN +#undef BS_SUFFIX_UPPER +#undef BS_SUFFIX_LOWER diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bmpenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/bmpenc.c index abf644bd..3e3ca324 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/bmpenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bmpenc.c @@ -161,7 +161,7 @@ const FFCodec ff_bmp_encoder = { CODEC_LONG_NAME("BMP (Windows and OS/2 bitmap)"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_BMP, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = bmp_encode_init, FF_CODEC_ENCODE_CB(bmp_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/bonk.c b/arm/raspi/third_party/ffmpeg/libavcodec/bonk.c index 2b2e2024..061cc69a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/bonk.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/bonk.c @@ -101,6 +101,10 @@ static av_cold int bonk_init(AVCodecContext *avctx) s->samples_per_packet = AV_RL16(avctx->extradata + 15); if (!s->samples_per_packet) return AVERROR(EINVAL); + + if (s->down_sampling * s->samples_per_packet < s->n_taps) + return AVERROR_INVALIDDATA; + s->max_framesize = s->samples_per_packet * avctx->ch_layout.nb_channels * s->down_sampling * 16LL; if (s->max_framesize > (INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) / 8) return AVERROR_INVALIDDATA; @@ -217,6 +221,9 @@ static int intlist_read(BonkContext *s, int *buf, int entries, int base_2_part) level += 1 << low_bits; } + if (level > 1 << 16) + return AVERROR_INVALIDDATA; + if (x >= max_x) return AVERROR_INVALIDDATA; @@ -277,10 +284,10 @@ static int predictor_calc_error(int *k, int *state, int order, int error) return x; } -static void predictor_init_state(int *k, int *state, int order) +static void predictor_init_state(int *k, unsigned *state, int order) { for (int i = order - 2; i >= 0; i--) { - int x = state[i]; + unsigned x = state[i]; for (int j = 0, p = i + 1; p < order; j++, p++) { int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); @@ -330,7 +337,7 @@ static int bonk_decode(AVCodecContext *avctx, AVFrame *frame, skip_bits(gb, s->skip); if ((ret = intlist_read(s, s->k, s->n_taps, 0)) < 0) - return ret; + goto fail; for (int i = 0; i < s->n_taps; i++) s->k[i] *= s->quant[i]; @@ -345,7 +352,7 @@ static int bonk_decode(AVCodecContext *avctx, AVFrame *frame, predictor_init_state(s->k, state, s->n_taps); if ((ret = intlist_read(s, s->input_samples, samples_per_packet, 1)) < 0) - return ret; + goto fail; for (int i = 0; i < samples_per_packet; i++) { for (int j = 0; j < s->down_sampling - 1; j++) { @@ -353,7 +360,7 @@ static int bonk_decode(AVCodecContext *avctx, AVFrame *frame, sample++; } - sample[0] = predictor_calc_error(s->k, state, s->n_taps, s->input_samples[i] * quant); + sample[0] = predictor_calc_error(s->k, state, s->n_taps, s->input_samples[i] * (unsigned)quant); sample++; } @@ -390,6 +397,7 @@ static int bonk_decode(AVCodecContext *avctx, AVFrame *frame, n = get_bits_count(gb) / 8; if (n > buf_size) { +fail: s->bitstream_size = 0; s->bitstream_index = 0; return AVERROR_INVALIDDATA; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_av1_syntax_template.c b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_av1_syntax_template.c index d98d3d42..e95925a4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_av1_syntax_template.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_av1_syntax_template.c @@ -1862,11 +1862,8 @@ static int FUNC(metadata_hdr_mdcv)(CodedBitstreamContext *ctx, RWContext *rw, fb(16, white_point_chromaticity_x); fb(16, white_point_chromaticity_y); - fc(32, luminance_max, 1, MAX_UINT_BITS(32)); - // luminance_min must be lower than luminance_max. Convert luminance_max from - // 24.8 fixed point to 18.14 fixed point in order to compare them. - fc(32, luminance_min, 0, FFMIN(((uint64_t)current->luminance_max << 6) - 1, - MAX_UINT_BITS(32))); + fb(32, luminance_max); + fb(32, luminance_min); return 0; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_h2645.c b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_h2645.c index 4ee06003..80e48829 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_h2645.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_h2645.c @@ -1500,6 +1500,12 @@ static const SEIMessageTypeDescriptor cbs_sei_common_types[] = { sizeof(SEIRawAlternativeTransferCharacteristics), SEI_MESSAGE_RW(sei, alternative_transfer_characteristics), }, + { + SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT, + 1, 0, + sizeof(SEIRawAmbientViewingEnvironment), + SEI_MESSAGE_RW(sei, ambient_viewing_environment), + }, SEI_MESSAGE_TYPE_END, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei.h b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei.h index c7a7a95b..1c327a46 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei.h @@ -65,6 +65,12 @@ typedef struct SEIRawAlternativeTransferCharacteristics { uint8_t preferred_transfer_characteristics; } SEIRawAlternativeTransferCharacteristics; +typedef struct SEIRawAmbientViewingEnvironment { + uint32_t ambient_illuminance; + uint16_t ambient_light_x; + uint16_t ambient_light_y; +} SEIRawAmbientViewingEnvironment; + typedef struct SEIRawMessage { uint32_t payload_type; uint32_t payload_size; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei_syntax_template.c b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei_syntax_template.c index 0ef7b42e..6a7cc36d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei_syntax_template.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cbs_sei_syntax_template.c @@ -144,6 +144,23 @@ static int FUNC(alternative_transfer_characteristics) return 0; } +static int FUNC(ambient_viewing_environment) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawAmbientViewingEnvironment *current, + SEIMessageState *state) +{ + static const uint16_t max_ambient_light_value = 50000; + int err; + + HEADER("Ambient Viewing Environment"); + + u(32, ambient_illuminance, 1, MAX_UINT_BITS(32)); + u(16, ambient_light_x, 0, max_ambient_light_value); + u(16, ambient_light_y, 0, max_ambient_light_value); + + return 0; +} + static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, SEIRawMessage *current) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cfhdenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/cfhdenc.c index 0fca46ef..f4474384 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cfhdenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cfhdenc.c @@ -258,6 +258,11 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) if (ret < 0) return ret; + if (avctx->height < 4) { + av_log(avctx, AV_LOG_ERROR, "Height must be >= 4.\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->width & 15) { av_log(avctx, AV_LOG_ERROR, "Width must be multiple of 16.\n"); return AVERROR_INVALIDDATA; @@ -267,22 +272,21 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) for (int i = 0; i < s->planes; i++) { int w8, h8, w4, h4, w2, h2; - int width = i ? avctx->width >> s->chroma_h_shift : avctx->width; - int height = i ? FFALIGN(avctx->height >> s->chroma_v_shift, 8) : - FFALIGN(avctx->height >> s->chroma_v_shift, 8); - ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; + const int a_height = FFALIGN(avctx->height, 8); + int width = i ? AV_CEIL_RSHIFT(avctx->width, s->chroma_h_shift) : avctx->width; + int height = i ? a_height >> s->chroma_v_shift: a_height; - w8 = FFALIGN(width / 8, 8) + 64; - h8 = FFALIGN(height, 8) / 8; + w8 = width / 8 + 64; + h8 = height / 8; w4 = w8 * 2; h4 = h8 * 2; w2 = w4 * 2; h2 = h4 * 2; s->plane[i].dwt_buf = - av_calloc(height * stride, sizeof(*s->plane[i].dwt_buf)); + av_calloc(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_buf)); s->plane[i].dwt_tmp = - av_malloc_array(height * stride, sizeof(*s->plane[i].dwt_tmp)); + av_malloc_array(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_tmp)); if (!s->plane[i].dwt_buf || !s->plane[i].dwt_tmp) return AVERROR(ENOMEM); @@ -300,7 +304,7 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) for (int j = 0; j < DWT_LEVELS; j++) { for (int k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { s->plane[i].band[j][k].width = (width / 8) << j; - s->plane[i].band[j][k].height = (height / 8) << j; + s->plane[i].band[j][k].height = height >> (DWT_LEVELS - j); s->plane[i].band[j][k].a_width = w8 << j; s->plane[i].band[j][k].a_height = h8 << j; } @@ -433,6 +437,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int ret; for (int plane = 0; plane < s->planes; plane++) { + const int h_shift = plane ? s->chroma_h_shift : 0; int width = s->plane[plane].band[2][0].width; int a_width = s->plane[plane].band[2][0].a_width; int height = s->plane[plane].band[2][0].height; @@ -453,7 +458,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, dsp->horiz_filter(input, low, high, in_stride, a_width, a_width, - width * 2, height * 2); + avctx->width >> h_shift, avctx->height); input = s->plane[plane].l_h[7]; low = s->plane[plane].subband[7]; @@ -548,7 +553,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, width, height * 2); } - ret = ff_alloc_packet(avctx, pkt, 64LL + s->planes * (2LL * avctx->width * avctx->height + 1000LL)); + ret = ff_alloc_packet(avctx, pkt, 256LL + s->planes * (2LL * avctx->width * (avctx->height + 15) + 2048LL)); if (ret < 0) return ret; @@ -591,6 +596,9 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_put_be16(pby, avctx->width); bytestream2_put_be16(pby, ImageHeight); + bytestream2_put_be16(pby, FFALIGN(avctx->height, 8)); + + bytestream2_put_be16(pby, -DisplayHeight); bytestream2_put_be16(pby, avctx->height); bytestream2_put_be16(pby, -FrameNumber); @@ -851,7 +859,8 @@ const FFCodec ff_cfhd_encoder = { CODEC_LONG_NAME("GoPro CineForm HD"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_CFHD, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(CFHDEncContext), .p.priv_class = &cfhd_class, .init = cfhd_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cinepakenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/cinepakenc.c index c05449e8..f15325ad 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cinepakenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cinepakenc.c @@ -1219,7 +1219,7 @@ const FFCodec ff_cinepak_encoder = { CODEC_LONG_NAME("Cinepak"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_CINEPAK, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(CinepakEncContext), .init = cinepak_encode_init, FF_CODEC_ENCODE_CB(cinepak_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cljrenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/cljrenc.c index c1f8810a..d6589315 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cljrenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cljrenc.c @@ -113,7 +113,7 @@ const FFCodec ff_cljr_encoder = { CODEC_LONG_NAME("Cirrus Logic AccuPak"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_CLJR, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(CLJRContext), FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/cngenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/cngenc.c index ff40017f..596d6f8c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/cngenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/cngenc.c @@ -101,7 +101,7 @@ const FFCodec ff_comfortnoise_encoder = { CODEC_LONG_NAME("RFC 3389 comfort noise generator"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_COMFORT_NOISE, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(CNGContext), .init = cng_encode_init, FF_CODEC_ENCODE_CB(cng_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/codec_desc.c b/arm/raspi/third_party/ffmpeg/libavcodec/codec_desc.c index 24a0433d..8ab228d8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/codec_desc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/codec_desc.c @@ -2536,6 +2536,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Replay"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ADPCM_XMD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_xmd", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Konami XMD"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, /* AMR */ { @@ -2619,6 +2626,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("DPCM Xilam DERF"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_WADY_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wady_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Marble WADY"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CBD2_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "cbd2_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Cuberoot-Delta-Exact"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, /* audio codecs */ { @@ -3604,6 +3625,18 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_VNULL, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vnull", + .long_name = NULL_IF_CONFIG_SMALL("Null video codec"), + }, + { + .id = AV_CODEC_ID_ANULL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "anull", + .long_name = NULL_IF_CONFIG_SMALL("Null audio codec"), + }, }; static int descriptor_compare(const void *key, const void *member) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/codec_id.h b/arm/raspi/third_party/ffmpeg/libavcodec/codec_id.h index f436a2b6..0c574c96 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/codec_id.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/codec_id.h @@ -413,6 +413,7 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_IMA_CUNNING, AV_CODEC_ID_ADPCM_IMA_MOFLEX, AV_CODEC_ID_ADPCM_IMA_ACORN, + AV_CODEC_ID_ADPCM_XMD, /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, @@ -430,6 +431,8 @@ enum AVCodecID { AV_CODEC_ID_SDX2_DPCM, AV_CODEC_ID_GREMLIN_DPCM, AV_CODEC_ID_DERF_DPCM, + AV_CODEC_ID_WADY_DPCM, + AV_CODEC_ID_CBD2_DPCM, /* audio codecs */ AV_CODEC_ID_MP2 = 0x15000, @@ -587,6 +590,16 @@ enum AVCodecID { * stream (only used by libavformat) */ AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information. AV_CODEC_ID_WRAPPED_AVFRAME = 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket + /** + * Dummy null video codec, useful mainly for development and debugging. + * Null encoder/decoder discard all input and never return any output. + */ + AV_CODEC_ID_VNULL, + /** + * Dummy null audio codec, useful mainly for development and debugging. + * Null encoder/decoder discard all input and never return any output. + */ + AV_CODEC_ID_ANULL, }; /** diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/codec_internal.h b/arm/raspi/third_party/ffmpeg/libavcodec/codec_internal.h index e3b77e6d..130a7dc3 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/codec_internal.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/codec_internal.h @@ -80,6 +80,14 @@ * Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE). */ #define FF_CODEC_CAP_ICC_PROFILES (1 << 9) +/** + * The encoder has AV_CODEC_CAP_DELAY set, but does not actually have delay - it + * only wants to be flushed at the end to update some context variables (e.g. + * 2pass stats) or produce a trailing packet. Besides that it immediately + * produces exactly one output packet per each input frame, just as no-delay + * encoders do. + */ +#define FF_CODEC_CAP_EOF_FLUSH (1 << 10) /** * FFCodec.codec_tags termination value diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dcaenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/dcaenc.c index 4cab54ef..c731d793 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dcaenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dcaenc.c @@ -1315,7 +1315,8 @@ const FFCodec ff_dca_encoder = { CODEC_LONG_NAME("DCA (DTS Coherent Acoustics)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_DTS, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(DCAEncContext), .init = encode_init, .close = encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/decode.c b/arm/raspi/third_party/ffmpeg/libavcodec/decode.c index 6be2d3d6..0abc8873 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/decode.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/decode.c @@ -132,38 +132,16 @@ fail2: return 0; } -#define IS_EMPTY(pkt) (!(pkt)->data) - -static int copy_packet_props(AVPacket *dst, const AVPacket *src) -{ - int ret = av_packet_copy_props(dst, src); - if (ret < 0) - return ret; - - dst->size = src->size; // HACK: Needed for ff_decode_frame_props(). - dst->data = (void*)1; // HACK: Needed for IS_EMPTY(). - - return 0; -} - static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) { - AVPacket tmp = { 0 }; int ret = 0; - if (IS_EMPTY(avci->last_pkt_props)) { - if (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) < 0) - return copy_packet_props(avci->last_pkt_props, pkt); + av_packet_unref(avci->last_pkt_props); + if (pkt) { + ret = av_packet_copy_props(avci->last_pkt_props, pkt); + if (!ret) + avci->last_pkt_props->opaque = (void *)(intptr_t)pkt->size; // Needed for ff_decode_frame_props(). } - - ret = copy_packet_props(&tmp, pkt); - if (ret < 0) - return ret; - - ret = av_fifo_write(avci->pkt_props, &tmp, 1); - if (ret < 0) - av_packet_unref(&tmp); - return ret; } @@ -483,7 +461,6 @@ FF_ENABLE_DEPRECATION_WARNINGS if (ret >= pkt->size || ret < 0) { av_packet_unref(pkt); - av_packet_unref(avci->last_pkt_props); } else { int consumed = ret; @@ -492,7 +469,8 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->pts = AV_NOPTS_VALUE; pkt->dts = AV_NOPTS_VALUE; if (!(codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { - avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. + // See extract_packet_props() comment. + avci->last_pkt_props->opaque = (void *)((intptr_t)avci->last_pkt_props->opaque - consumed); avci->last_pkt_props->pts = AV_NOPTS_VALUE; avci->last_pkt_props->dts = AV_NOPTS_VALUE; } @@ -578,8 +556,6 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) { ret = codec->cb.receive_frame(avctx, frame); - if (ret != AVERROR(EAGAIN)) - av_packet_unref(avci->last_pkt_props); } else ret = decode_simple_receive_frame(avctx, frame); @@ -593,12 +569,6 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) return ok; } - if (!(codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS) && - IS_EMPTY(avci->last_pkt_props)) { - // May fail if the FIFO is empty. - av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1); - } - if (!ret) { frame->best_effort_timestamp = guess_correct_pts(avctx, frame->pts, @@ -697,6 +667,33 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) AV_FRAME_CROP_UNALIGNED : 0); } +// make sure frames returned to the caller are valid +static int frame_validate(AVCodecContext *avctx, AVFrame *frame) +{ + if (!frame->buf[0] || frame->format < 0) + goto fail; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (frame->width <= 0 || frame->height <= 0) + goto fail; + break; + case AVMEDIA_TYPE_AUDIO: + if (!av_channel_layout_check(&frame->ch_layout) || + frame->sample_rate <= 0) + goto fail; + + break; + default: av_assert0(0); + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "An invalid frame was output by a decoder. " + "This is a bug, please report it.\n"); + return AVERROR_BUG; +} + int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame) { AVCodecInternal *avci = avctx->internal; @@ -713,12 +710,14 @@ int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame) return ret; } + ret = frame_validate(avctx, frame); + if (ret < 0) + goto fail; + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { ret = apply_cropping(avctx, frame); - if (ret < 0) { - av_frame_unref(frame); - return ret; - } + if (ret < 0) + goto fail; } avctx->frame_number++; @@ -736,10 +735,8 @@ int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame) avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate : avctx->sample_rate; ret = av_channel_layout_copy(&avci->initial_ch_layout, &frame->ch_layout); - if (ret < 0) { - av_frame_unref(frame); - return ret; - } + if (ret < 0) + goto fail; break; } } @@ -765,12 +762,15 @@ int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame) " drop count: %d \n", avctx->frame_number, frame->pts, avci->changed_frames_dropped); - av_frame_unref(frame); - return AVERROR_INPUT_CHANGED; + ret = AVERROR_INPUT_CHANGED; + goto fail; } } } return 0; +fail: + av_frame_unref(frame); + return ret; } static void get_subtitle_defaults(AVSubtitle *sub) @@ -1291,9 +1291,8 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) return av_packet_unpack_dictionary(side_metadata, size, frame_md); } -int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt) { - AVPacket *pkt = avctx->internal->last_pkt_props; static const struct { enum AVPacketSideDataType packet; enum AVFrameSideDataType frame; @@ -1311,32 +1310,44 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_DYNAMIC_HDR10_PLUS, AV_FRAME_DATA_DYNAMIC_HDR_PLUS }, }; + frame->pts = pkt->pts; + frame->pkt_pos = pkt->pos; + frame->duration = pkt->duration; + frame->pkt_size = pkt->size; + + for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + size_t size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); + + memcpy(frame_sd->data, packet_sd, size); + } + } + add_metadata_from_side_data(pkt, frame); + + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + } + + return 0; +} + +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +{ + const AVPacket *pkt = avctx->internal->last_pkt_props; + if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { - frame->pts = pkt->pts; - frame->pkt_pos = pkt->pos; - frame->duration = pkt->duration; - frame->pkt_size = pkt->size; - - for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) { - size_t size; - uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); - if (packet_sd) { - AVFrameSideData *frame_sd = av_frame_new_side_data(frame, - sd[i].frame, - size); - if (!frame_sd) - return AVERROR(ENOMEM); - - memcpy(frame_sd->data, packet_sd, size); - } - } - add_metadata_from_side_data(pkt, frame); - - if (pkt->flags & AV_PKT_FLAG_DISCARD) { - frame->flags |= AV_FRAME_FLAG_DISCARD; - } else { - frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); - } + int ret = ff_decode_frame_props_from_pkt(frame, pkt); + if (ret < 0) + return ret; + frame->pkt_size = (int)(intptr_t)pkt->opaque; } frame->reordered_opaque = avctx->reordered_opaque; @@ -1651,9 +1662,7 @@ FF_ENABLE_DEPRECATION_WARNINGS avci->in_pkt = av_packet_alloc(); avci->last_pkt_props = av_packet_alloc(); - avci->pkt_props = av_fifo_alloc2(1, sizeof(*avci->last_pkt_props), - AV_FIFO_FLAG_AUTO_GROW); - if (!avci->in_pkt || !avci->last_pkt_props || !avci->pkt_props) + if (!avci->in_pkt || !avci->last_pkt_props) return AVERROR(ENOMEM); ret = decode_bsfs_init(avctx); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/decode.h b/arm/raspi/third_party/ffmpeg/libavcodec/decode.h index 5d95369b..906122b4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/decode.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/decode.h @@ -69,6 +69,11 @@ int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame); */ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); +/** + * Set various frame properties from the provided packet. + */ +int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt); + /** * Set various frame properties from the codec context / packet data. */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dfpwmenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/dfpwmenc.c index 7f465a44..5318b04a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dfpwmenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dfpwmenc.c @@ -116,5 +116,6 @@ const FFCodec ff_dfpwm_encoder = { .init = dfpwm_enc_init, FF_CODEC_ENCODE_CB(dfpwm_enc_frame), .p.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE}, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dnxhdenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/dnxhdenc.c index b7dc54f8..176bf972 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dnxhdenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dnxhdenc.c @@ -1359,7 +1359,7 @@ const FFCodec ff_dnxhd_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_DNXHD, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | - AV_CODEC_CAP_SLICE_THREADS, + AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(DNXHDEncContext), .init = dnxhd_encode_init, FF_CODEC_ENCODE_CB(dnxhd_encode_picture), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dpcm.c b/arm/raspi/third_party/ffmpeg/libavcodec/dpcm.c index 2425f84e..6ea9e2c0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dpcm.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dpcm.c @@ -45,7 +45,8 @@ typedef struct DPCMContext { int16_t array[256]; - int sample[2]; ///< previous sample (for SOL_DPCM) + int sample[2]; ///< previous sample (for SOL_DPCM and WADY_DPCM) + int scale; ///< scale for WADY_DPCM const int8_t *sol_table; ///< delta table for SOL_DPCM } DPCMContext; @@ -126,6 +127,24 @@ static const int16_t sol_table_16[128] = { 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 }; +static const int16_t wady_table[128] = { + 0, 2, 4, 6, 8, 10, 12, 15, + 18, 21, 24, 28, 32, 36, 40, 44, + 49, 54, 59, 64, 70, 76, 82, 88, + 95, 102, 109, 116, 124, 132, 140, 148, + 160, 170, 180, 190, 200, 210, 220, 230, + 240, 255, 270, 285, 300, 320, 340, 360, + 380, 400, 425, 450, 475, 500, 525, 550, + 580, 610, 650, 700, 750, 800, 900, 1000, + -0, -2, -4, -6, -8, -10, -12, -15, + -18, -21, -24, -28, -32, -36, -40, -44, + -49, -54, -59, -64, -70, -76, -82, -88, + -95, -102,-109,-116,-124,-132,-140,-148, + -160,-170,-180,-190,-200,-210,-220,-230, + -240,-255,-270,-285,-300,-320,-340,-360, + -380,-400,-425,-450,-475,-500,-525,-550, + -580,-610,-650,-700,-750,-800,-900,-1000, +}; static av_cold int dpcm_decode_init(AVCodecContext *avctx) { @@ -139,7 +158,7 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) s->sample[0] = s->sample[1] = 0; - switch(avctx->codec->id) { + switch (avctx->codec->id) { case AV_CODEC_ID_ROQ_DPCM: /* initialize square table */ @@ -175,6 +194,13 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) } break; + case AV_CODEC_ID_CBD2_DPCM: + for (i = -128; i < 128; i++) { + int16_t cube = (i * i * i) / 64; + s->array[i+128] = cube; + } + break; + case AV_CODEC_ID_GREMLIN_DPCM: { int delta = 0; int code = 64; @@ -193,6 +219,10 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) } break; + case AV_CODEC_ID_WADY_DPCM: + s->scale = (avctx->extradata && avctx->extradata_size > 0) ? avctx->extradata[0] : 1; + break; + default: break; } @@ -239,8 +269,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, else out = buf_size; break; + case AV_CODEC_ID_WADY_DPCM: case AV_CODEC_ID_DERF_DPCM: case AV_CODEC_ID_GREMLIN_DPCM: + case AV_CODEC_ID_CBD2_DPCM: case AV_CODEC_ID_SDX2_DPCM: out = buf_size; break; @@ -362,6 +394,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, } break; + case AV_CODEC_ID_CBD2_DPCM: case AV_CODEC_ID_SDX2_DPCM: while (output_samples < samples_end) { int8_t n = bytestream2_get_byteu(&gb); @@ -401,6 +434,22 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, } } break; + + case AV_CODEC_ID_WADY_DPCM: { + int idx = 0; + + while (output_samples < samples_end) { + const uint8_t n = bytestream2_get_byteu(&gb); + + if (n & 0x80) + s->sample[idx] = sign_extend((n & 0x7f) << 9, 16); + else + s->sample[idx] += s->scale * wady_table[n & 0x7f]; + *output_samples++ = av_clip_int16(s->sample[idx]); + idx ^= stereo; + } + } + break; } *got_frame_ptr = 1; @@ -408,6 +457,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, return avpkt->size; } +static void dpcm_flush(AVCodecContext *avctx) +{ + DPCMContext *s = avctx->priv_data; + + s->sample[0] = s->sample[1] = 0; +} + #define DPCM_DECODER(id_, name_, long_name_) \ const FFCodec ff_ ## name_ ## _decoder = { \ .p.name = #name_, \ @@ -417,9 +473,11 @@ const FFCodec ff_ ## name_ ## _decoder = { \ .p.capabilities = AV_CODEC_CAP_DR1, \ .priv_data_size = sizeof(DPCMContext), \ .init = dpcm_decode_init, \ + .flush = dpcm_flush, \ FF_CODEC_DECODE_CB(dpcm_decode_frame), \ } +DPCM_DECODER(AV_CODEC_ID_CBD2_DPCM, cbd2_dpcm, "DPCM Cuberoot-Delta-Exact"); DPCM_DECODER(AV_CODEC_ID_DERF_DPCM, derf_dpcm, "DPCM Xilam DERF"); DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM, gremlin_dpcm, "DPCM Gremlin"); DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); @@ -427,3 +485,4 @@ DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact"); DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); +DPCM_DECODER(AV_CODEC_ID_WADY_DPCM, wady_dpcm, "DPCM Marble WADY"); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dts2pts_bsf.c b/arm/raspi/third_party/ffmpeg/libavcodec/dts2pts_bsf.c index 8142562d..263514fa 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dts2pts_bsf.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dts2pts_bsf.c @@ -90,9 +90,11 @@ static int cmp_insert(const void *key, const void *node) static int cmp_find(const void *key, const void *node) { - int ret = ((const DTS2PTSFrame *)key)->poc - ((const DTS2PTSNode *) node)->poc; + const DTS2PTSFrame * key1 = key; + const DTS2PTSNode *node1 = node; + int ret = FFDIFFSIGN(key1->poc, node1->poc); if (!ret) - ret = ((const DTS2PTSFrame *)key)->gop - ((const DTS2PTSNode *) node)->gop; + ret = key1->gop - node1->gop; return ret; } @@ -301,15 +303,15 @@ static int h264_filter(AVBSFContext *ctx) if (output_picture_number != h264->last_poc) { if (h264->last_poc != INT_MIN) { - int diff = FFABS(h264->last_poc - output_picture_number); + int64_t diff = FFABS(h264->last_poc - (int64_t)output_picture_number); if ((output_picture_number < 0) && !h264->last_poc) h264->poc_diff = 0; - else if (FFABS(output_picture_number) < h264->poc_diff) { + else if (FFABS((int64_t)output_picture_number) < h264->poc_diff) { diff = FFABS(output_picture_number); h264->poc_diff = 0; } - if (!h264->poc_diff || (h264->poc_diff > diff)) { + if ((!h264->poc_diff || (h264->poc_diff > diff)) && diff <= INT_MAX) { h264->poc_diff = diff; if (h264->poc_diff == 1 && h264->sps.frame_mbs_only_flag) { av_tree_enumerate(s->root, &h264->poc_diff, NULL, dec_poc); @@ -461,9 +463,10 @@ static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out) poc_node = av_tree_find(s->root, &dup, cmp_find, NULL); } } - } else { + } else if (s->eof && frame.poc > INT_MIN) { DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc - 1, frame.poc_diff, frame.gop }; - if (s->eof && (poc_node = av_tree_find(s->root, &dup, cmp_find, NULL)) && poc_node->poc == dup.poc) { + poc_node = av_tree_find(s->root, &dup, cmp_find, NULL); + if (poc_node && poc_node->poc == dup.poc) { out->pts = poc_node->dts; if (out->pts != AV_NOPTS_VALUE) out->pts += poc_node->duration; @@ -480,7 +483,8 @@ static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out) poc_node->poc, poc_node->gop, poc_node->dts, poc_node->duration); } else av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc); - } + } else + av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc); av_log(ctx, AV_LOG_DEBUG, "Returning frame for POC %d, GOP %d, dts %"PRId64", pts %"PRId64"\n", frame.poc, frame.gop, out->dts, out->pts); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dvdsubenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/dvdsubenc.c index 0874aaa0..d272b576 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dvdsubenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dvdsubenc.c @@ -379,7 +379,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, if (x2 > avctx->width || y2 > avctx->height) { av_log(avctx, AV_LOG_ERROR, "canvas_size(%d:%d) is too small(%d:%d) for render\n", avctx->width, avctx->height, x2, y2); - ret = AVERROR(EINVAL);; + ret = AVERROR(EINVAL); goto fail; } *q++ = 0x05; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/dvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/dvenc.c index 4c747ef7..8f5fa050 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/dvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/dvenc.c @@ -1239,7 +1239,8 @@ const FFCodec ff_dvvideo_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_DVVIDEO, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | - AV_CODEC_CAP_SLICE_THREADS, + AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(DVEncContext), .init = dvvideo_encode_init, FF_CODEC_ENCODE_CB(dvvideo_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/eac3dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/eac3dec.c index d360b026..deca51dd 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/eac3dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/eac3dec.c @@ -138,9 +138,11 @@ static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) // spx_noise_blend and spx_signal_blend are both FP.23 nscale *= 1.0 / (1<<23); sscale *= 1.0 / (1<<23); + if (nscale < -1.0) + nscale = -1.0; #endif for (i = 0; i < s->spx_band_sizes[bnd]; i++) { - float noise = nscale * (int32_t)av_lfg_get(&s->dith_state); + UINTFLOAT noise = (INTFLOAT)(nscale * (int32_t)av_lfg_get(&s->dith_state)); s->transform_coeffs[ch][bin] *= sscale; s->transform_coeffs[ch][bin++] += noise; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/eac3enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/eac3enc.c index 78d4f139..ab9eda26 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/eac3enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/eac3enc.c @@ -254,7 +254,7 @@ const FFCodec ff_eac3_encoder = { CODEC_LONG_NAME("ATSC A/52 E-AC-3"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_EAC3, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(AC3EncodeContext), .init = ff_ac3_float_encode_init, FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/eatgq.c b/arm/raspi/third_party/ffmpeg/libavcodec/eatgq.c index 89e9f208..01e1acd4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/eatgq.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/eatgq.c @@ -56,7 +56,7 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) return 0; } -static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) +static int tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) { const uint8_t *scantable = ff_zigzag_direct; int i, j, value; @@ -64,6 +64,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb for (i = 1; i < 64;) { switch (show_bits(gb, 3)) { case 4: + if (i >= 63) + return AVERROR_INVALIDDATA; block[scantable[i++]] = 0; case 0: block[scantable[i++]] = 0; @@ -73,6 +75,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb case 1: skip_bits(gb, 2); value = get_bits(gb, 6); + if (value > 64 - i) + return AVERROR_INVALIDDATA; for (j = 0; j < value; j++) block[scantable[i++]] = 0; break; @@ -100,6 +104,7 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb } } block[0] += 128 << 4; + return 0; } static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, @@ -160,8 +165,11 @@ static int tgq_decode_mb(TgqContext *s, GetByteContext *gbyte, if (ret < 0) return ret; - for (i = 0; i < 6; i++) - tgq_decode_block(s, s->block[i], &gb); + for (i = 0; i < 6; i++) { + int ret = tgq_decode_block(s, s->block[i], &gb); + if (ret < 0) + return ret; + } tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(gbyte, mode); } else { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/encode.c b/arm/raspi/third_party/ffmpeg/libavcodec/encode.c index fbe2c97c..c92beaf8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/encode.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/encode.c @@ -190,6 +190,21 @@ int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame) return 0; } +int ff_encode_reordered_opaque(AVCodecContext *avctx, + AVPacket *pkt, const AVFrame *frame) +{ + avctx->reordered_opaque = frame->reordered_opaque; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + int ret = av_buffer_replace(&pkt->opaque_ref, frame->opaque_ref); + if (ret < 0) + return ret; + pkt->opaque = frame->opaque; + } + + return 0; +} + int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, AVFrame *frame, int *got_packet) { @@ -211,21 +226,30 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, // set the timestamps for the simple no-delay case // encoders with delay have to set the timestamps themselves - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || + (frame && (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH))) { if (avpkt->pts == AV_NOPTS_VALUE) avpkt->pts = frame->pts; - if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { - if (!avpkt->duration) + if (!avpkt->duration) { + if (frame->duration) + avpkt->duration = frame->duration; + else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); + } } + + ret = ff_encode_reordered_opaque(avctx, avpkt, frame); + if (ret < 0) + goto unref; } // dts equals pts unless there is reordering // there can be no reordering if there is no encoder delay if (!(avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) || - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || + (codec->caps_internal & FF_CODEC_CAP_EOF_FLUSH)) avpkt->dts = avpkt->pts; } else { unref: @@ -442,6 +466,13 @@ FF_ENABLE_DEPRECATION_WARNINGS return ret; } + // unset frame duration unless AV_CODEC_FLAG_FRAME_DURATION is set, + // since otherwise we cannot be sure that whatever value it has is in the + // right timebase, so we would produce an incorrect value, which is worse + // than none at all + if (!(avctx->flags & AV_CODEC_FLAG_FRAME_DURATION)) + dst->duration = 0; + return 0; } @@ -634,6 +665,13 @@ int ff_encode_preinit(AVCodecContext *avctx) return AVERROR(EINVAL); } + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE && + !(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE)) { + av_log(avctx, AV_LOG_ERROR, "The copy_opaque flag is set, but the " + "encoder does not support it.\n"); + return AVERROR(EINVAL); + } + switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: ret = encode_preinit_video(avctx); break; case AVMEDIA_TYPE_AUDIO: ret = encode_preinit_audio(avctx); break; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/encode.h b/arm/raspi/third_party/ffmpeg/libavcodec/encode.h index 81d18d6e..26a33040 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/encode.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/encode.h @@ -69,6 +69,12 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame); */ int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size); +/** + * Propagate user opaque values from the frame to avctx/pkt as needed. + */ +int ff_encode_reordered_opaque(AVCodecContext *avctx, + AVPacket *pkt, const AVFrame *frame); + /* * Perform encoder initialization and validation. * Called when opening the encoder, before the FFCodec.init() call. diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/exrenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/exrenc.c index 10ed8768..36327f49 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/exrenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/exrenc.c @@ -547,7 +547,8 @@ const FFCodec ff_exr_encoder = { .p.priv_class = &exr_class, .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_EXR, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), .close = encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1.h b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1.h index 005f3087..04869da5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1.h @@ -85,7 +85,7 @@ typedef struct FFV1Context { int chroma_h_shift, chroma_v_shift; int transparency; int flags; - int picture_number; + int64_t picture_number; int key_frame; ThreadFrame picture, last_picture; struct FFV1Context *fsrc; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1dec.c index b1cfc4bf..d74786ce 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1dec.c @@ -168,24 +168,31 @@ static int decode_slice_header(const FFV1Context *f, FFV1Context *fs) RangeCoder *c = &fs->c; uint8_t state[CONTEXT_SIZE]; unsigned ps, i, context_count; + int sx, sy, sw, sh; + memset(state, 128, sizeof(state)); + sx = get_symbol(c, state, 0); + sy = get_symbol(c, state, 0); + sw = get_symbol(c, state, 0) + 1U; + sh = get_symbol(c, state, 0) + 1U; av_assert0(f->version > 2); - fs->slice_x = get_symbol(c, state, 0) * f->width ; - fs->slice_y = get_symbol(c, state, 0) * f->height; - fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x; - fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y; - fs->slice_x /= f->num_h_slices; - fs->slice_y /= f->num_v_slices; - fs->slice_width = fs->slice_width /f->num_h_slices - fs->slice_x; - fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y; - if ((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height) - return -1; - if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width - || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height) - return -1; + if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) + return AVERROR_INVALIDDATA; + if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) + return AVERROR_INVALIDDATA; + + fs->slice_x = sx * (int64_t)f->width / f->num_h_slices; + fs->slice_y = sy * (int64_t)f->height / f->num_v_slices; + fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x; + fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y; + + av_assert0((unsigned)fs->slice_width <= f->width && + (unsigned)fs->slice_height <= f->height); + av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width + && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height); if (fs->ac == AC_GOLOMB_RICE && fs->slice_width >= (1<<23)) return AVERROR_INVALIDDATA; @@ -770,21 +777,25 @@ static int read_header(FFV1Context *f) fs->slice_damaged = 0; if (f->version == 2) { - fs->slice_x = get_symbol(c, state, 0) * f->width ; - fs->slice_y = get_symbol(c, state, 0) * f->height; - fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x; - fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y; + int sx = get_symbol(c, state, 0); + int sy = get_symbol(c, state, 0); + int sw = get_symbol(c, state, 0) + 1U; + int sh = get_symbol(c, state, 0) + 1U; - fs->slice_x /= f->num_h_slices; - fs->slice_y /= f->num_v_slices; - fs->slice_width = fs->slice_width / f->num_h_slices - fs->slice_x; - fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y; - if ((unsigned)fs->slice_width > f->width || - (unsigned)fs->slice_height > f->height) + if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) return AVERROR_INVALIDDATA; - if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width - || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height) + if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) return AVERROR_INVALIDDATA; + + fs->slice_x = sx * (int64_t)f->width / f->num_h_slices; + fs->slice_y = sy * (int64_t)f->height / f->num_v_slices; + fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x; + fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y; + + av_assert0((unsigned)fs->slice_width <= f->width && + (unsigned)fs->slice_height <= f->height); + av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width + && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height); } for (i = 0; i < f->plane_count; i++) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1enc.c index 0237ac48..fb12776c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ffv1enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ffv1enc.c @@ -1231,8 +1231,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, f->picture_number++; pkt->size = buf_p - pkt->data; - pkt->pts = - pkt->dts = pict->pts; pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame; *got_packet = 1; @@ -1272,7 +1270,8 @@ const FFCodec ff_ffv1_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_FFV1, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | - AV_CODEC_CAP_SLICE_THREADS, + AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(FFV1Context), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), @@ -1301,5 +1300,5 @@ const FFCodec ff_ffv1_encoder = { }, .p.priv_class = &ffv1_class, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/fitsenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/fitsenc.c index ac910499..12952278 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/fitsenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/fitsenc.c @@ -114,7 +114,7 @@ const FFCodec ff_fits_encoder = { CODEC_LONG_NAME("Flexible Image Transport System"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_FITS, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(fits_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE, AV_PIX_FMT_GBRP16BE, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flac.c b/arm/raspi/third_party/ffmpeg/libavcodec/flac.c index 352d663c..174b4801 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flac.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flac.c @@ -28,7 +28,7 @@ #include "flacdata.h" #include "flac_parse.h" -static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; +static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 32 }; static const AVChannelLayout flac_channel_layouts[8] = { AV_CHANNEL_LAYOUT_MONO, @@ -82,7 +82,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, /* bits per sample */ bps_code = get_bits(gb, 3); - if (bps_code == 3 || bps_code == 7) { + if (bps_code == 3) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sample size code (%d)\n", bps_code); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flacdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/flacdec.c index 5b8547a9..cc778a8d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flacdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flacdec.c @@ -64,6 +64,9 @@ typedef struct FLACContext { int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples uint8_t *decoded_buffer; unsigned int decoded_buffer_size; + int64_t *decoded_33bps; ///< decoded samples for a 33 bps subframe + uint8_t *decoded_buffer_33bps; + unsigned int decoded_buffer_size_33bps; int buggy_lpc; ///< use workaround for old lavc encoded files FLACDSPContext dsp; @@ -154,6 +157,24 @@ static int allocate_buffers(FLACContext *s) s->stream_info.channels, s->stream_info.max_blocksize, AV_SAMPLE_FMT_S32P, 0); + if (ret >= 0 && s->stream_info.bps == 32 && s->stream_info.channels == 2) { + buf_size = av_samples_get_buffer_size(NULL, 1, + s->stream_info.max_blocksize, + AV_SAMPLE_FMT_S64P, 0); + if (buf_size < 0) + return buf_size; + + av_fast_malloc(&s->decoded_buffer_33bps, &s->decoded_buffer_size_33bps, buf_size); + if (!s->decoded_buffer_33bps) + return AVERROR(ENOMEM); + + ret = av_samples_fill_arrays((uint8_t **)&s->decoded_33bps, NULL, + s->decoded_buffer_33bps, + 1, + s->stream_info.max_blocksize, + AV_SAMPLE_FMT_S64P, 0); + + } return ret < 0 ? ret : 0; } @@ -331,6 +352,62 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } +#define DECODER_SUBFRAME_FIXED_WIDE(residual) { \ + const int blocksize = s->blocksize; \ + int ret; \ + \ + if ((ret = decode_residuals(s, residual, pred_order)) < 0) \ + return ret; \ + \ + switch (pred_order) { \ + case 0: \ + for (int i = pred_order; i < blocksize; i++) \ + decoded[i] = residual[i]; \ + break; \ + case 1: \ + for (int i = pred_order; i < blocksize; i++) \ + decoded[i] = (int64_t)residual[i] + (int64_t)decoded[i-1];\ + break; \ + case 2: \ + for (int i = pred_order; i < blocksize; i++) \ + decoded[i] = (int64_t)residual[i] + 2*(int64_t)decoded[i-1] - (int64_t)decoded[i-2]; \ + break; \ + case 3: \ + for (int i = pred_order; i < blocksize; i++) \ + decoded[i] = (int64_t)residual[i] + 3*(int64_t)decoded[i-1] - 3*(int64_t)decoded[i-2] + (int64_t)decoded[i-3]; \ + break; \ + case 4: \ + for (int i = pred_order; i < blocksize; i++) \ + decoded[i] = (int64_t)residual[i] + 4*(int64_t)decoded[i-1] - 6*(int64_t)decoded[i-2] + 4*(int64_t)decoded[i-3] - (int64_t)decoded[i-4]; \ + break; \ + default: \ + av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); \ + return AVERROR_INVALIDDATA; \ + } \ + return 0; \ +} + +static int decode_subframe_fixed_wide(FLACContext *s, int32_t *decoded, + int pred_order, int bps) +{ + /* warm up samples */ + for (int i = 0; i < pred_order; i++) { + decoded[i] = get_sbits_long(&s->gb, bps); + } + DECODER_SUBFRAME_FIXED_WIDE(decoded); +} + + +static int decode_subframe_fixed_33bps(FLACContext *s, int64_t *decoded, + int32_t *residual, int pred_order) +{ + /* warm up samples */ \ + for (int i = 0; i < pred_order; i++) { \ + decoded[i] = get_sbits64(&s->gb, 33); \ + } \ + DECODER_SUBFRAME_FIXED_WIDE(residual); +} + static void lpc_analyze_remodulate(SUINT32 *decoded, const int coeffs[32], int order, int qlevel, int len, int bps) { @@ -402,12 +479,53 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, return 0; } +static int decode_subframe_lpc_33bps(FLACContext *s, int64_t *decoded, + int32_t *residual, int pred_order) +{ + int i, j, ret; + int coeff_prec, qlevel; + int coeffs[32]; + + /* warm up samples */ + for (i = 0; i < pred_order; i++) { + decoded[i] = get_sbits64(&s->gb, 33); + } + + coeff_prec = get_bits(&s->gb, 4) + 1; + if (coeff_prec == 16) { + av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); + return AVERROR_INVALIDDATA; + } + qlevel = get_sbits(&s->gb, 5); + if (qlevel < 0) { + av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n", + qlevel); + return AVERROR_INVALIDDATA; + } + + for (i = 0; i < pred_order; i++) { + coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec); + } + + if ((ret = decode_residuals(s, residual, pred_order)) < 0) + return ret; + + for (i = pred_order; i < s->blocksize; i++, decoded++) { + int64_t sum = 0; + for (j = 0; j < pred_order; j++) + sum += (int64_t)coeffs[j] * decoded[j]; + decoded[j] = residual[i] + (sum >> qlevel); + } + + return 0; +} + static inline int decode_subframe(FLACContext *s, int channel) { int32_t *decoded = s->decoded[channel]; int type, wasted = 0; int bps = s->stream_info.bps; - int i, tmp, ret; + int i, ret; if (channel == 0) { if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) @@ -427,7 +545,7 @@ static inline int decode_subframe(FLACContext *s, int channel) int left = get_bits_left(&s->gb); if ( left <= 0 || (left < bps && !show_bits_long(&s->gb, left)) || - !show_bits_long(&s->gb, bps)) { + !show_bits_long(&s->gb, bps-1)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of wasted bits > available bits (%d) - left=%d\n", bps, left); @@ -436,34 +554,63 @@ static inline int decode_subframe(FLACContext *s, int channel) wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb)); bps -= wasted; } - if (bps > 32) { - avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32"); - return AVERROR_PATCHWELCOME; - } //FIXME use av_log2 for types if (type == 0) { - tmp = get_sbits_long(&s->gb, bps); - for (i = 0; i < s->blocksize; i++) - decoded[i] = tmp; + if (bps < 33) { + int32_t tmp = get_sbits_long(&s->gb, bps); + for (i = 0; i < s->blocksize; i++) + decoded[i] = tmp; + } else { + int64_t tmp = get_sbits64(&s->gb, 33); + for (i = 0; i < s->blocksize; i++) + s->decoded_33bps[i] = tmp; + } } else if (type == 1) { - for (i = 0; i < s->blocksize; i++) - decoded[i] = get_sbits_long(&s->gb, bps); + if (bps < 33) { + for (i = 0; i < s->blocksize; i++) + decoded[i] = get_sbits_long(&s->gb, bps); + } else { + for (i = 0; i < s->blocksize; i++) + s->decoded_33bps[i] = get_sbits64(&s->gb, 33); + } } else if ((type >= 8) && (type <= 12)) { - if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0) - return ret; + int order = type & ~0x8; + if (bps < 33) { + if (bps + order <= 32) { + if ((ret = decode_subframe_fixed(s, decoded, order, bps)) < 0) + return ret; + } else { + if ((ret = decode_subframe_fixed_wide(s, decoded, order, bps)) < 0) + return ret; + } + } else { + if ((ret = decode_subframe_fixed_33bps(s, s->decoded_33bps, decoded, order)) < 0) + return ret; + } } else if (type >= 32) { - if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) - return ret; + if (bps < 33) { + if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) + return ret; + } else { + if ((ret = decode_subframe_lpc_33bps(s, s->decoded_33bps, decoded, (type & ~0x20)+1)) < 0) + return ret; + } } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); return AVERROR_INVALIDDATA; } - if (wasted && wasted < 32) { - int i; - for (i = 0; i < s->blocksize; i++) - decoded[i] = (unsigned)decoded[i] << wasted; + if (wasted) { + if (wasted+bps == 33) { + int i; + for (i = 0; i < s->blocksize; i++) + s->decoded_33bps[i] = (uint64_t)decoded[i] << wasted; + } else if (wasted < 32) { + int i; + for (i = 0; i < s->blocksize; i++) + decoded[i] = (unsigned)decoded[i] << wasted; + } } return 0; @@ -554,6 +701,26 @@ static int decode_frame(FLACContext *s) return 0; } +static void decorrelate_33bps(int ch_mode, int32_t **decoded, int64_t *decoded_33bps, int len) +{ + int i; + if (ch_mode == FLAC_CHMODE_LEFT_SIDE ) { + for (i = 0; i < len; i++) + decoded[1][i] = decoded[0][i] - decoded_33bps[i]; + } else if (ch_mode == FLAC_CHMODE_RIGHT_SIDE ) { + for (i = 0; i < len; i++) + decoded[0][i] = decoded[1][i] + decoded_33bps[i]; + } else if (ch_mode == FLAC_CHMODE_MID_SIDE ) { + for (i = 0; i < len; i++) { + uint64_t a = decoded[0][i]; + int64_t b = decoded_33bps[i]; + a -= b >> 1; + decoded[0][i] = (a + b); + decoded[1][i] = a; + } + } +} + static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { @@ -612,9 +779,15 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame, if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) return ret; - s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, - s->stream_info.channels, - s->blocksize, s->sample_shift); + if (s->stream_info.bps == 32 && s->ch_mode > 0) { + decorrelate_33bps(s->ch_mode, s->decoded, s->decoded_33bps, s->blocksize); + s->dsp.decorrelate[0](frame->data, s->decoded, s->stream_info.channels, + s->blocksize, s->sample_shift); + } else { + s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, + s->stream_info.channels, + s->blocksize, s->sample_shift); + } if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); @@ -635,6 +808,7 @@ static av_cold int flac_decode_close(AVCodecContext *avctx) FLACContext *s = avctx->priv_data; av_freep(&s->decoded_buffer); + av_freep(&s->decoded_buffer_33bps); return 0; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flacenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/flacenc.c index bca71b37..a449b732 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flacenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flacenc.c @@ -31,7 +31,6 @@ #include "codec_internal.h" #include "encode.h" #include "put_bits.h" -#include "put_golomb.h" #include "lpc.h" #include "flac.h" #include "flacdata.h" @@ -95,6 +94,7 @@ typedef struct FlacSubframe { typedef struct FlacFrame { FlacSubframe subframes[FLAC_MAX_CHANNELS]; + int64_t samples_33bps[FLAC_MAX_BLOCKSIZE]; int blocksize; int bs_code[2]; uint8_t crc8; @@ -282,10 +282,22 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) s->bps_code = 4; break; case AV_SAMPLE_FMT_S32: - if (avctx->bits_per_raw_sample != 24) - av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n"); - avctx->bits_per_raw_sample = 24; - s->bps_code = 6; + if (avctx->bits_per_raw_sample <= 24) { + if (avctx->bits_per_raw_sample < 24) + av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n"); + avctx->bits_per_raw_sample = 24; + s->bps_code = 6; + } else if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_WARNING, + "encoding as 24 bits-per-sample, more is considered " + "experimental. Add -strict experimental if you want " + "to encode more than 24 bits-per-sample\n"); + avctx->bits_per_raw_sample = 24; + s->bps_code = 6; + } else { + avctx->bits_per_raw_sample = 32; + s->bps_code = 7; + } break; } @@ -536,8 +548,7 @@ static uint64_t rice_count_exact(const int32_t *res, int n, int k) uint64_t count = 0; for (i = 0; i < n; i++) { - int32_t v = -2 * res[i] - 1; - v ^= v >> 31; + unsigned v = ((unsigned)(res[i]) << 1) ^ (res[i] >> 31); count += (v >> k) + 1 + k; } return count; @@ -716,8 +727,8 @@ static uint64_t calc_rice_params(RiceContext *rc, tmp_rc.coding_mode = rc->coding_mode; - for (i = 0; i < n; i++) - udata[i] = (2 * data[i]) ^ (data[i] >> 31); + for (i = pred_order; i < n; i++) + udata[i] = ((unsigned)(data[i]) << 1) ^ (data[i] >> 31); calc_sum_top(pmax, exact ? kmax : 0, udata, n, pred_order, sums); @@ -815,6 +826,130 @@ static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n, } +/* These four functions check for every residual whether it can be + * contained in INT32_MAX) \ + return 1; \ + res[i] = res64; \ + } \ + } else if (order == 2) { \ + for (int i = order; i < n; i++) { \ + int64_t res64 = (int64_t)smp[i] - 2*(int64_t)smp[i-1] + smp[i-2]; \ + if (res64 <= INT32_MIN || res64 > INT32_MAX) \ + return 1; \ + res[i] = res64; \ + } \ + } else if (order == 3) { \ + for (int i = order; i < n; i++) { \ + int64_t res64 = (int64_t)smp[i] - 3*(int64_t)smp[i-1] + 3*(int64_t)smp[i-2] - smp[i-3]; \ + if (res64 <= INT32_MIN || res64 > INT32_MAX) \ + return 1; \ + res[i] = res64; \ + } \ + } else { \ + for (int i = order; i < n; i++) { \ + int64_t res64 = (int64_t)smp[i] - 4*(int64_t)smp[i-1] + 6*(int64_t)smp[i-2] - 4*(int64_t)smp[i-3] + smp[i-4]; \ + if (res64 <= INT32_MIN || res64 > INT32_MAX) \ + return 1; \ + res[i] = res64; \ + } \ + } \ + return 0; \ +} + +static int encode_residual_fixed_with_residual_limit(int32_t *res, const int32_t *smp, + int n, int order) +{ + ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT(); +} + + +static int encode_residual_fixed_with_residual_limit_33bps(int32_t *res, const int64_t *smp, + int n, int order) +{ + ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT(); +} + +#define LPC_ENCODE_WITH_RESIDUAL_LIMIT() \ +{ \ + for (int i = 0; i < order; i++) \ + res[i] = smp[i]; \ + for (int i = order; i < len; i++) { \ + int64_t p = 0, tmp; \ + for (int j = 0; j < order; j++) \ + p += (int64_t)coefs[j]*smp[(i-1)-j]; \ + p >>= shift; \ + tmp = smp[i] - p; \ + if (tmp <= INT32_MIN || tmp > INT32_MAX) \ + return 1; \ + res[i] = tmp; \ + } \ + return 0; \ +} + +static int lpc_encode_with_residual_limit(int32_t *res, const int32_t *smp, int len, + int order, int32_t *coefs, int shift) +{ + LPC_ENCODE_WITH_RESIDUAL_LIMIT(); +} + +static int lpc_encode_with_residual_limit_33bps(int32_t *res, const int64_t *smp, int len, + int order, int32_t *coefs, int shift) +{ + LPC_ENCODE_WITH_RESIDUAL_LIMIT(); +} + +static int lpc_encode_choose_datapath(FlacEncodeContext *s, int32_t bps, + int32_t *res, const int32_t *smp, + const int64_t *smp_33bps, int len, + int order, int32_t *coefs, int shift) +{ + uint64_t max_residual_value = 0; + int64_t max_sample_value = ((int64_t)(1) << (bps-1)); + /* This calculates the max size of any residual with the current + * predictor, so we know whether we need to check the residual */ + for (int i = 0; i < order; i++) + max_residual_value += FFABS(max_sample_value * coefs[i]); + max_residual_value >>= shift; + max_residual_value += max_sample_value; + if (bps > 32) { + if (lpc_encode_with_residual_limit_33bps(res, smp_33bps, len, order, coefs, shift)) + return 1; + } else if (max_residual_value > INT32_MAX) { + if (lpc_encode_with_residual_limit(res, smp, len, order, coefs, shift)) + return 1; + } else if (bps + s->options.lpc_coeff_precision + av_log2(order) <= 32) { + s->flac_dsp.lpc16_encode(res, smp, len, order, coefs, shift); + } else { + s->flac_dsp.lpc32_encode(res, smp, len, order, coefs, shift); + } + return 0; +} + +#define DEFAULT_TO_VERBATIM() \ +{ \ + sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; \ + if (sub->obits <= 32) \ + memcpy(res, smp, n * sizeof(int32_t)); \ + return subframe_count_exact(s, sub, 0); \ +} + static int encode_residual_ch(FlacEncodeContext *s, int ch) { int i, n; @@ -824,28 +959,38 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER]; int shift[MAX_LPC_ORDER]; int32_t *res, *smp; + int64_t *smp_33bps; - frame = &s->frame; - sub = &frame->subframes[ch]; - res = sub->residual; - smp = sub->samples; - n = frame->blocksize; + frame = &s->frame; + sub = &frame->subframes[ch]; + res = sub->residual; + smp = sub->samples; + smp_33bps = frame->samples_33bps; + n = frame->blocksize; /* CONSTANT */ - for (i = 1; i < n; i++) - if(smp[i] != smp[0]) - break; - if (i == n) { - sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; - res[0] = smp[0]; - return subframe_count_exact(s, sub, 0); + if (sub->obits > 32) { + for (i = 1; i < n; i++) + if(smp_33bps[i] != smp_33bps[0]) + break; + if (i == n) { + sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; + return subframe_count_exact(s, sub, 0); + } + } else { + for (i = 1; i < n; i++) + if(smp[i] != smp[0]) + break; + if (i == n) { + sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; + res[0] = smp[0]; + return subframe_count_exact(s, sub, 0); + } } /* VERBATIM */ if (frame->verbatim_only || n < 5) { - sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; - memcpy(res, smp, n * sizeof(int32_t)); - return subframe_count_exact(s, sub, 0); + DEFAULT_TO_VERBATIM(); } min_order = s->options.min_prediction_order; @@ -862,15 +1007,32 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) opt_order = 0; bits[0] = UINT32_MAX; for (i = min_order; i <= max_order; i++) { - encode_residual_fixed(res, smp, n, i); + if (sub->obits == 33) { + if (encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, i)) + continue; + } else if (sub->obits + i >= 32) { + if (encode_residual_fixed_with_residual_limit(res, smp, n, i)) + continue; + } else + encode_residual_fixed(res, smp, n, i); bits[i] = find_subframe_rice_params(s, sub, i); if (bits[i] < bits[opt_order]) opt_order = i; } + if (opt_order == 0 && bits[0] == UINT32_MAX) { + /* No predictor found with residuals within order = opt_order; sub->type_code = sub->type | sub->order; if (sub->order != max_order) { - encode_residual_fixed(res, smp, n, sub->order); + if (sub->obits == 33) + encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, sub->order); + else if (sub->obits + i >= 32) + encode_residual_fixed_with_residual_limit(res, smp, n, sub->order); + else + encode_residual_fixed(res, smp, n, sub->order); find_subframe_rice_params(s, sub, sub->order); } return subframe_count_exact(s, sub, sub->order); @@ -878,6 +1040,14 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) /* LPC */ sub->type = FLAC_SUBFRAME_LPC; + if (sub->obits == 33) + /* As ff_lpc_calc_coefs is shared with other codecs and the LSB + * probably isn't predictable anyway, throw away LSB for analysis + * so it fits 32 bit int and existing function can be used + * unmodified */ + for (i = 0; i < n; i++) + smp[i] = smp_33bps[i] >> 1; + opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, smp, n, min_order, max_order, s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type, s->options.lpc_passes, omethod, @@ -898,13 +1068,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) order = av_clip(order, min_order - 1, max_order - 1); if (order == last_order) continue; - if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(order) <= 32) { - s->flac_dsp.lpc16_encode(res, smp, n, order+1, coefs[order], - shift[order]); - } else { - s->flac_dsp.lpc32_encode(res, smp, n, order+1, coefs[order], - shift[order]); - } + if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, order+1, coefs[order], shift[order])) + continue; bits[i] = find_subframe_rice_params(s, sub, order+1); if (bits[i] < bits[opt_index]) { opt_index = i; @@ -918,11 +1083,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) opt_order = 0; bits[0] = UINT32_MAX; for (i = min_order-1; i < max_order; i++) { - if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(i) <= 32) { - s->flac_dsp.lpc16_encode(res, smp, n, i+1, coefs[i], shift[i]); - } else { - s->flac_dsp.lpc32_encode(res, smp, n, i+1, coefs[i], shift[i]); - } + if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i])) + continue; bits[i] = find_subframe_rice_params(s, sub, i+1); if (bits[i] < bits[opt_order]) opt_order = i; @@ -940,11 +1102,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) for (i = last-step; i <= last+step; i += step) { if (i < min_order-1 || i >= max_order || bits[i] < UINT32_MAX) continue; - if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(i) <= 32) { - s->flac_dsp.lpc32_encode(res, smp, n, i+1, coefs[i], shift[i]); - } else { - s->flac_dsp.lpc16_encode(res, smp, n, i+1, coefs[i], shift[i]); - } + if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i])) + continue; bits[i] = find_subframe_rice_params(s, sub, i+1); if (bits[i] < bits[opt_order]) opt_order = i; @@ -981,11 +1140,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) if (diffsum >8) continue; - if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(opt_order - 1) <= 32) { - s->flac_dsp.lpc16_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]); - } else { - s->flac_dsp.lpc32_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]); - } + if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, opt_order, lpc_try, shift[opt_order-1])) + continue; score = find_subframe_rice_params(s, sub, opt_order); if (score < best_score) { best_score = score; @@ -1002,10 +1158,10 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) for (i = 0; i < sub->order; i++) sub->coefs[i] = coefs[sub->order-1][i]; - if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(opt_order) <= 32) { - s->flac_dsp.lpc16_encode(res, smp, n, sub->order, sub->coefs, sub->shift); - } else { - s->flac_dsp.lpc32_encode(res, smp, n, sub->order, sub->coefs, sub->shift); + if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, sub->order, sub->coefs, sub->shift)) { + /* No predictor found with residuals within order); @@ -1072,57 +1228,91 @@ static int encode_frame(FlacEncodeContext *s) static void remove_wasted_bits(FlacEncodeContext *s) { - int ch, i; + int ch, i, wasted_bits; for (ch = 0; ch < s->channels; ch++) { FlacSubframe *sub = &s->frame.subframes[ch]; - int32_t v = 0; - for (i = 0; i < s->frame.blocksize; i++) { - v |= sub->samples[i]; - if (v & 1) - break; - } + if (sub->obits > 32) { + int64_t v = 0; + for (i = 0; i < s->frame.blocksize; i++) { + v |= s->frame.samples_33bps[i]; + if (v & 1) + break; + } + + if (!v || (v & 1)) + return; + + v = ff_ctzll(v); + + /* If any wasted bits are found, samples are moved + * from frame.samples_33bps to frame.subframes[ch] */ + for (i = 0; i < s->frame.blocksize; i++) + sub->samples[i] = s->frame.samples_33bps[i] >> v; + wasted_bits = v; + } else { + int32_t v = 0; + for (i = 0; i < s->frame.blocksize; i++) { + v |= sub->samples[i]; + if (v & 1) + break; + } + + if (!v || (v & 1)) + return; - if (v && !(v & 1)) { v = ff_ctz(v); for (i = 0; i < s->frame.blocksize; i++) sub->samples[i] >>= v; - - sub->wasted = v; - sub->obits -= v; - - /* for 24-bit, check if removing wasted bits makes the range better - suited for using RICE instead of RICE2 for entropy coding */ - if (sub->obits <= 17) - sub->rc.coding_mode = CODING_MODE_RICE; + wasted_bits = v; } + + sub->wasted = wasted_bits; + sub->obits -= wasted_bits; + + /* for 24-bit, check if removing wasted bits makes the range better + * suited for using RICE instead of RICE2 for entropy coding */ + if (sub->obits <= 17) + sub->rc.coding_mode = CODING_MODE_RICE; } } static int estimate_stereo_mode(const int32_t *left_ch, const int32_t *right_ch, int n, - int max_rice_param) + int max_rice_param, int bps) { - int i, best; - int32_t lt, rt; + int best; uint64_t sum[4]; uint64_t score[4]; int k; /* calculate sum of 2nd order residual for each channel */ sum[0] = sum[1] = sum[2] = sum[3] = 0; - for (i = 2; i < n; i++) { - lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2]; - rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2]; - sum[2] += FFABS((lt + rt) >> 1); - sum[3] += FFABS(lt - rt); - sum[0] += FFABS(lt); - sum[1] += FFABS(rt); + if(bps < 30) { + int32_t lt, rt; + for (int i = 2; i < n; i++) { + lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2]; + rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2]; + sum[2] += FFABS((lt + rt) >> 1); + sum[3] += FFABS(lt - rt); + sum[0] += FFABS(lt); + sum[1] += FFABS(rt); + } + } else { + int64_t lt, rt; + for (int i = 2; i < n; i++) { + lt = (int64_t)left_ch[i] - 2*(int64_t)left_ch[i-1] + left_ch[i-2]; + rt = (int64_t)right_ch[i] - 2*(int64_t)right_ch[i-1] + right_ch[i-2]; + sum[2] += FFABS((lt + rt) >> 1); + sum[3] += FFABS(lt - rt); + sum[0] += FFABS(lt); + sum[1] += FFABS(rt); + } } /* estimate bit counts */ - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { k = find_optimal_param(2 * sum[i], n, max_rice_param); sum[i] = rice_encode_count( 2 * sum[i], n, k); } @@ -1135,7 +1325,7 @@ static int estimate_stereo_mode(const int32_t *left_ch, const int32_t *right_ch, /* return mode with lowest score */ best = 0; - for (i = 1; i < 4; i++) + for (int i = 1; i < 4; i++) if (score[i] < score[best]) best = i; @@ -1150,12 +1340,14 @@ static void channel_decorrelation(FlacEncodeContext *s) { FlacFrame *frame; int32_t *left, *right; - int i, n; + int64_t *side_33bps; + int n; - frame = &s->frame; - n = frame->blocksize; - left = frame->subframes[0].samples; - right = frame->subframes[1].samples; + frame = &s->frame; + n = frame->blocksize; + left = frame->subframes[0].samples; + right = frame->subframes[1].samples; + side_33bps = frame->samples_33bps; if (s->channels != 2) { frame->ch_mode = FLAC_CHMODE_INDEPENDENT; @@ -1164,29 +1356,49 @@ static void channel_decorrelation(FlacEncodeContext *s) if (s->options.ch_mode < 0) { int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2; - frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param); + frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param, s->avctx->bits_per_raw_sample); } else frame->ch_mode = s->options.ch_mode; /* perform decorrelation and adjust bits-per-sample */ if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT) return; - if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) { - int32_t tmp; - for (i = 0; i < n; i++) { - tmp = left[i]; - left[i] = (tmp + right[i]) >> 1; - right[i] = tmp - right[i]; + if(s->avctx->bits_per_raw_sample == 32) { + if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) { + int64_t tmp; + for (int i = 0; i < n; i++) { + tmp = left[i]; + left[i] = (tmp + right[i]) >> 1; + side_33bps[i] = tmp - right[i]; + } + frame->subframes[1].obits++; + } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { + for (int i = 0; i < n; i++) + side_33bps[i] = (int64_t)left[i] - right[i]; + frame->subframes[1].obits++; + } else { + for (int i = 0; i < n; i++) + side_33bps[i] = (int64_t)left[i] - right[i]; + frame->subframes[0].obits++; } - frame->subframes[1].obits++; - } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { - for (i = 0; i < n; i++) - right[i] = left[i] - right[i]; - frame->subframes[1].obits++; } else { - for (i = 0; i < n; i++) - left[i] -= right[i]; - frame->subframes[0].obits++; + if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) { + int32_t tmp; + for (int i = 0; i < n; i++) { + tmp = left[i]; + left[i] = (tmp + right[i]) >> 1; + right[i] = tmp - right[i]; + } + frame->subframes[1].obits++; + } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { + for (int i = 0; i < n; i++) + right[i] = left[i] - right[i]; + frame->subframes[1].obits++; + } else { + for (int i = 0; i < n; i++) + left[i] -= right[i]; + frame->subframes[0].obits++; + } } } @@ -1235,13 +1447,32 @@ static void write_frame_header(FlacEncodeContext *s) } +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k) +{ + unsigned v, e; + + v = ((unsigned)(i) << 1) ^ (i >> 31); + + e = (v >> k) + 1; + while (e > 31) { + put_bits(pb, 31, 0); + e -= 31; + } + put_bits(pb, e, 1); + if (k) { + unsigned mask = UINT32_MAX >> (32-k); + put_bits(pb, k, v & mask); + } +} + + static void write_subframes(FlacEncodeContext *s) { int ch; for (ch = 0; ch < s->channels; ch++) { FlacSubframe *sub = &s->frame.subframes[ch]; - int i, p, porder, psize; + int p, porder, psize; int32_t *part_end; int32_t *res = sub->residual; int32_t *frame_end = &sub->residual[s->frame.blocksize]; @@ -1255,21 +1486,45 @@ static void write_subframes(FlacEncodeContext *s) /* subframe */ if (sub->type == FLAC_SUBFRAME_CONSTANT) { - put_sbits(&s->pb, sub->obits, res[0]); + if(sub->obits == 33) + put_sbits63(&s->pb, 33, s->frame.samples_33bps[0]); + else if(sub->obits == 32) + put_bits32(&s->pb, res[0]); + else + put_sbits(&s->pb, sub->obits, res[0]); } else if (sub->type == FLAC_SUBFRAME_VERBATIM) { - while (res < frame_end) - put_sbits(&s->pb, sub->obits, *res++); + if (sub->obits == 33) { + int64_t *res64 = s->frame.samples_33bps; + int64_t *frame_end64 = &s->frame.samples_33bps[s->frame.blocksize]; + while (res64 < frame_end64) + put_sbits63(&s->pb, 33, (*res64++)); + } else if (sub->obits == 32) { + while (res < frame_end) + put_bits32(&s->pb, *res++); + } else { + while (res < frame_end) + put_sbits(&s->pb, sub->obits, *res++); + } } else { /* warm-up samples */ - for (i = 0; i < sub->order; i++) - put_sbits(&s->pb, sub->obits, *res++); + if (sub->obits == 33) { + for (int i = 0; i < sub->order; i++) + put_sbits63(&s->pb, 33, s->frame.samples_33bps[i]); + res += sub->order; + } else if (sub->obits == 32) { + for (int i = 0; i < sub->order; i++) + put_bits32(&s->pb, *res++); + } else { + for (int i = 0; i < sub->order; i++) + put_sbits(&s->pb, sub->obits, *res++); + } /* LPC coefficients */ if (sub->type == FLAC_SUBFRAME_LPC) { int cbits = s->options.lpc_coeff_precision; put_bits( &s->pb, 4, cbits-1); put_sbits(&s->pb, 5, sub->shift); - for (i = 0; i < sub->order; i++) + for (int i = 0; i < sub->order; i++) put_sbits(&s->pb, cbits, sub->coefs[i]); } @@ -1287,7 +1542,7 @@ static void write_subframes(FlacEncodeContext *s) int k = sub->rc.params[p]; put_bits(&s->pb, sub->rc.coding_mode, k); while (res < part_end) - set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0); + set_sr_golomb_flac(&s->pb, *res++, k); part_end = FFMIN(frame_end, part_end + psize); } } @@ -1335,7 +1590,7 @@ static int update_md5_sum(FlacEncodeContext *s, const void *samples) (const uint16_t *) samples, buf_size / 2); buf = s->md5_buffer; #endif - } else { + } else if (s->avctx->bits_per_raw_sample <= 24) { int i; const int32_t *samples0 = samples; uint8_t *tmp = s->md5_buffer; @@ -1345,6 +1600,15 @@ static int update_md5_sum(FlacEncodeContext *s, const void *samples) AV_WL24(tmp + 3*i, v); } buf = s->md5_buffer; + } else { + /* s->avctx->bits_per_raw_sample <= 32 */ + int i; + const int32_t *samples0 = samples; + uint8_t *tmp = s->md5_buffer; + + for (i = 0; i < s->frame.blocksize * s->channels; i++) + AV_WL32(tmp + 4*i, samples0[i]); + buf = s->md5_buffer; } av_md5_update(s->md5ctx, buf, buf_size); @@ -1426,10 +1690,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (out_bytes < s->min_framesize) s->min_framesize = out_bytes; - avpkt->pts = frame->pts; - avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); - - s->next_pts = avpkt->pts + avpkt->duration; + s->next_pts = frame->pts + ff_samples_to_time_base(avctx, frame->nb_samples); av_shrink_packet(avpkt, out_bytes); @@ -1493,7 +1754,8 @@ const FFCodec ff_flac_encoder = { .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_FLAC, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | - AV_CODEC_CAP_SMALL_LAST_FRAME, + AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(FlacEncodeContext), .init = flac_encode_init, FF_CODEC_ENCODE_CB(flac_encode_frame), @@ -1502,5 +1764,5 @@ const FFCodec ff_flac_encoder = { AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, .p.priv_class = &flac_encoder_class, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flashsv2enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/flashsv2enc.c index 668ca6a8..46e24a9c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flashsv2enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flashsv2enc.c @@ -915,7 +915,7 @@ const FFCodec ff_flashsv2_encoder = { CODEC_LONG_NAME("Flash Screen Video Version 2"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_FLASHSV2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(FlashSV2Context), .init = flashsv2_encode_init, FF_CODEC_ENCODE_CB(flashsv2_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flashsvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/flashsvenc.c index 35793400..6192bc25 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flashsvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flashsvenc.c @@ -44,38 +44,40 @@ * Speed up. Make the difference check faster. */ -#include -#include +#include #include +#include "libavutil/buffer.h" + #include "avcodec.h" #include "codec_internal.h" #include "encode.h" #include "put_bits.h" #include "bytestream.h" +/* These values are hardcoded for now. */ +#define BLOCK_WIDTH (4 * 16U) +#define BLOCK_HEIGHT (4 * 16U) typedef struct FlashSVContext { AVCodecContext *avctx; - uint8_t *previous_frame; + const uint8_t *previous_frame; + AVBufferRef *prev_frame_buf; int image_width, image_height; - int block_width, block_height; - uint8_t *encbuffer; - int block_size; + unsigned packet_size; int last_key_frame; uint8_t tmpblock[3 * 256 * 256]; } FlashSVContext; static int copy_region_enc(const uint8_t *sptr, uint8_t *dptr, int dx, int dy, - int h, int w, int stride, uint8_t *pfptr) + int h, int w, int stride, const uint8_t *pfptr) { int i, j; - uint8_t *npfptr; int diff = 0; for (i = dx + h; i > dx; i--) { const uint8_t *nsptr = sptr + i * stride + dy * 3; - npfptr = pfptr + i * stride + dy * 3; + const uint8_t *npfptr = pfptr + i * stride + dy * 3; for (j = 0; j < w * 3; j++) { diff |= npfptr[j] ^ nsptr[j]; dptr[j] = nsptr[j]; @@ -91,8 +93,7 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; - av_freep(&s->encbuffer); - av_freep(&s->previous_frame); + av_buffer_unref(&s->prev_frame_buf); return 0; } @@ -100,6 +101,7 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx) static av_cold int flashsv_encode_init(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; + int h_blocks, v_blocks, nb_blocks; s->avctx = avctx; @@ -114,12 +116,10 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) s->image_width = avctx->width; s->image_height = avctx->height; - s->encbuffer = av_mallocz(s->image_width * s->image_height * 3); - - if (!s->encbuffer) { - av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - return AVERROR(ENOMEM); - } + h_blocks = (s->image_width + BLOCK_WIDTH - 1) / BLOCK_WIDTH; + v_blocks = (s->image_height + BLOCK_WIDTH - 1) / BLOCK_WIDTH; + nb_blocks = h_blocks * v_blocks; + s->packet_size = 4 + nb_blocks * (2 + 3 * BLOCK_WIDTH * BLOCK_HEIGHT); return 0; } @@ -127,7 +127,7 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf, int buf_size, int block_width, int block_height, - uint8_t *previous_frame, int *I_frame) + const uint8_t *previous_frame, int *I_frame) { PutBitContext pb; @@ -202,46 +202,30 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { FlashSVContext * const s = avctx->priv_data; - const AVFrame * const p = pict; - uint8_t *pfptr; + const uint8_t *prev_frame = s->previous_frame; int res; int I_frame = 0; int opt_w = 4, opt_h = 4; /* First frame needs to be a keyframe */ - if (avctx->frame_number == 0) { - s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height); - if (!s->previous_frame) { - av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - return AVERROR(ENOMEM); - } + if (!s->previous_frame) { + prev_frame = pict->data[0]; I_frame = 1; } - if (p->linesize[0] < 0) - pfptr = s->previous_frame - (s->image_height - 1) * p->linesize[0]; - else - pfptr = s->previous_frame; - /* Check the placement of keyframes */ if (avctx->gop_size > 0 && avctx->frame_number >= s->last_key_frame + avctx->gop_size) { I_frame = 1; } - if ((res = ff_alloc_packet(avctx, pkt, s->image_width * s->image_height * 3)) < 0) + res = ff_alloc_packet(avctx, pkt, s->packet_size); + if (res < 0) return res; - pkt->size = encode_bitstream(s, p, pkt->data, pkt->size, opt_w * 16, opt_h * 16, - pfptr, &I_frame); - - //save the current frame - if (p->linesize[0] > 0) - memcpy(s->previous_frame, p->data[0], s->image_height * p->linesize[0]); - else - memcpy(s->previous_frame, - p->data[0] + p->linesize[0] * (s->image_height - 1), - s->image_height * FFABS(p->linesize[0])); + pkt->size = encode_bitstream(s, pict, pkt->data, pkt->size, + opt_w * 16, opt_h * 16, + prev_frame, &I_frame); //mark the frame type so the muxer can mux it correctly if (I_frame) { @@ -253,6 +237,12 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; + //save the current frame + res = av_buffer_replace(&s->prev_frame_buf, pict->buf[0]); + if (res < 0) + return res; + s->previous_frame = pict->data[0]; + return 0; } @@ -261,7 +251,7 @@ const FFCodec ff_flashsv_encoder = { CODEC_LONG_NAME("Flash Screen Video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_FLASHSV, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(FlashSVContext), .init = flashsv_encode_init, FF_CODEC_ENCODE_CB(flashsv_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.c index b49ca2e0..6a96cb0f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.c @@ -25,7 +25,7 @@ #include "mpegvideodata.h" #include "mpegvideoenc.h" -void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number) +void ff_flv_encode_picture_header(MpegEncContext *s) { int format; @@ -105,4 +105,5 @@ const FFCodec ff_flv_encoder = { .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE}, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.h b/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.h index aaa0fcff..1ecbb46b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/flvenc.h @@ -24,7 +24,7 @@ #include "mpegvideo.h" #include "put_bits.h" -void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_flv_encode_picture_header(MpegEncContext *s); void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run, int last); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ftr.c b/arm/raspi/third_party/ffmpeg/libavcodec/ftr.c index 277b9be5..74a2c10b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ftr.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ftr.c @@ -37,7 +37,7 @@ static av_cold int ftr_init(AVCodecContext *avctx) if (avctx->ch_layout.nb_channels > 64 || avctx->ch_layout.nb_channels <= 0) - return AVERROR(ENOTSUP); + return AVERROR(EINVAL); s->packet = av_packet_alloc(); if (!s->packet) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/g722enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/g722enc.c index bc08211b..47811cee 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/g722enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/g722enc.c @@ -375,7 +375,8 @@ const FFCodec ff_adpcm_g722_encoder = { CODEC_LONG_NAME("G.722 ADPCM"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ADPCM_G722, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(G722Context), .init = g722_encode_init, .close = g722_encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/g723_1enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/g723_1enc.c index 84660671..be801531 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/g723_1enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/g723_1enc.c @@ -1241,7 +1241,7 @@ const FFCodec ff_g723_1_encoder = { CODEC_LONG_NAME("G.723.1"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_G723_1, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(G723_1_Context), .init = g723_1_encode_init, FF_CODEC_ENCODE_CB(g723_1_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/g726.c b/arm/raspi/third_party/ffmpeg/libavcodec/g726.c index 7bbb7f90..6c563876 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/g726.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/g726.c @@ -405,7 +405,8 @@ const FFCodec ff_adpcm_g726_encoder = { CODEC_LONG_NAME("G.726 ADPCM"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ADPCM_G726, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(G726Context), .init = g726_encode_init, FF_CODEC_ENCODE_CB(g726_encode_frame), @@ -422,7 +423,8 @@ const FFCodec ff_adpcm_g726le_encoder = { CODEC_LONG_NAME("G.726 little endian ADPCM (\"right-justified\")"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ADPCM_G726LE, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(G726Context), .init = g726_encode_init, FF_CODEC_ENCODE_CB(g726_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/get_bits.h b/arm/raspi/third_party/ffmpeg/libavcodec/get_bits.h index 992765dc..65dc080d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/get_bits.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/get_bits.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2004 Michael Niedermayer - * Copyright (c) 2016 Alexandra Hájková * * This file is part of FFmpeg. * @@ -58,12 +57,55 @@ #define CACHED_BITSTREAM_READER 0 #endif +#if CACHED_BITSTREAM_READER + +// we always want the LE implementation, to provide get_bits_le() +#define BITSTREAM_LE + +#ifndef BITSTREAM_READER_LE +# define BITSTREAM_BE +# define BITSTREAM_DEFAULT_BE +#endif + +#include "bitstream.h" + +#undef BITSTREAM_LE +#undef BITSTREAM_BE +#undef BITSTREAM_DEFAULT_BE + +typedef BitstreamContext GetBitContext; + +#define get_bits_count bits_tell +#define get_bits_left bits_left +#define skip_bits_long bits_skip +#define skip_bits bits_skip +#define get_bits bits_read_nz +#define get_bitsz bits_read +#define get_bits_long bits_read +#define get_bits1 bits_read_bit +#define get_bits64 bits_read_64 +#define get_xbits bits_read_xbits +#define get_sbits bits_read_signed_nz +#define get_sbits_long bits_read_signed +#define show_bits bits_peek +#define show_bits_long bits_peek +#define init_get_bits bits_init +#define init_get_bits8 bits_init8 +#define align_get_bits bits_align +#define get_vlc2 bits_read_vlc + +#define init_get_bits8_le(s, buffer, byte_size) bits_init8_le((BitstreamContextLE*)s, buffer, byte_size) +#define get_bits_le(s, n) bits_read_le((BitstreamContextLE*)s, n) + +#define show_bits1(s) bits_peek(s, 1) +#define skip_bits1(s) bits_skip(s, 1) + +#define skip_1stop_8data_bits bits_skip_1stop_8data + +#else // CACHED_BITSTREAM_READER + typedef struct GetBitContext { const uint8_t *buffer, *buffer_end; -#if CACHED_BITSTREAM_READER - uint64_t cache; - unsigned bits_left; -#endif int index; int size_in_bits; int size_in_bits_plus8; @@ -120,16 +162,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n); * For examples see get_bits, show_bits, skip_bits, get_vlc. */ -#if CACHED_BITSTREAM_READER -# define MIN_CACHE_BITS 64 -#elif defined LONG_BITSTREAM_READER +#if defined LONG_BITSTREAM_READER # define MIN_CACHE_BITS 32 #else # define MIN_CACHE_BITS 25 #endif -#if !CACHED_BITSTREAM_READER - #define OPEN_READER_NOSIZE(name, gb) \ unsigned int name ## _index = (gb)->index; \ unsigned int av_unused name ## _cache @@ -214,73 +252,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n); #define GET_CACHE(name, gb) ((uint32_t) name ## _cache) -#endif static inline int get_bits_count(const GetBitContext *s) { -#if CACHED_BITSTREAM_READER - return s->index - s->bits_left; -#else return s->index; -#endif } -#if CACHED_BITSTREAM_READER -static inline void refill_32(GetBitContext *s, int is_le) -{ -#if !UNCHECKED_BITSTREAM_READER - if (s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if (is_le) - s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache; - else - s->cache = s->cache | (uint64_t)AV_RB32(s->buffer + (s->index >> 3)) << (32 - s->bits_left); - s->index += 32; - s->bits_left += 32; -} - -static inline void refill_64(GetBitContext *s, int is_le) -{ -#if !UNCHECKED_BITSTREAM_READER - if (s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if (is_le) - s->cache = AV_RL64(s->buffer + (s->index >> 3)); - else - s->cache = AV_RB64(s->buffer + (s->index >> 3)); - s->index += 64; - s->bits_left = 64; -} - -static inline uint64_t get_val(GetBitContext *s, unsigned n, int is_le) -{ - uint64_t ret; - av_assert2(n>0 && n<=63); - if (is_le) { - ret = s->cache & ((UINT64_C(1) << n) - 1); - s->cache >>= n; - } else { - ret = s->cache >> (64 - n); - s->cache <<= n; - } - s->bits_left -= n; - return ret; -} - -static inline unsigned show_val(const GetBitContext *s, unsigned n) -{ -#ifdef BITSTREAM_READER_LE - return s->cache & ((UINT64_C(1) << n) - 1); -#else - return s->cache >> (64 - n); -#endif -} -#endif - /** * Skips the specified number of bits. * @param n the number of bits to skip, @@ -290,29 +267,13 @@ static inline unsigned show_val(const GetBitContext *s, unsigned n) */ static inline void skip_bits_long(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - skip_bits(s, n); -#else #if UNCHECKED_BITSTREAM_READER s->index += n; #else s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index); #endif -#endif } -#if CACHED_BITSTREAM_READER -static inline void skip_remaining(GetBitContext *s, unsigned n) -{ -#ifdef BITSTREAM_READER_LE - s->cache >>= n; -#else - s->cache <<= n; -#endif - s->bits_left -= n; -} -#endif - /** * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). * if MSB not set it is negative @@ -320,13 +281,6 @@ static inline void skip_remaining(GetBitContext *s, unsigned n) */ static inline int get_xbits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - int32_t cache = show_bits(s, 32); - int sign = ~cache >> 31; - skip_remaining(s, n); - - return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; -#else register int sign; register int32_t cache; OPEN_READER(re, s); @@ -337,10 +291,8 @@ static inline int get_xbits(GetBitContext *s, int n) LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; -#endif } -#if !CACHED_BITSTREAM_READER static inline int get_xbits_le(GetBitContext *s, int n) { register int sign; @@ -354,22 +306,16 @@ static inline int get_xbits_le(GetBitContext *s, int n) CLOSE_READER(re, s); return (zero_extend(sign ^ cache, n) ^ sign) - sign; } -#endif static inline int get_sbits(GetBitContext *s, int n) { register int tmp; -#if CACHED_BITSTREAM_READER - av_assert2(n>0 && n<=25); - tmp = sign_extend(get_bits(s, n), n); -#else OPEN_READER(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_SBITS(re, s, n); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif return tmp; } @@ -379,32 +325,12 @@ static inline int get_sbits(GetBitContext *s, int n) static inline unsigned int get_bits(GetBitContext *s, int n) { register unsigned int tmp; -#if CACHED_BITSTREAM_READER - - av_assert2(n>0 && n<=32); - if (n > s->bits_left) { -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - if (s->bits_left < 32) - s->bits_left = n; - } - -#ifdef BITSTREAM_READER_LE - tmp = get_val(s, n, 1); -#else - tmp = get_val(s, n, 0); -#endif -#else OPEN_READER(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_UBITS(re, s, n); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif av_assert2(tmp < UINT64_C(1) << n); return tmp; } @@ -419,16 +345,6 @@ static av_always_inline int get_bitsz(GetBitContext *s, int n) static inline unsigned int get_bits_le(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - av_assert2(n>0 && n<=32); - if (n > s->bits_left) { - refill_32(s, 1); - if (s->bits_left < 32) - s->bits_left = n; - } - - return get_val(s, n, 1); -#else register int tmp; OPEN_READER(re, s); av_assert2(n>0 && n<=25); @@ -437,7 +353,6 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n) LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); return tmp; -#endif } /** @@ -446,71 +361,22 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n) static inline unsigned int show_bits(GetBitContext *s, int n) { register unsigned int tmp; -#if CACHED_BITSTREAM_READER - if (n > s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - - tmp = show_val(s, n); -#else OPEN_READER_NOSIZE(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_UBITS(re, s, n); -#endif return tmp; } static inline void skip_bits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - if (n < s->bits_left) - skip_remaining(s, n); - else { - n -= s->bits_left; - s->cache = 0; - s->bits_left = 0; - - if (n >= 64) { - unsigned skip = (n / 8) * 8; - - n -= skip; - s->index += skip; - } -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - if (n) - skip_remaining(s, n); - } -#else OPEN_READER(re, s); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif } static inline unsigned int get_bits1(GetBitContext *s) { -#if CACHED_BITSTREAM_READER - if (!s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - -#ifdef BITSTREAM_READER_LE - return get_val(s, 1, 1); -#else - return get_val(s, 1, 0); -#endif -#else unsigned int index = s->index; uint8_t result = s->buffer[index >> 3]; #ifdef BITSTREAM_READER_LE @@ -527,7 +393,6 @@ static inline unsigned int get_bits1(GetBitContext *s) s->index = index; return result; -#endif } static inline unsigned int show_bits1(GetBitContext *s) @@ -548,10 +413,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) av_assert2(n>=0 && n<=32); if (!n) { return 0; -#if CACHED_BITSTREAM_READER - } - return get_bits(s, n); -#else } else if (n <= MIN_CACHE_BITS) { return get_bits(s, n); } else { @@ -563,7 +424,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) return ret | get_bits(s, n - 16); #endif } -#endif } /** @@ -596,6 +456,18 @@ static inline int get_sbits_long(GetBitContext *s, int n) return sign_extend(get_bits_long(s, n), n); } +/** + * Read 0-64 bits as a signed integer. + */ +static inline int64_t get_sbits64(GetBitContext *s, int n) +{ + // sign_extend(x, 0) is undefined + if (!n) + return 0; + + return sign_extend64(get_bits64(s, n), n); +} + /** * Show 0-32 bits. */ @@ -609,8 +481,17 @@ static inline unsigned int show_bits_long(GetBitContext *s, int n) } } -static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, - int bit_size, int is_le) + +/** + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) { int buffer_size; int ret = 0; @@ -629,33 +510,9 @@ static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, s->buffer_end = buffer + buffer_size; s->index = 0; -#if CACHED_BITSTREAM_READER - s->cache = 0; - s->bits_left = 0; - refill_64(s, is_le); -#endif - return ret; } -/** - * Initialize GetBitContext. - * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes - * larger than the actual read bits because some optimized bitstream - * readers read 32 or 64 bit at once and could read over the end - * @param bit_size the size of the buffer in bits - * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. - */ -static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) -{ -#ifdef BITSTREAM_READER_LE - return init_get_bits_xe(s, buffer, bit_size, 1); -#else - return init_get_bits_xe(s, buffer, bit_size, 0); -#endif -} - /** * Initialize GetBitContext. * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes @@ -677,7 +534,7 @@ static inline int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer, { if (byte_size > INT_MAX / 8 || byte_size < 0) byte_size = -1; - return init_get_bits_xe(s, buffer, byte_size * 8, 1); + return init_get_bits(s, buffer, byte_size * 8); } static inline const uint8_t *align_get_bits(GetBitContext *s) @@ -762,19 +619,6 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) SKIP_BITS(name, gb, n); \ } while (0) -/* Return the LUT element for the given bitstream configuration. */ -static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, - const VLCElem *table) -{ - unsigned idx; - - *nb_bits = -*n; - idx = show_bits(s, *nb_bits) + code; - *n = table[idx].len; - - return table[idx].sym; -} - /** * Parse a vlc code. * @param bits is the number of bits which will be read at once, must be @@ -787,24 +631,6 @@ static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth) { -#if CACHED_BITSTREAM_READER - int nb_bits; - unsigned idx = show_bits(s, bits); - int code = table[idx].sym; - int n = table[idx].len; - - if (max_depth > 1 && n < 0) { - skip_remaining(s, bits); - code = set_idx(s, code, &n, &nb_bits, table); - if (max_depth > 2 && n < 0) { - skip_remaining(s, nb_bits); - code = set_idx(s, code, &n, &nb_bits, table); - } - } - skip_remaining(s, n); - - return code; -#else int code; OPEN_READER(re, s); @@ -815,7 +641,6 @@ static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, CLOSE_READER(re, s); return code; -#endif } static inline int decode012(GetBitContext *gb) @@ -855,4 +680,6 @@ static inline int skip_1stop_8data_bits(GetBitContext *gb) return 0; } +#endif // CACHED_BITSTREAM_READER + #endif /* AVCODEC_GET_BITS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/gif.c b/arm/raspi/third_party/ffmpeg/libavcodec/gif.c index 7e717d82..e17ead0f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/gif.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/gif.c @@ -553,7 +553,7 @@ const FFCodec ff_gif_encoder = { CODEC_LONG_NAME("GIF (Graphics Interchange Format)"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_GIF, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(GIFContext), .init = gif_encode_init, FF_CODEC_ENCODE_CB(gif_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.c index e8ea357c..438ebb63 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.c @@ -52,7 +52,7 @@ typedef struct H261EncContext { } format; } H261EncContext; -void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number) +void ff_h261_encode_picture_header(MpegEncContext *s) { H261EncContext *const h = (H261EncContext *)s; int temp_ref; @@ -413,4 +413,5 @@ const FFCodec ff_h261_encoder = { .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.h index 102e9944..d8fdcad7 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h261enc.h @@ -33,7 +33,7 @@ void ff_h261_reorder_mb_index(MpegEncContext *s); void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y); -void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h261_encode_picture_header(MpegEncContext *s); int ff_h261_encode_init(MpegEncContext *s); #endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h263dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/h263dec.c index b2cd77a4..09057de4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h263dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h263dec.c @@ -430,6 +430,18 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict, return ret; s->next_picture_ptr = NULL; + *got_frame = 1; + } else if (s->skipped_last_frame && s->current_picture_ptr) { + /* Output the last picture we decoded again if the stream ended with + * an NVOP */ + if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) + return ret; + /* Copy props from the last input packet. Otherwise, props from the last + * returned picture would be reused */ + if ((ret = ff_decode_frame_props(avctx, pict)) < 0) + return ret; + s->current_picture_ptr = NULL; + *got_frame = 1; } @@ -492,13 +504,15 @@ retry: } else if (CONFIG_MSMPEG4DEC && s->msmpeg4_version) { ret = ff_msmpeg4_decode_picture_header(s); } else if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) { - if (s->avctx->extradata_size && s->picture_number == 0) { + if (s->avctx->extradata_size && !s->extradata_parsed) { GetBitContext gb; if (init_get_bits8(&gb, s->avctx->extradata, s->avctx->extradata_size) >= 0 ) ff_mpeg4_decode_picture_header(avctx->priv_data, &gb, 1, 0); + s->extradata_parsed = 1; } ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb, 0, 0); + s->skipped_last_frame = (ret == FRAME_SKIPPED); } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) { ret = ff_intel_h263_decode_picture_header(s); } else if (CONFIG_FLV_DECODER && s->h263_flv) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h263enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/h263enc.h index fff85a18..e4547568 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h263enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h263enc.h @@ -25,7 +25,7 @@ #include "mpegvideoenc.h" void ff_h263_encode_init(MpegEncContext *s); -void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h263_encode_picture_header(MpegEncContext *s); void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line); void ff_h263_encode_mb(MpegEncContext *s, int16_t block[6][64], diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.c b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.c new file mode 100644 index 00000000..6e4a9a1a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.c @@ -0,0 +1,670 @@ +/* + * Common H.264 and HEVC Supplementary Enhancement Information messages + * + * Copyright (c) 2003 Michael Niedermayer + * Copyright (C) 2012 - 2013 Guillaume Martres + * Copyright (C) 2012 - 2013 Gildas Cocherel + * Copyright (C) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config_components.h" + +#include "libavutil/ambient_viewing_environment.h" +#include "libavutil/display.h" +#include "libavutil/film_grain_params.h" +#include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" + +#include "atsc_a53.h" +#include "avcodec.h" +#include "dynamic_hdr10_plus.h" +#include "dynamic_hdr_vivid.h" +#include "get_bits.h" +#include "golomb.h" +#include "h2645_sei.h" + +#define IS_H264(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_H264 : CONFIG_H264_SEI) +#define IS_HEVC(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_HEVC : CONFIG_HEVC_SEI) + +#if CONFIG_HEVC_SEI +static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s, + GetByteContext *gb) +{ + size_t meta_size; + int err; + AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size); + if (!metadata) + return AVERROR(ENOMEM); + + err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer, + bytestream2_get_bytes_left(gb)); + if (err < 0) { + av_free(metadata); + return err; + } + + av_buffer_unref(&s->info); + s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0); + if (!s->info) { + av_free(metadata); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid *s, + GetByteContext *gb) +{ + size_t meta_size; + int err; + AVDynamicHDRVivid *metadata = av_dynamic_hdr_vivid_alloc(&meta_size); + if (!metadata) + return AVERROR(ENOMEM); + + err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata, + gb->buffer, bytestream2_get_bytes_left(gb)); + if (err < 0) { + av_free(metadata); + return err; + } + + av_buffer_unref(&s->info); + s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0); + if (!s->info) { + av_free(metadata); + return AVERROR(ENOMEM); + } + + return 0; +} +#endif + +static int decode_registered_user_data_afd(H2645SEIAFD *h, GetByteContext *gb) +{ + int flag; + + if (bytestream2_get_bytes_left(gb) <= 0) + return AVERROR_INVALIDDATA; + + flag = !!(bytestream2_get_byteu(gb) & 0x40); // active_format_flag + + if (flag) { + if (bytestream2_get_bytes_left(gb) <= 0) + return AVERROR_INVALIDDATA; + h->active_format_description = bytestream2_get_byteu(gb) & 0xF; + h->present = 1; + } + + return 0; +} + +static int decode_registered_user_data_closed_caption(H2645SEIA53Caption *h, + GetByteContext *gb) +{ + return ff_parse_a53_cc(&h->buf_ref, gb->buffer, + bytestream2_get_bytes_left(gb)); +} + +static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, + enum AVCodecID codec_id, void *logctx) +{ + int country_code, provider_code; + + if (bytestream2_get_bytes_left(gb) < 3) + return AVERROR_INVALIDDATA; + + country_code = bytestream2_get_byteu(gb); // itu_t_t35_country_code + if (country_code == 0xFF) { + if (bytestream2_get_bytes_left(gb) < 3) + return AVERROR_INVALIDDATA; + + bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte + } + + if (country_code != 0xB5 && country_code != 0x26) { // usa_country_code and cn_country_code + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n", + country_code); + return 0; + } + + /* itu_t_t35_payload_byte follows */ + provider_code = bytestream2_get_be16u(gb); + + switch (provider_code) { + case 0x31: { // atsc_provider_code + uint32_t user_identifier; + + if (bytestream2_get_bytes_left(gb) < 4) + return AVERROR_INVALIDDATA; + + user_identifier = bytestream2_get_be32u(gb); + switch (user_identifier) { + case MKBETAG('D', 'T', 'G', '1'): // afd_data + return decode_registered_user_data_afd(&h->afd, gb); + case MKBETAG('G', 'A', '9', '4'): // closed captions + return decode_registered_user_data_closed_caption(&h->a53_caption, gb); + default: + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", + user_identifier); + break; + } + break; + } +#if CONFIG_HEVC_SEI + case 0x04: { // cuva_provider_code + const uint16_t cuva_provider_oriented_code = 0x0005; + uint16_t provider_oriented_code; + + if (!IS_HEVC(codec_id)) + goto unsupported_provider_code; + + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; + + provider_oriented_code = bytestream2_get_be16u(gb); + if (provider_oriented_code == cuva_provider_oriented_code) { + return decode_registered_user_data_dynamic_hdr_vivid(&h->dynamic_hdr_vivid, gb); + } + break; + } + case 0x3C: { // smpte_provider_code + // A/341 Amendment - 2094-40 + const uint16_t smpte2094_40_provider_oriented_code = 0x0001; + const uint8_t smpte2094_40_application_identifier = 0x04; + uint16_t provider_oriented_code; + uint8_t application_identifier; + + if (!IS_HEVC(codec_id)) + goto unsupported_provider_code; + + if (bytestream2_get_bytes_left(gb) < 3) + return AVERROR_INVALIDDATA; + + provider_oriented_code = bytestream2_get_be16u(gb); + application_identifier = bytestream2_get_byteu(gb); + if (provider_oriented_code == smpte2094_40_provider_oriented_code && + application_identifier == smpte2094_40_application_identifier) { + return decode_registered_user_data_dynamic_hdr_plus(&h->dynamic_hdr_plus, gb); + } + break; + } + unsupported_provider_code: +#endif + default: + av_log(logctx, AV_LOG_VERBOSE, + "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n", + provider_code); + break; + } + + return 0; +} + +static int decode_unregistered_user_data(H2645SEIUnregistered *h, + GetByteContext *gb, + enum AVCodecID codec_id) +{ + uint8_t *user_data; + int size = bytestream2_get_bytes_left(gb); + AVBufferRef *buf_ref, **tmp; + + if (size < 16 || size >= INT_MAX - 1) + return AVERROR_INVALIDDATA; + + tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); + if (!tmp) + return AVERROR(ENOMEM); + h->buf_ref = tmp; + + buf_ref = av_buffer_alloc(size + 1); + if (!buf_ref) + return AVERROR(ENOMEM); + user_data = buf_ref->data; + + bytestream2_get_bufferu(gb, user_data, size); + user_data[size] = 0; + buf_ref->size = size; + h->buf_ref[h->nb_buf_ref++] = buf_ref; + + if (IS_H264(codec_id)) { + int e, build; + e = sscanf(user_data + 16, "x264 - core %d", &build); + if (e == 1 && build > 0) + h->x264_build = build; + if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16)) + h->x264_build = 67; + } + + return 0; +} + +static int decode_display_orientation(H2645SEIDisplayOrientation *h, + GetBitContext *gb) +{ + h->present = !get_bits1(gb); // display_orientation_cancel_flag + + if (h->present) { + h->hflip = get_bits1(gb); // hor_flip + h->vflip = get_bits1(gb); // ver_flip + + h->anticlockwise_rotation = get_bits(gb, 16); + // This is followed by display_orientation_repetition_period + // and display_orientation_extension_flag for H.264 + // and by display_orientation_persistence_flag for HEVC. + } + + return 0; +} + +static int decode_frame_packing_arrangement(H2645SEIFramePacking *h, + GetBitContext *gb, + enum AVCodecID codec_id) +{ + h->arrangement_id = get_ue_golomb_long(gb); + h->arrangement_cancel_flag = get_bits1(gb); + h->present = !h->arrangement_cancel_flag; + + if (h->present) { + h->arrangement_type = get_bits(gb, 7); + h->quincunx_sampling_flag = get_bits1(gb); + h->content_interpretation_type = get_bits(gb, 6); + + // spatial_flipping_flag, frame0_flipped_flag, field_views_flag + skip_bits(gb, 3); + h->current_frame_is_frame0_flag = get_bits1(gb); + // frame0_self_contained_flag, frame1_self_contained_flag + skip_bits(gb, 2); + + if (!h->quincunx_sampling_flag && h->arrangement_type != 5) + skip_bits(gb, 16); // frame[01]_grid_position_[xy] + skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte + if (IS_H264(codec_id)) + h->arrangement_repetition_period = get_ue_golomb_long(gb); + else + skip_bits1(gb); // frame_packing_arrangement_persistence_flag + } + // H.264: frame_packing_arrangement_extension_flag, + // HEVC: upsampled_aspect_ratio_flag + skip_bits1(gb); + + return 0; +} + +static int decode_alternative_transfer(H2645SEIAlternativeTransfer *s, + GetByteContext *gb) +{ + if (bytestream2_get_bytes_left(gb) < 1) + return AVERROR_INVALIDDATA; + + s->present = 1; + s->preferred_transfer_characteristics = bytestream2_get_byteu(gb); + + return 0; +} + +static int decode_ambient_viewing_environment(H2645SEIAmbientViewingEnvironment *s, + GetByteContext *gb) +{ + static const uint16_t max_ambient_light_value = 50000; + + if (bytestream2_get_bytes_left(gb) < 8) + return AVERROR_INVALIDDATA; + + s->ambient_illuminance = bytestream2_get_be32u(gb); + if (!s->ambient_illuminance) + return AVERROR_INVALIDDATA; + + s->ambient_light_x = bytestream2_get_be16u(gb); + if (s->ambient_light_x > max_ambient_light_value) + return AVERROR_INVALIDDATA; + + s->ambient_light_y = bytestream2_get_be16u(gb); + if (s->ambient_light_y > max_ambient_light_value) + return AVERROR_INVALIDDATA; + + s->present = 1; + + return 0; +} + +static int decode_film_grain_characteristics(H2645SEIFilmGrainCharacteristics *h, + enum AVCodecID codec_id, GetBitContext *gb) +{ + h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag + + if (h->present) { + memset(h, 0, sizeof(*h)); + h->model_id = get_bits(gb, 2); + h->separate_colour_description_present_flag = get_bits1(gb); + if (h->separate_colour_description_present_flag) { + h->bit_depth_luma = get_bits(gb, 3) + 8; + h->bit_depth_chroma = get_bits(gb, 3) + 8; + h->full_range = get_bits1(gb); + h->color_primaries = get_bits(gb, 8); + h->transfer_characteristics = get_bits(gb, 8); + h->matrix_coeffs = get_bits(gb, 8); + } + h->blending_mode_id = get_bits(gb, 2); + h->log2_scale_factor = get_bits(gb, 4); + for (int c = 0; c < 3; c++) + h->comp_model_present_flag[c] = get_bits1(gb); + for (int c = 0; c < 3; c++) { + if (h->comp_model_present_flag[c]) { + h->num_intensity_intervals[c] = get_bits(gb, 8) + 1; + h->num_model_values[c] = get_bits(gb, 3) + 1; + if (h->num_model_values[c] > 6) + return AVERROR_INVALIDDATA; + for (int i = 0; i < h->num_intensity_intervals[c]; i++) { + h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8); + h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8); + for (int j = 0; j < h->num_model_values[c]; j++) + h->comp_model_value[c][i][j] = get_se_golomb_long(gb); + } + } + } + if (IS_HEVC(codec_id)) + h->persistence_flag = get_bits1(gb); + else + h->repetition_period = get_ue_golomb_long(gb); + + h->present = 1; + } + + return 0; +} + +int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, + enum AVCodecID codec_id, GetBitContext *gb, + GetByteContext *gbyte, void *logctx) +{ + switch (type) { + case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: + return decode_registered_user_data(h, gbyte, codec_id, logctx); + case SEI_TYPE_USER_DATA_UNREGISTERED: + return decode_unregistered_user_data(&h->unregistered, gbyte, codec_id); + case SEI_TYPE_DISPLAY_ORIENTATION: + return decode_display_orientation(&h->display_orientation, gb); + case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: + return decode_film_grain_characteristics(&h->film_grain_characteristics, codec_id, gb); + case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: + return decode_frame_packing_arrangement(&h->frame_packing, gb, codec_id); + case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: + return decode_alternative_transfer(&h->alternative_transfer, gbyte); + case SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT: + return decode_ambient_viewing_environment(&h->ambient_viewing_environment, + gbyte); + default: + return FF_H2645_SEI_MESSAGE_UNHANDLED; + } +} + +int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src) +{ + int ret = av_buffer_replace(&dst->a53_caption.buf_ref, + src->a53_caption.buf_ref); + if (ret < 0) + return ret; + + for (unsigned i = 0; i < dst->unregistered.nb_buf_ref; i++) + av_buffer_unref(&dst->unregistered.buf_ref[i]); + dst->unregistered.nb_buf_ref = 0; + + if (src->unregistered.nb_buf_ref) { + ret = av_reallocp_array(&dst->unregistered.buf_ref, + src->unregistered.nb_buf_ref, + sizeof(*dst->unregistered.buf_ref)); + if (ret < 0) + return ret; + + for (unsigned i = 0; i < src->unregistered.nb_buf_ref; i++) { + dst->unregistered.buf_ref[i] = av_buffer_ref(src->unregistered.buf_ref[i]); + if (!dst->unregistered.buf_ref[i]) + return AVERROR(ENOMEM); + dst->unregistered.nb_buf_ref++; + } + } + + return 0; +} + +static int is_frame_packing_type_valid(SEIFpaType type, enum AVCodecID codec_id) +{ + if (IS_H264(codec_id)) + return type <= SEI_FPA_H264_TYPE_2D && + type >= SEI_FPA_H264_TYPE_CHECKERBOARD; + else + return type <= SEI_FPA_TYPE_INTERLEAVE_TEMPORAL && + type >= SEI_FPA_TYPE_SIDE_BY_SIDE; +} + +int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, + enum AVCodecID codec_id, + AVCodecContext *avctx, const H2645VUI *vui, + unsigned bit_depth_luma, unsigned bit_depth_chroma, + int seed) +{ + H2645SEIFramePacking *fp = &sei->frame_packing; + + if (fp->present && + is_frame_packing_type_valid(fp->arrangement_type, codec_id) && + fp->content_interpretation_type > 0 && + fp->content_interpretation_type < 3) { + AVStereo3D *stereo = av_stereo3d_create_side_data(frame); + + if (!stereo) + return AVERROR(ENOMEM); + + switch (fp->arrangement_type) { +#if CONFIG_H264_SEI + case SEI_FPA_H264_TYPE_CHECKERBOARD: + stereo->type = AV_STEREO3D_CHECKERBOARD; + break; + case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN: + stereo->type = AV_STEREO3D_COLUMNS; + break; + case SEI_FPA_H264_TYPE_INTERLEAVE_ROW: + stereo->type = AV_STEREO3D_LINES; + break; +#endif + case SEI_FPA_TYPE_SIDE_BY_SIDE: + if (fp->quincunx_sampling_flag) + stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; + else + stereo->type = AV_STEREO3D_SIDEBYSIDE; + break; + case SEI_FPA_TYPE_TOP_BOTTOM: + stereo->type = AV_STEREO3D_TOPBOTTOM; + break; + case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: + stereo->type = AV_STEREO3D_FRAMESEQUENCE; + break; +#if CONFIG_H264_SEI + case SEI_FPA_H264_TYPE_2D: + stereo->type = AV_STEREO3D_2D; + break; +#endif + } + + if (fp->content_interpretation_type == 2) + stereo->flags = AV_STEREO3D_FLAG_INVERT; + + if (fp->arrangement_type == SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) { + if (fp->current_frame_is_frame0_flag) + stereo->view = AV_STEREO3D_VIEW_LEFT; + else + stereo->view = AV_STEREO3D_VIEW_RIGHT; + } + } + + if (sei->display_orientation.present && + (sei->display_orientation.anticlockwise_rotation || + sei->display_orientation.hflip || + sei->display_orientation.vflip)) { + H2645SEIDisplayOrientation *o = &sei->display_orientation; + double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); + AVFrameSideData *rotation = av_frame_new_side_data(frame, + AV_FRAME_DATA_DISPLAYMATRIX, + sizeof(int32_t) * 9); + if (!rotation) + return AVERROR(ENOMEM); + + /* av_display_rotation_set() expects the angle in the clockwise + * direction, hence the first minus. + * The below code applies the flips after the rotation, yet + * the H.2645 specs require flipping to be applied first. + * Because of R O(phi) = O(-phi) R (where R is flipping around + * an arbitatry axis and O(phi) is the proper rotation by phi) + * we can create display matrices as desired by negating + * the degree once for every flip applied. */ + angle = -angle * (1 - 2 * !!o->hflip) * (1 - 2 * !!o->vflip); + av_display_rotation_set((int32_t *)rotation->data, angle); + av_display_matrix_flip((int32_t *)rotation->data, + o->hflip, o->vflip); + } + + if (sei->a53_caption.buf_ref) { + H2645SEIA53Caption *a53 = &sei->a53_caption; + AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_A53_CC, a53->buf_ref); + if (!sd) + av_buffer_unref(&a53->buf_ref); + a53->buf_ref = NULL; + if (avctx) + avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; + } + + for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) { + H2645SEIUnregistered *unreg = &sei->unregistered; + + if (unreg->buf_ref[i]) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, + AV_FRAME_DATA_SEI_UNREGISTERED, + unreg->buf_ref[i]); + if (!sd) + av_buffer_unref(&unreg->buf_ref[i]); + unreg->buf_ref[i] = NULL; + } + } + sei->unregistered.nb_buf_ref = 0; + + if (sei->afd.present) { + AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_AFD, + sizeof(uint8_t)); + + if (sd) { + *sd->data = sei->afd.active_format_description; + sei->afd.present = 0; + } + } + + if (sei->film_grain_characteristics.present) { + H2645SEIFilmGrainCharacteristics *fgc = &sei->film_grain_characteristics; + AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame); + AVFilmGrainH274Params *h274; + + if (!fgp) + return AVERROR(ENOMEM); + + fgp->type = AV_FILM_GRAIN_PARAMS_H274; + h274 = &fgp->codec.h274; + + fgp->seed = seed; + + h274->model_id = fgc->model_id; + if (fgc->separate_colour_description_present_flag) { + h274->bit_depth_luma = fgc->bit_depth_luma; + h274->bit_depth_chroma = fgc->bit_depth_chroma; + h274->color_range = fgc->full_range + 1; + h274->color_primaries = fgc->color_primaries; + h274->color_trc = fgc->transfer_characteristics; + h274->color_space = fgc->matrix_coeffs; + } else { + h274->bit_depth_luma = bit_depth_luma; + h274->bit_depth_chroma = bit_depth_chroma; + if (vui->video_signal_type_present_flag) + h274->color_range = vui->video_full_range_flag + 1; + else + h274->color_range = AVCOL_RANGE_UNSPECIFIED; + if (vui->colour_description_present_flag) { + h274->color_primaries = vui->colour_primaries; + h274->color_trc = vui->transfer_characteristics; + h274->color_space = vui->matrix_coeffs; + } else { + h274->color_primaries = AVCOL_PRI_UNSPECIFIED; + h274->color_trc = AVCOL_TRC_UNSPECIFIED; + h274->color_space = AVCOL_SPC_UNSPECIFIED; + } + } + h274->blending_mode_id = fgc->blending_mode_id; + h274->log2_scale_factor = fgc->log2_scale_factor; + + memcpy(&h274->component_model_present, &fgc->comp_model_present_flag, + sizeof(h274->component_model_present)); + memcpy(&h274->num_intensity_intervals, &fgc->num_intensity_intervals, + sizeof(h274->num_intensity_intervals)); + memcpy(&h274->num_model_values, &fgc->num_model_values, + sizeof(h274->num_model_values)); + memcpy(&h274->intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound, + sizeof(h274->intensity_interval_lower_bound)); + memcpy(&h274->intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound, + sizeof(h274->intensity_interval_upper_bound)); + memcpy(&h274->comp_model_value, &fgc->comp_model_value, + sizeof(h274->comp_model_value)); + + if (IS_H264(codec_id)) + fgc->present = !!fgc->repetition_period; + else + fgc->present = fgc->persistence_flag; + + if (avctx) + avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN; + } + + if (sei->ambient_viewing_environment.present) { + H2645SEIAmbientViewingEnvironment *env = + &sei->ambient_viewing_environment; + + AVAmbientViewingEnvironment *dst_env = + av_ambient_viewing_environment_create_side_data(frame); + if (!dst_env) + return AVERROR(ENOMEM); + + dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000); + dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000); + dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000); + } + + return 0; +} + +void ff_h2645_sei_reset(H2645SEI *s) +{ + av_buffer_unref(&s->a53_caption.buf_ref); + + for (unsigned i = 0; i < s->unregistered.nb_buf_ref; i++) + av_buffer_unref(&s->unregistered.buf_ref[i]); + s->unregistered.nb_buf_ref = 0; + av_freep(&s->unregistered.buf_ref); + av_buffer_unref(&s->dynamic_hdr_plus.info); + av_buffer_unref(&s->dynamic_hdr_vivid.info); + + s->ambient_viewing_environment.present = 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.h b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.h new file mode 100644 index 00000000..e07ae103 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_sei.h @@ -0,0 +1,152 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H2645_SEI_H +#define AVCODEC_H2645_SEI_H + +#include + +#include "libavutil/buffer.h" +#include "libavutil/frame.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "codec_id.h" +#include "get_bits.h" +#include "h2645_vui.h" +#include "sei.h" + +typedef struct H2645SEIA53Caption { + AVBufferRef *buf_ref; +} H2645SEIA53Caption; + +typedef struct H2645SEIAFD { + int present; + uint8_t active_format_description; +} H2645SEIAFD; + +typedef struct HEVCSEIDynamicHDRPlus { + AVBufferRef *info; +} HEVCSEIDynamicHDRPlus; + +typedef struct HEVCSEIDynamicHDRVivid { + AVBufferRef *info; +} HEVCSEIDynamicHDRVivid; + +typedef struct H2645SEIUnregistered { + AVBufferRef **buf_ref; + unsigned nb_buf_ref; + int x264_build; //< H.264 only +} H2645SEIUnregistered; + +typedef struct H2645SEIFramePacking { + int present; + int arrangement_id; + int arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received (currently H.264 only) + SEIFpaType arrangement_type; + int arrangement_repetition_period; + int content_interpretation_type; + int quincunx_sampling_flag; + int current_frame_is_frame0_flag; +} H2645SEIFramePacking; + +typedef struct H2645SEIDisplayOrientation { + int present; + int anticlockwise_rotation; + int hflip, vflip; +} H2645SEIDisplayOrientation; + +typedef struct H2645SEIAlternativeTransfer { + int present; + int preferred_transfer_characteristics; +} H2645SEIAlternativeTransfer; + +typedef struct H2645SEIAmbientViewingEnvironment { + int present; + uint32_t ambient_illuminance; + uint16_t ambient_light_x; + uint16_t ambient_light_y; +} H2645SEIAmbientViewingEnvironment; + +typedef struct H2645SEIFilmGrainCharacteristics { + int present; + int model_id; + int separate_colour_description_present_flag; + int bit_depth_luma; + int bit_depth_chroma; + int full_range; + int color_primaries; + int transfer_characteristics; + int matrix_coeffs; + int blending_mode_id; + int log2_scale_factor; + int comp_model_present_flag[3]; + uint16_t num_intensity_intervals[3]; + uint8_t num_model_values[3]; + uint8_t intensity_interval_lower_bound[3][256]; + uint8_t intensity_interval_upper_bound[3][256]; + int16_t comp_model_value[3][256][6]; + int repetition_period; //< H.264 only + int persistence_flag; //< HEVC only +} H2645SEIFilmGrainCharacteristics; + +typedef struct H2645SEI { + H2645SEIA53Caption a53_caption; + H2645SEIAFD afd; + HEVCSEIDynamicHDRPlus dynamic_hdr_plus; //< HEVC only + HEVCSEIDynamicHDRVivid dynamic_hdr_vivid; //< HEVC only + H2645SEIUnregistered unregistered; + H2645SEIFramePacking frame_packing; + H2645SEIDisplayOrientation display_orientation; + H2645SEIAlternativeTransfer alternative_transfer; + H2645SEIFilmGrainCharacteristics film_grain_characteristics; + H2645SEIAmbientViewingEnvironment ambient_viewing_environment; +} H2645SEI; + +enum { + FF_H2645_SEI_MESSAGE_HANDLED = 0, + FF_H2645_SEI_MESSAGE_UNHANDLED, +}; + +/** + * Decode a single SEI message. + * + * This function may either use gb or gbyte to decode the SEI message. + * + * @param[in, out] gb GetBitContext that needs to be at the start + * of the payload (i.e. after the payload_size bytes); + * it needs to be initially byte-aligned + * @param[in, out] gbyte a GetByteContext for the same data as gb + * @return < 0 on error, FF_H2645_SEI_MESSAGE_HANDLED if the SEI message + * has been handled or FF_H2645_SEI_MESSAGE_UNHANDLED if not. + */ +int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, + enum AVCodecID codec_id, GetBitContext *gb, + GetByteContext *gbyte, void *logctx); + +int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src); + +void ff_h2645_sei_reset(H2645SEI *s); + +int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, + enum AVCodecID codec_id, + AVCodecContext *avctx, const H2645VUI *vui, + unsigned bit_depth_luma, unsigned bit_depth_chroma, + int seed); + +#endif /* AVCODEC_H2645_SEI_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.c b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.c new file mode 100644 index 00000000..0633fcbd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.c @@ -0,0 +1,91 @@ +/* + * Common H.264/HEVC VUI Parameter decoding + * + * Copyright (c) 2003 Michael Niedermayer + * Copyright (C) 2012 - 2013 Guillaume Martres + * Copyright (C) 2012 - 2013 Mickael Raulet + * Copyright (C) 2012 - 2013 Gildas Cocherel + * Copyright (C) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/log.h" +#include "libavutil/pixdesc.h" + +#include "get_bits.h" +#include "golomb.h" +#include "h2645data.h" +#include "h2645_vui.h" + +#define EXTENDED_SAR 255 + +void ff_h2645_decode_common_vui_params(GetBitContext *gb, H2645VUI *vui, void *logctx) +{ + int aspect_ratio_info_present_flag; + + av_log(logctx, AV_LOG_DEBUG, "Decoding VUI\n"); + + aspect_ratio_info_present_flag = get_bits1(gb); + if (aspect_ratio_info_present_flag) { + uint8_t aspect_ratio_idc = get_bits(gb, 8); + if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) + vui->sar = ff_h2645_pixel_aspect[aspect_ratio_idc]; + else if (aspect_ratio_idc == EXTENDED_SAR) { + vui->sar.num = get_bits(gb, 16); + vui->sar.den = get_bits(gb, 16); + } else + av_log(logctx, AV_LOG_WARNING, + "Unknown SAR index: %u.\n", aspect_ratio_idc); + } else + vui->sar = (AVRational){ 0, 1 }; + + vui->overscan_info_present_flag = get_bits1(gb); + if (vui->overscan_info_present_flag) + vui->overscan_appropriate_flag = get_bits1(gb); + + vui->video_signal_type_present_flag = get_bits1(gb); + if (vui->video_signal_type_present_flag) { + vui->video_format = get_bits(gb, 3); + vui->video_full_range_flag = get_bits1(gb); + vui->colour_description_present_flag = get_bits1(gb); + if (vui->colour_description_present_flag) { + vui->colour_primaries = get_bits(gb, 8); + vui->transfer_characteristics = get_bits(gb, 8); + vui->matrix_coeffs = get_bits(gb, 8); + + // Set invalid values to "unspecified" + if (!av_color_primaries_name(vui->colour_primaries)) + vui->colour_primaries = AVCOL_PRI_UNSPECIFIED; + if (!av_color_transfer_name(vui->transfer_characteristics)) + vui->transfer_characteristics = AVCOL_TRC_UNSPECIFIED; + if (!av_color_space_name(vui->matrix_coeffs)) + vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED; + } + } + + vui->chroma_loc_info_present_flag = get_bits1(gb); + if (vui->chroma_loc_info_present_flag) { + vui->chroma_sample_loc_type_top_field = get_ue_golomb_31(gb); + vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_31(gb); + if (vui->chroma_sample_loc_type_top_field <= 5U) + vui->chroma_location = vui->chroma_sample_loc_type_top_field + 1; + else + vui->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + } else + vui->chroma_location = AVCHROMA_LOC_LEFT; +} diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.h b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.h new file mode 100644 index 00000000..638da7c3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645_vui.h @@ -0,0 +1,49 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H2645_VUI_H +#define AVCODEC_H2645_VUI_H + +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "get_bits.h" + +typedef struct H2645VUI { + AVRational sar; + + int overscan_info_present_flag; + int overscan_appropriate_flag; + + int video_signal_type_present_flag; + int video_format; + int video_full_range_flag; + int colour_description_present_flag; + enum AVColorPrimaries colour_primaries; + enum AVColorTransferCharacteristic transfer_characteristics; + enum AVColorSpace matrix_coeffs; + + int chroma_loc_info_present_flag; + int chroma_sample_loc_type_top_field; + int chroma_sample_loc_type_bottom_field; + enum AVChromaLocation chroma_location; +} H2645VUI; + +void ff_h2645_decode_common_vui_params(GetBitContext *gb, H2645VUI *vui, void *logctx); + +#endif /* AVCODEC_H2645_VUI_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.c b/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.c new file mode 100644 index 00000000..9897ca31 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.c @@ -0,0 +1,39 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "h2645data.h" + +const AVRational ff_h2645_pixel_aspect[] = { + { 0, 1 }, + { 1, 1 }, + { 12, 11 }, + { 10, 11 }, + { 16, 11 }, + { 40, 33 }, + { 24, 11 }, + { 20, 11 }, + { 32, 11 }, + { 80, 33 }, + { 18, 11 }, + { 15, 11 }, + { 64, 33 }, + { 160, 99 }, + { 4, 3 }, + { 3, 2 }, + { 2, 1 }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.h b/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.h new file mode 100644 index 00000000..bc56d768 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h2645data.h @@ -0,0 +1,26 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H2645DATA_H +#define AVCODEC_H2645DATA_H + +#include "libavutil/rational.h" + +extern const AVRational ff_h2645_pixel_aspect[17]; + +#endif /* AVCODEC_H2645DATA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_metadata_bsf.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264_metadata_bsf.c index 6efdc924..d318bf0c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_metadata_bsf.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_metadata_bsf.c @@ -29,6 +29,7 @@ #include "h264.h" #include "h264_levels.h" #include "h264_sei.h" +#include "h2645data.h" enum { FLIP_HORIZONTAL = 1, @@ -144,25 +145,17 @@ static int h264_metadata_update_sps(AVBSFContext *bsf, int crop_unit_x, crop_unit_y; if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) { - // Table E-1. - static const AVRational sar_idc[] = { - { 0, 0 }, // Unspecified (never written here). - { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, - { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, - { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, - { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, - }; int num, den, i; av_reduce(&num, &den, ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den, 65535); - for (i = 1; i < FF_ARRAY_ELEMS(sar_idc); i++) { - if (num == sar_idc[i].num && - den == sar_idc[i].den) + for (i = 1; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { + if (num == ff_h2645_pixel_aspect[i].num && + den == ff_h2645_pixel_aspect[i].den) break; } - if (i == FF_ARRAY_ELEMS(sar_idc)) { + if (i == FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { sps->vui.aspect_ratio_idc = 255; sps->vui.sar_width = num; sps->vui.sar_height = den; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_parser.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264_parser.c index 6a433c71..5c6eb37e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_parser.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_parser.c @@ -274,8 +274,8 @@ static inline int parse_nal_units(AVCodecParserContext *s, s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; ff_h264_sei_uninit(&p->sei); - p->sei.frame_packing.arrangement_cancel_flag = -1; - p->sei.unregistered.x264_build = -1; + p->sei.common.frame_packing.arrangement_cancel_flag = -1; + p->sei.common.unregistered.x264_build = -1; if (!buf_size) return 0; @@ -565,7 +565,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, } if (sps->timing_info_present_flag) { int64_t den = sps->time_scale; - if (p->sei.unregistered.x264_build < 44U) + if (p->sei.common.unregistered.x264_build < 44U) den *= 2; av_reduce(&avctx->framerate.den, &avctx->framerate.num, sps->num_units_in_tick * avctx->ticks_per_frame, den, 1 << 30); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.c index e16da68d..d0d1e659 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.c @@ -31,13 +31,12 @@ #include "mathops.h" #include "avcodec.h" #include "h264data.h" +#include "h2645_vui.h" #include "h264_ps.h" #include "golomb.h" #define MIN_LOG2_MAX_FRAME_NUM 4 -#define EXTENDED_SAR 255 - static const uint8_t default_scaling4[2][16] = { { 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 }, @@ -132,58 +131,7 @@ static inline int decode_hrd_parameters(GetBitContext *gb, void *logctx, static inline int decode_vui_parameters(GetBitContext *gb, void *logctx, SPS *sps) { - int aspect_ratio_info_present_flag; - unsigned int aspect_ratio_idc; - - aspect_ratio_info_present_flag = get_bits1(gb); - - if (aspect_ratio_info_present_flag) { - aspect_ratio_idc = get_bits(gb, 8); - if (aspect_ratio_idc == EXTENDED_SAR) { - sps->sar.num = get_bits(gb, 16); - sps->sar.den = get_bits(gb, 16); - } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h264_pixel_aspect)) { - sps->sar = ff_h264_pixel_aspect[aspect_ratio_idc]; - } else { - av_log(logctx, AV_LOG_ERROR, "illegal aspect ratio\n"); - return AVERROR_INVALIDDATA; - } - } else { - sps->sar.num = - sps->sar.den = 0; - } - - if (get_bits1(gb)) /* overscan_info_present_flag */ - get_bits1(gb); /* overscan_appropriate_flag */ - - sps->video_signal_type_present_flag = get_bits1(gb); - if (sps->video_signal_type_present_flag) { - get_bits(gb, 3); /* video_format */ - sps->full_range = get_bits1(gb); /* video_full_range_flag */ - - sps->colour_description_present_flag = get_bits1(gb); - if (sps->colour_description_present_flag) { - sps->color_primaries = get_bits(gb, 8); /* colour_primaries */ - sps->color_trc = get_bits(gb, 8); /* transfer_characteristics */ - sps->colorspace = get_bits(gb, 8); /* matrix_coefficients */ - - // Set invalid values to "unspecified" - if (!av_color_primaries_name(sps->color_primaries)) - sps->color_primaries = AVCOL_PRI_UNSPECIFIED; - if (!av_color_transfer_name(sps->color_trc)) - sps->color_trc = AVCOL_TRC_UNSPECIFIED; - if (!av_color_space_name(sps->colorspace)) - sps->colorspace = AVCOL_SPC_UNSPECIFIED; - } - } - - /* chroma_location_info_present_flag */ - if (get_bits1(gb)) { - /* chroma_sample_location_type_top_field */ - sps->chroma_location = get_ue_golomb_31(gb) + 1; - get_ue_golomb_31(gb); /* chroma_sample_location_type_bottom_field */ - } else - sps->chroma_location = AVCHROMA_LOC_LEFT; + ff_h2645_decode_common_vui_params(gb, &sps->vui, logctx); if (show_bits1(gb) && get_bits_left(gb) < 10) { av_log(logctx, AV_LOG_WARNING, "Truncated VUI (%d)\n", get_bits_left(gb)); @@ -376,12 +324,12 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, sps->profile_idc = profile_idc; sps->constraint_set_flags = constraint_set_flags; sps->level_idc = level_idc; - sps->full_range = -1; + sps->vui.video_full_range_flag = -1; memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); sps->scaling_matrix_present = 0; - sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED + sps->vui.matrix_coeffs = AVCOL_SPC_UNSPECIFIED; if (sps->profile_idc == 100 || // High profile sps->profile_idc == 110 || // High10 profile @@ -598,8 +546,8 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, } } - if (!sps->sar.den) - sps->sar.den = 1; + if (!sps->vui.sar.den) + sps->vui.sar.den = 1; if (avctx->debug & FF_DEBUG_PICT_INFO) { static const char csp[4][5] = { "Gray", "420", "422", "444" }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.h b/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.h index dc52835e..5c35761f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_ps.h @@ -33,6 +33,7 @@ #include "avcodec.h" #include "get_bits.h" #include "h264.h" +#include "h2645_vui.h" #define MAX_SPS_COUNT 32 #define MAX_PPS_COUNT 256 @@ -70,14 +71,7 @@ typedef struct SPS { unsigned int crop_top; ///< frame_cropping_rect_top_offset unsigned int crop_bottom; ///< frame_cropping_rect_bottom_offset int vui_parameters_present_flag; - AVRational sar; - int video_signal_type_present_flag; - int full_range; - int colour_description_present_flag; - enum AVColorPrimaries color_primaries; - enum AVColorTransferCharacteristic color_trc; - enum AVColorSpace colorspace; - enum AVChromaLocation chroma_location; + H2645VUI vui; int timing_info_present_flag; uint32_t num_units_in_tick; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.c index 034ddb8f..66820495 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.c @@ -32,7 +32,7 @@ #include "libavutil/log.h" #include "libavutil/macros.h" #include "libavutil/mem.h" -#include "atsc_a53.h" +#include "bytestream.h" #include "get_bits.h" #include "golomb.h" #include "h264_ps.h" @@ -54,24 +54,22 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->picture_timing.present = 0; h->buffering_period.present = 0; - h->frame_packing.present = 0; - h->film_grain_characteristics.present = 0; - h->display_orientation.present = 0; - h->afd.present = 0; + h->common.frame_packing.present = 0; + h->common.film_grain_characteristics.present = 0; + h->common.display_orientation.present = 0; + h->common.afd.present = 0; - av_buffer_unref(&h->a53_caption.buf_ref); - for (int i = 0; i < h->unregistered.nb_buf_ref; i++) - av_buffer_unref(&h->unregistered.buf_ref[i]); - h->unregistered.nb_buf_ref = 0; - av_freep(&h->unregistered.buf_ref); + ff_h2645_sei_reset(&h->common); } int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, void *logctx) { GetBitContext gb; + av_unused int ret; - init_get_bits(&gb, h->payload, h->payload_size_bits); + ret = init_get_bits8(&gb, h->payload, h->payload_size_bytes); + av_assert1(ret >= 0); if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) { @@ -133,157 +131,23 @@ int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, return 0; } -static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, +static int decode_picture_timing(H264SEIPictureTiming *h, GetByteContext *gb, void *logctx) { - int index = get_bits_count(gb); - int size_bits = get_bits_left(gb); - int size = (size_bits + 7) / 8; + int size = bytestream2_get_bytes_left(gb); - if (index & 7) { - av_log(logctx, AV_LOG_ERROR, "Unaligned SEI payload\n"); - return AVERROR_INVALIDDATA; - } if (size > sizeof(h->payload)) { av_log(logctx, AV_LOG_ERROR, "Picture timing SEI payload too large\n"); return AVERROR_INVALIDDATA; } - memcpy(h->payload, gb->buffer + index / 8, size); + bytestream2_get_bufferu(gb, h->payload, size); - h->payload_size_bits = size_bits; + h->payload_size_bytes = size; h->present = 1; return 0; } -static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size) -{ - int flag; - - if (size-- < 1) - return AVERROR_INVALIDDATA; - skip_bits(gb, 1); // 0 - flag = get_bits(gb, 1); // active_format_flag - skip_bits(gb, 6); // reserved - - if (flag) { - if (size-- < 1) - return AVERROR_INVALIDDATA; - skip_bits(gb, 4); // reserved - h->active_format_description = get_bits(gb, 4); - h->present = 1; - } - - return 0; -} - -static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h, - GetBitContext *gb, void *logctx, - int size) -{ - if (size < 3) - return AVERROR(EINVAL); - - return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size); -} - -static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, - void *logctx, int size) -{ - int country_code, provider_code; - - if (size < 3) - return AVERROR_INVALIDDATA; - size -= 3; - - country_code = get_bits(gb, 8); // itu_t_t35_country_code - if (country_code == 0xFF) { - if (size < 1) - return AVERROR_INVALIDDATA; - - skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte - size--; - } - - if (country_code != 0xB5) { // usa_country_code - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n", - country_code); - return 0; - } - - /* itu_t_t35_payload_byte follows */ - provider_code = get_bits(gb, 16); - - switch (provider_code) { - case 0x31: { // atsc_provider_code - uint32_t user_identifier; - - if (size < 4) - return AVERROR_INVALIDDATA; - size -= 4; - - user_identifier = get_bits_long(gb, 32); - switch (user_identifier) { - case MKBETAG('D', 'T', 'G', '1'): // afd_data - return decode_registered_user_data_afd(&h->afd, gb, size); - case MKBETAG('G', 'A', '9', '4'): // closed captions - return decode_registered_user_data_closed_caption(&h->a53_caption, gb, - logctx, size); - default: - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", - user_identifier); - break; - } - break; - } - default: - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n", - provider_code); - break; - } - - return 0; -} - -static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb, - void *logctx, int size) -{ - uint8_t *user_data; - int e, build, i; - AVBufferRef *buf_ref, **tmp; - - if (size < 16 || size >= INT_MAX - 1) - return AVERROR_INVALIDDATA; - - tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); - if (!tmp) - return AVERROR(ENOMEM); - h->buf_ref = tmp; - - buf_ref = av_buffer_alloc(size + 1); - if (!buf_ref) - return AVERROR(ENOMEM); - user_data = buf_ref->data; - - for (i = 0; i < size; i++) - user_data[i] = get_bits(gb, 8); - - user_data[i] = 0; - buf_ref->size = size; - h->buf_ref[h->nb_buf_ref++] = buf_ref; - - e = sscanf(user_data + 16, "x264 - core %d", &build); - if (e == 1 && build > 0) - h->x264_build = build; - if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16)) - h->x264_build = 67; - - return 0; -} - static int decode_recovery_point(H264SEIRecoveryPoint *h, GetBitContext *gb, void *logctx) { unsigned recovery_frame_cnt = get_ue_golomb_long(gb); @@ -339,122 +203,26 @@ static int decode_buffering_period(H264SEIBufferingPeriod *h, GetBitContext *gb, return 0; } -static int decode_frame_packing_arrangement(H264SEIFramePacking *h, - GetBitContext *gb) +static int decode_green_metadata(H264SEIGreenMetaData *h, GetByteContext *gb) { - h->arrangement_id = get_ue_golomb_long(gb); - h->arrangement_cancel_flag = get_bits1(gb); - h->present = !h->arrangement_cancel_flag; - - if (h->present) { - h->arrangement_type = get_bits(gb, 7); - h->quincunx_sampling_flag = get_bits1(gb); - h->content_interpretation_type = get_bits(gb, 6); - - // spatial_flipping_flag, frame0_flipped_flag, field_views_flag - skip_bits(gb, 3); - h->current_frame_is_frame0_flag = get_bits1(gb); - // frame0_self_contained_flag, frame1_self_contained_flag - skip_bits(gb, 2); - - if (!h->quincunx_sampling_flag && h->arrangement_type != 5) - skip_bits(gb, 16); // frame[01]_grid_position_[xy] - skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte - h->arrangement_repetition_period = get_ue_golomb_long(gb); - } - skip_bits1(gb); // frame_packing_arrangement_extension_flag - - return 0; -} - -static int decode_display_orientation(H264SEIDisplayOrientation *h, - GetBitContext *gb) -{ - h->present = !get_bits1(gb); - - if (h->present) { - h->hflip = get_bits1(gb); // hor_flip - h->vflip = get_bits1(gb); // ver_flip - - h->anticlockwise_rotation = get_bits(gb, 16); - get_ue_golomb_long(gb); // display_orientation_repetition_period - skip_bits1(gb); // display_orientation_extension_flag - } - - return 0; -} - -static int decode_green_metadata(H264SEIGreenMetaData *h, GetBitContext *gb) -{ - h->green_metadata_type = get_bits(gb, 8); + h->green_metadata_type = bytestream2_get_byte(gb); if (h->green_metadata_type == 0) { - h->period_type = get_bits(gb, 8); + h->period_type = bytestream2_get_byte(gb); if (h->period_type == 2) - h->num_seconds = get_bits(gb, 16); + h->num_seconds = bytestream2_get_be16(gb); else if (h->period_type == 3) - h->num_pictures = get_bits(gb, 16); + h->num_pictures = bytestream2_get_be16(gb); - h->percent_non_zero_macroblocks = get_bits(gb, 8); - h->percent_intra_coded_macroblocks = get_bits(gb, 8); - h->percent_six_tap_filtering = get_bits(gb, 8); - h->percent_alpha_point_deblocking_instance = get_bits(gb, 8); + h->percent_non_zero_macroblocks = bytestream2_get_byte(gb); + h->percent_intra_coded_macroblocks = bytestream2_get_byte(gb); + h->percent_six_tap_filtering = bytestream2_get_byte(gb); + h->percent_alpha_point_deblocking_instance = bytestream2_get_byte(gb); } else if (h->green_metadata_type == 1) { - h->xsd_metric_type = get_bits(gb, 8); - h->xsd_metric_value = get_bits(gb, 16); - } - - return 0; -} - -static int decode_alternative_transfer(H264SEIAlternativeTransfer *h, - GetBitContext *gb) -{ - h->present = 1; - h->preferred_transfer_characteristics = get_bits(gb, 8); - return 0; -} - -static int decode_film_grain_characteristics(H264SEIFilmGrainCharacteristics *h, - GetBitContext *gb) -{ - h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag - - if (h->present) { - memset(h, 0, sizeof(*h)); - h->model_id = get_bits(gb, 2); - h->separate_colour_description_present_flag = get_bits1(gb); - if (h->separate_colour_description_present_flag) { - h->bit_depth_luma = get_bits(gb, 3) + 8; - h->bit_depth_chroma = get_bits(gb, 3) + 8; - h->full_range = get_bits1(gb); - h->color_primaries = get_bits(gb, 8); - h->transfer_characteristics = get_bits(gb, 8); - h->matrix_coeffs = get_bits(gb, 8); - } - h->blending_mode_id = get_bits(gb, 2); - h->log2_scale_factor = get_bits(gb, 4); - for (int c = 0; c < 3; c++) - h->comp_model_present_flag[c] = get_bits1(gb); - for (int c = 0; c < 3; c++) { - if (h->comp_model_present_flag[c]) { - h->num_intensity_intervals[c] = get_bits(gb, 8) + 1; - h->num_model_values[c] = get_bits(gb, 3) + 1; - if (h->num_model_values[c] > 6) - return AVERROR_INVALIDDATA; - for (int i = 0; i < h->num_intensity_intervals[c]; i++) { - h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8); - h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8); - for (int j = 0; j < h->num_model_values[c]; j++) - h->comp_model_value[c][i][j] = get_se_golomb_long(gb); - } - } - } - h->repetition_period = get_ue_golomb_long(gb); - - h->present = 1; + h->xsd_metric_type = bytestream2_get_byte(gb); + h->xsd_metric_value = bytestream2_get_be16(gb); } return 0; @@ -463,45 +231,46 @@ static int decode_film_grain_characteristics(H264SEIFilmGrainCharacteristics *h, int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, const H264ParamSets *ps, void *logctx) { + GetByteContext gbyte; int master_ret = 0; - while (get_bits_left(gb) > 16 && show_bits(gb, 16)) { + av_assert1((get_bits_count(gb) % 8) == 0); + bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8, + get_bits_left(gb) / 8); + + while (bytestream2_get_bytes_left(&gbyte) > 2 && bytestream2_peek_ne16(&gbyte)) { + GetByteContext gbyte_payload; GetBitContext gb_payload; int type = 0; unsigned size = 0; int ret = 0; do { - if (get_bits_left(gb) < 8) + if (bytestream2_get_bytes_left(&gbyte) <= 0) return AVERROR_INVALIDDATA; - type += show_bits(gb, 8); - } while (get_bits(gb, 8) == 255); + type += bytestream2_peek_byteu(&gbyte); + } while (bytestream2_get_byteu(&gbyte) == 255); do { - if (get_bits_left(gb) < 8) + if (bytestream2_get_bytes_left(&gbyte) <= 0) return AVERROR_INVALIDDATA; - size += show_bits(gb, 8); - } while (get_bits(gb, 8) == 255); + size += bytestream2_peek_byteu(&gbyte); + } while (bytestream2_get_byteu(&gbyte) == 255); - if (size > get_bits_left(gb) / 8) { + if (size > bytestream2_get_bytes_left(&gbyte)) { av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", - type, 8*size, get_bits_left(gb)); + type, size, bytestream2_get_bytes_left(&gbyte)); return AVERROR_INVALIDDATA; } - ret = init_get_bits8(&gb_payload, gb->buffer + get_bits_count(gb) / 8, size); + bytestream2_init (&gbyte_payload, gbyte.buffer, size); + ret = init_get_bits8(&gb_payload, gbyte.buffer, size); if (ret < 0) return ret; switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI - ret = decode_picture_timing(&h->picture_timing, &gb_payload, logctx); - break; - case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - ret = decode_registered_user_data(h, &gb_payload, logctx, size); - break; - case SEI_TYPE_USER_DATA_UNREGISTERED: - ret = decode_unregistered_user_data(&h->unregistered, &gb_payload, logctx, size); + ret = decode_picture_timing(&h->picture_timing, &gbyte_payload, logctx); break; case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(&h->recovery_point, &gb_payload, logctx); @@ -509,23 +278,14 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, case SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(&h->buffering_period, &gb_payload, ps, logctx); break; - case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: - ret = decode_frame_packing_arrangement(&h->frame_packing, &gb_payload); - break; - case SEI_TYPE_DISPLAY_ORIENTATION: - ret = decode_display_orientation(&h->display_orientation, &gb_payload); - break; case SEI_TYPE_GREEN_METADATA: - ret = decode_green_metadata(&h->green_metadata, &gb_payload); - break; - case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: - ret = decode_alternative_transfer(&h->alternative_transfer, &gb_payload); - break; - case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: - ret = decode_film_grain_characteristics(&h->film_grain_characteristics, &gb_payload); + ret = decode_green_metadata(&h->green_metadata, &gbyte_payload); break; default: - av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); + ret = ff_h2645_sei_message_decode(&h->common, type, AV_CODEC_ID_H264, + &gb_payload, &gbyte_payload, logctx); + if (ret == FF_H2645_SEI_MESSAGE_UNHANDLED) + av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); } if (ret < 0 && ret != AVERROR_PS_NOT_FOUND) return ret; @@ -537,47 +297,47 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, type, -get_bits_left(&gb_payload)); } - skip_bits_long(gb, 8 * size); + bytestream2_skipu(&gbyte, size); } return master_ret; } -const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h) +const char *ff_h264_sei_stereo_mode(const H2645SEIFramePacking *h) { if (h->arrangement_cancel_flag == 0) { switch (h->arrangement_type) { - case H264_SEI_FPA_TYPE_CHECKERBOARD: + case SEI_FPA_H264_TYPE_CHECKERBOARD: if (h->content_interpretation_type == 2) return "checkerboard_rl"; else return "checkerboard_lr"; - case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN: + case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN: if (h->content_interpretation_type == 2) return "col_interleaved_rl"; else return "col_interleaved_lr"; - case H264_SEI_FPA_TYPE_INTERLEAVE_ROW: + case SEI_FPA_H264_TYPE_INTERLEAVE_ROW: if (h->content_interpretation_type == 2) return "row_interleaved_rl"; else return "row_interleaved_lr"; - case H264_SEI_FPA_TYPE_SIDE_BY_SIDE: + case SEI_FPA_TYPE_SIDE_BY_SIDE: if (h->content_interpretation_type == 2) return "right_left"; else return "left_right"; - case H264_SEI_FPA_TYPE_TOP_BOTTOM: + case SEI_FPA_TYPE_TOP_BOTTOM: if (h->content_interpretation_type == 2) return "bottom_top"; else return "top_bottom"; - case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: + case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: if (h->content_interpretation_type == 2) return "block_rl"; else return "block_lr"; - case H264_SEI_FPA_TYPE_2D: + case SEI_FPA_H264_TYPE_2D: default: return "mono"; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.h b/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.h index f9166b45..bb9275e5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_sei.h @@ -20,6 +20,7 @@ #define AVCODEC_H264_SEI_H #include "get_bits.h" +#include "h2645_sei.h" #include "h264_ps.h" #include "sei.h" @@ -39,19 +40,6 @@ typedef enum { H264_SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling } H264_SEI_PicStructType; -/** - * frame_packing_arrangement types - */ -typedef enum { - H264_SEI_FPA_TYPE_CHECKERBOARD = 0, - H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, - H264_SEI_FPA_TYPE_INTERLEAVE_ROW = 2, - H264_SEI_FPA_TYPE_SIDE_BY_SIDE = 3, - H264_SEI_FPA_TYPE_TOP_BOTTOM = 4, - H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, - H264_SEI_FPA_TYPE_2D = 6, -} H264_SEI_FpaType; - typedef struct H264SEITimeCode { /* When not continuously receiving full timecodes, we have to reference the previous timecode received */ @@ -66,7 +54,7 @@ typedef struct H264SEITimeCode { typedef struct H264SEIPictureTiming { // maximum size of pic_timing according to the spec should be 274 bits uint8_t payload[40]; - int payload_size_bits; + int payload_size_bytes; int present; H264_SEI_PicStructType pic_struct; @@ -99,21 +87,6 @@ typedef struct H264SEIPictureTiming { int timecode_cnt; } H264SEIPictureTiming; -typedef struct H264SEIAFD { - int present; - uint8_t active_format_description; -} H264SEIAFD; - -typedef struct H264SEIA53Caption { - AVBufferRef *buf_ref; -} H264SEIA53Caption; - -typedef struct H264SEIUnregistered { - int x264_build; - AVBufferRef **buf_ref; - int nb_buf_ref; -} H264SEIUnregistered; - typedef struct H264SEIRecoveryPoint { /** * recovery_frame_cnt @@ -130,23 +103,6 @@ typedef struct H264SEIBufferingPeriod { int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs } H264SEIBufferingPeriod; -typedef struct H264SEIFramePacking { - int present; - int arrangement_id; - int arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received - H264_SEI_FpaType arrangement_type; - int arrangement_repetition_period; - int content_interpretation_type; - int quincunx_sampling_flag; - int current_frame_is_frame0_flag; -} H264SEIFramePacking; - -typedef struct H264SEIDisplayOrientation { - int present; - int anticlockwise_rotation; - int hflip, vflip; -} H264SEIDisplayOrientation; - typedef struct H264SEIGreenMetaData { uint8_t green_metadata_type; uint8_t period_type; @@ -160,44 +116,12 @@ typedef struct H264SEIGreenMetaData { uint16_t xsd_metric_value; } H264SEIGreenMetaData; -typedef struct H264SEIAlternativeTransfer { - int present; - int preferred_transfer_characteristics; -} H264SEIAlternativeTransfer; - -typedef struct H264SEIFilmGrainCharacteristics { - int present; - int model_id; - int separate_colour_description_present_flag; - int bit_depth_luma; - int bit_depth_chroma; - int full_range; - int color_primaries; - int transfer_characteristics; - int matrix_coeffs; - int blending_mode_id; - int log2_scale_factor; - int comp_model_present_flag[3]; - uint16_t num_intensity_intervals[3]; - uint8_t num_model_values[3]; - uint8_t intensity_interval_lower_bound[3][256]; - uint8_t intensity_interval_upper_bound[3][256]; - int16_t comp_model_value[3][256][6]; - int repetition_period; -} H264SEIFilmGrainCharacteristics; - typedef struct H264SEIContext { + H2645SEI common; H264SEIPictureTiming picture_timing; - H264SEIAFD afd; - H264SEIA53Caption a53_caption; - H264SEIUnregistered unregistered; H264SEIRecoveryPoint recovery_point; H264SEIBufferingPeriod buffering_period; - H264SEIFramePacking frame_packing; - H264SEIDisplayOrientation display_orientation; H264SEIGreenMetaData green_metadata; - H264SEIAlternativeTransfer alternative_transfer; - H264SEIFilmGrainCharacteristics film_grain_characteristics; } H264SEIContext; struct H264ParamSets; @@ -205,6 +129,12 @@ struct H264ParamSets; int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, const struct H264ParamSets *ps, void *logctx); +static inline int ff_h264_sei_ctx_replace(H264SEIContext *dst, + const H264SEIContext *src) +{ + return ff_h2645_sei_ctx_replace(&dst->common, &src->common); +} + /** * Reset SEI values at the beginning of the frame. */ @@ -213,7 +143,7 @@ void ff_h264_sei_uninit(H264SEIContext *h); /** * Get stereo_mode string from the h264 frame_packing_arrangement */ -const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h); +const char *ff_h264_sei_stereo_mode(const H2645SEIFramePacking *h); /** * Parse the contents of a picture timing message given an active SPS. diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264_slice.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264_slice.c index 6f0a7c1f..6188c746 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264_slice.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264_slice.c @@ -31,7 +31,6 @@ #include "libavutil/display.h" #include "libavutil/film_grain_params.h" #include "libavutil/pixdesc.h" -#include "libavutil/stereo3d.h" #include "libavutil/timecode.h" #include "internal.h" #include "cabac.h" @@ -328,7 +327,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, !h->ps.sps || h->ps.sps->bit_depth_luma != h1->ps.sps->bit_depth_luma || h->ps.sps->chroma_format_idc != h1->ps.sps->chroma_format_idc || - h->ps.sps->colorspace != h1->ps.sps->colorspace)) { + h->ps.sps->vui.matrix_coeffs != h1->ps.sps->vui.matrix_coeffs)) { need_reinit = 1; } @@ -434,29 +433,11 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->frame_recovered = h1->frame_recovered; - ret = av_buffer_replace(&h->sei.a53_caption.buf_ref, h1->sei.a53_caption.buf_ref); + ret = ff_h264_sei_ctx_replace(&h->sei, &h1->sei); if (ret < 0) return ret; - for (i = 0; i < h->sei.unregistered.nb_buf_ref; i++) - av_buffer_unref(&h->sei.unregistered.buf_ref[i]); - h->sei.unregistered.nb_buf_ref = 0; - - if (h1->sei.unregistered.nb_buf_ref) { - ret = av_reallocp_array(&h->sei.unregistered.buf_ref, - h1->sei.unregistered.nb_buf_ref, - sizeof(*h->sei.unregistered.buf_ref)); - if (ret < 0) - return ret; - - for (i = 0; i < h1->sei.unregistered.nb_buf_ref; i++) { - h->sei.unregistered.buf_ref[i] = av_buffer_ref(h1->sei.unregistered.buf_ref[i]); - if (!h->sei.unregistered.buf_ref[i]) - return AVERROR(ENOMEM); - h->sei.unregistered.nb_buf_ref++; - } - } - h->sei.unregistered.x264_build = h1->sei.unregistered.x264_build; + h->sei.common.unregistered.x264_build = h1->sei.common.unregistered.x264_build; if (!h->cur_pic_ptr) return 0; @@ -529,7 +510,7 @@ static int h264_frame_start(H264Context *h) pic->f->crop_top = h->crop_top; pic->f->crop_bottom = h->crop_bottom; - pic->needs_fg = h->sei.film_grain_characteristics.present && !h->avctx->hwaccel && + pic->needs_fg = h->sei.common.film_grain_characteristics.present && !h->avctx->hwaccel && !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN); if ((ret = alloc_picture(h, pic)) < 0) @@ -580,8 +561,8 @@ static int h264_frame_start(H264Context *h) h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME); - if (h->sei.unregistered.x264_build >= 0) - h->x264_build = h->sei.unregistered.x264_build; + if (h->sei.common.unregistered.x264_build >= 0) + h->x264_build = h->sei.common.unregistered.x264_build; assert(h->cur_pic_ptr->long_ref == 0); @@ -956,7 +937,7 @@ static int h264_slice_header_init(H264Context *h) goto fail; } - ff_set_sar(h->avctx, sps->sar); + ff_set_sar(h->avctx, sps->vui.sar); av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, &h->chroma_x_shift, &h->chroma_y_shift); @@ -1081,7 +1062,7 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0)))) must_reinit = 1; - if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio)) + if (first_slice && av_cmp_q(sps->vui.sar, h->avctx->sample_aspect_ratio)) must_reinit = 1; if (!h->setup_finished) { @@ -1103,25 +1084,25 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl init_dimensions(h); - if (sps->video_signal_type_present_flag) { - h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG - : AVCOL_RANGE_MPEG; - if (sps->colour_description_present_flag) { - if (h->avctx->colorspace != sps->colorspace) + if (sps->vui.video_signal_type_present_flag) { + h->avctx->color_range = sps->vui.video_full_range_flag > 0 ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; + if (sps->vui.colour_description_present_flag) { + if (h->avctx->colorspace != sps->vui.matrix_coeffs) needs_reinit = 1; - h->avctx->color_primaries = sps->color_primaries; - h->avctx->color_trc = sps->color_trc; - h->avctx->colorspace = sps->colorspace; + h->avctx->color_primaries = sps->vui.colour_primaries; + h->avctx->color_trc = sps->vui.transfer_characteristics; + h->avctx->colorspace = sps->vui.matrix_coeffs; } } - if (h->sei.alternative_transfer.present && - av_color_transfer_name(h->sei.alternative_transfer.preferred_transfer_characteristics) && - h->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { - h->avctx->color_trc = h->sei.alternative_transfer.preferred_transfer_characteristics; + if (h->sei.common.alternative_transfer.present && + av_color_transfer_name(h->sei.common.alternative_transfer.preferred_transfer_characteristics) && + h->sei.common.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { + h->avctx->color_trc = h->sei.common.alternative_transfer.preferred_transfer_characteristics; } } - h->avctx->chroma_sample_location = sps->chroma_location; + h->avctx->chroma_sample_location = sps->vui.chroma_location; if (!h->context_initialized || must_reinit || needs_reinit) { int flush_changes = h->context_initialized; @@ -1163,6 +1144,7 @@ static int h264_export_frame_props(H264Context *h) const SPS *sps = h->ps.sps; H264Picture *cur = h->cur_pic_ptr; AVFrame *out = cur->f; + int ret; out->interlaced_frame = 0; out->repeat_pict = 0; @@ -1244,166 +1226,11 @@ static int h264_export_frame_props(H264Context *h) } } - if (h->sei.frame_packing.present && - h->sei.frame_packing.arrangement_type <= 6 && - h->sei.frame_packing.content_interpretation_type > 0 && - h->sei.frame_packing.content_interpretation_type < 3) { - H264SEIFramePacking *fp = &h->sei.frame_packing; - AVStereo3D *stereo = av_stereo3d_create_side_data(out); - if (stereo) { - switch (fp->arrangement_type) { - case H264_SEI_FPA_TYPE_CHECKERBOARD: - stereo->type = AV_STEREO3D_CHECKERBOARD; - break; - case H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN: - stereo->type = AV_STEREO3D_COLUMNS; - break; - case H264_SEI_FPA_TYPE_INTERLEAVE_ROW: - stereo->type = AV_STEREO3D_LINES; - break; - case H264_SEI_FPA_TYPE_SIDE_BY_SIDE: - if (fp->quincunx_sampling_flag) - stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; - else - stereo->type = AV_STEREO3D_SIDEBYSIDE; - break; - case H264_SEI_FPA_TYPE_TOP_BOTTOM: - stereo->type = AV_STEREO3D_TOPBOTTOM; - break; - case H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: - stereo->type = AV_STEREO3D_FRAMESEQUENCE; - break; - case H264_SEI_FPA_TYPE_2D: - stereo->type = AV_STEREO3D_2D; - break; - } - - if (fp->content_interpretation_type == 2) - stereo->flags = AV_STEREO3D_FLAG_INVERT; - - if (fp->arrangement_type == H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) { - if (fp->current_frame_is_frame0_flag) - stereo->view = AV_STEREO3D_VIEW_LEFT; - else - stereo->view = AV_STEREO3D_VIEW_RIGHT; - } - } - } - - if (h->sei.display_orientation.present && - (h->sei.display_orientation.anticlockwise_rotation || - h->sei.display_orientation.hflip || - h->sei.display_orientation.vflip)) { - H264SEIDisplayOrientation *o = &h->sei.display_orientation; - double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); - AVFrameSideData *rotation = av_frame_new_side_data(out, - AV_FRAME_DATA_DISPLAYMATRIX, - sizeof(int32_t) * 9); - if (rotation) { - /* av_display_rotation_set() expects the angle in the clockwise - * direction, hence the first minus. - * The below code applies the flips after the rotation, yet - * the H.2645 specs require flipping to be applied first. - * Because of R O(phi) = O(-phi) R (where R is flipping around - * an arbitatry axis and O(phi) is the proper rotation by phi) - * we can create display matrices as desired by negating - * the degree once for every flip applied. */ - angle = -angle * (1 - 2 * !!o->hflip) * (1 - 2 * !!o->vflip); - av_display_rotation_set((int32_t *)rotation->data, angle); - av_display_matrix_flip((int32_t *)rotation->data, - o->hflip, o->vflip); - } - } - - if (h->sei.afd.present) { - AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD, - sizeof(uint8_t)); - - if (sd) { - *sd->data = h->sei.afd.active_format_description; - h->sei.afd.present = 0; - } - } - - if (h->sei.a53_caption.buf_ref) { - H264SEIA53Caption *a53 = &h->sei.a53_caption; - - AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref); - if (!sd) - av_buffer_unref(&a53->buf_ref); - a53->buf_ref = NULL; - - h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; - } - - for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { - H264SEIUnregistered *unreg = &h->sei.unregistered; - - if (unreg->buf_ref[i]) { - AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, - AV_FRAME_DATA_SEI_UNREGISTERED, - unreg->buf_ref[i]); - if (!sd) - av_buffer_unref(&unreg->buf_ref[i]); - unreg->buf_ref[i] = NULL; - } - } - h->sei.unregistered.nb_buf_ref = 0; - - if (h->sei.film_grain_characteristics.present) { - H264SEIFilmGrainCharacteristics *fgc = &h->sei.film_grain_characteristics; - AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(out); - if (!fgp) - return AVERROR(ENOMEM); - - fgp->type = AV_FILM_GRAIN_PARAMS_H274; - fgp->seed = cur->poc + (h->poc_offset << 5); - - fgp->codec.h274.model_id = fgc->model_id; - if (fgc->separate_colour_description_present_flag) { - fgp->codec.h274.bit_depth_luma = fgc->bit_depth_luma; - fgp->codec.h274.bit_depth_chroma = fgc->bit_depth_chroma; - fgp->codec.h274.color_range = fgc->full_range + 1; - fgp->codec.h274.color_primaries = fgc->color_primaries; - fgp->codec.h274.color_trc = fgc->transfer_characteristics; - fgp->codec.h274.color_space = fgc->matrix_coeffs; - } else { - fgp->codec.h274.bit_depth_luma = sps->bit_depth_luma; - fgp->codec.h274.bit_depth_chroma = sps->bit_depth_chroma; - if (sps->video_signal_type_present_flag) - fgp->codec.h274.color_range = sps->full_range + 1; - else - fgp->codec.h274.color_range = AVCOL_RANGE_UNSPECIFIED; - if (sps->colour_description_present_flag) { - fgp->codec.h274.color_primaries = sps->color_primaries; - fgp->codec.h274.color_trc = sps->color_trc; - fgp->codec.h274.color_space = sps->colorspace; - } else { - fgp->codec.h274.color_primaries = AVCOL_PRI_UNSPECIFIED; - fgp->codec.h274.color_trc = AVCOL_TRC_UNSPECIFIED; - fgp->codec.h274.color_space = AVCOL_SPC_UNSPECIFIED; - } - } - fgp->codec.h274.blending_mode_id = fgc->blending_mode_id; - fgp->codec.h274.log2_scale_factor = fgc->log2_scale_factor; - - memcpy(&fgp->codec.h274.component_model_present, &fgc->comp_model_present_flag, - sizeof(fgp->codec.h274.component_model_present)); - memcpy(&fgp->codec.h274.num_intensity_intervals, &fgc->num_intensity_intervals, - sizeof(fgp->codec.h274.num_intensity_intervals)); - memcpy(&fgp->codec.h274.num_model_values, &fgc->num_model_values, - sizeof(fgp->codec.h274.num_model_values)); - memcpy(&fgp->codec.h274.intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound, - sizeof(fgp->codec.h274.intensity_interval_lower_bound)); - memcpy(&fgp->codec.h274.intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound, - sizeof(fgp->codec.h274.intensity_interval_upper_bound)); - memcpy(&fgp->codec.h274.comp_model_value, &fgc->comp_model_value, - sizeof(fgp->codec.h274.comp_model_value)); - - fgc->present = !!fgc->repetition_period; - - h->avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN; - } + ret = ff_h2645_sei_to_frame(out, &h->sei.common, AV_CODEC_ID_H264, h->avctx, + &sps->vui, sps->bit_depth_luma, sps->bit_depth_chroma, + cur->poc + (unsigned)(h->poc_offset << 5)); + if (ret < 0) + return ret; if (h->sei.picture_timing.timecode_cnt > 0) { uint32_t *tc_sd; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264data.h b/arm/raspi/third_party/ffmpeg/libavcodec/h264data.h index 4efe76a3..f809886a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264data.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264data.h @@ -49,26 +49,6 @@ extern const PMbInfo ff_h264_p_sub_mb_type_info[4]; extern const PMbInfo ff_h264_b_mb_type_info[23]; extern const PMbInfo ff_h264_b_sub_mb_type_info[13]; -static const AVRational ff_h264_pixel_aspect[17] = { - { 0, 1 }, - { 1, 1 }, - { 12, 11 }, - { 10, 11 }, - { 16, 11 }, - { 40, 33 }, - { 24, 11 }, - { 20, 11 }, - { 32, 11 }, - { 80, 33 }, - { 18, 11 }, - { 15, 11 }, - { 64, 33 }, - { 160, 99 }, - { 4, 3 }, - { 3, 2 }, - { 2, 1 }, -}; - extern const uint8_t ff_h264_dequant4_coeff_init[6][3]; extern const uint8_t ff_h264_dequant8_coeff_init_scan[16]; extern const uint8_t ff_h264_dequant8_coeff_init[6][6]; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h264dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/h264dec.c index cd0a8fdb..82288425 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h264dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h264dec.c @@ -296,8 +296,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->recovery_frame = -1; h->frame_recovered = 0; h->poc.prev_frame_num = -1; - h->sei.frame_packing.arrangement_cancel_flag = -1; - h->sei.unregistered.x264_build = -1; + h->sei.common.frame_packing.arrangement_cancel_flag = -1; + h->sei.common.unregistered.x264_build = -1; h->next_outputed_poc = INT_MIN; for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) @@ -852,7 +852,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) if (srcp->needs_fg && (ret = av_frame_copy_props(dst, srcp->f)) < 0) return ret; - av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.frame_packing), 0); + av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.common.frame_packing), 0); if (srcp->sei_recovery_frame_cnt == 0) dst->key_frame = 1; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h265_metadata_bsf.c b/arm/raspi/third_party/ffmpeg/libavcodec/h265_metadata_bsf.c index ffcbbf01..6787bd14 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h265_metadata_bsf.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h265_metadata_bsf.c @@ -24,6 +24,7 @@ #include "cbs.h" #include "cbs_bsf.h" #include "cbs_h265.h" +#include "h2645data.h" #include "hevc.h" #include "h265_profile_level.h" @@ -194,25 +195,17 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, int crop_unit_x, crop_unit_y; if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) { - // Table E-1. - static const AVRational sar_idc[] = { - { 0, 0 }, // Unspecified (never written here). - { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, - { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, - { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, - { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, - }; int num, den, i; av_reduce(&num, &den, ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den, 65535); - for (i = 1; i < FF_ARRAY_ELEMS(sar_idc); i++) { - if (num == sar_idc[i].num && - den == sar_idc[i].den) + for (i = 1; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { + if (num == ff_h2645_pixel_aspect[i].num && + den == ff_h2645_pixel_aspect[i].den) break; } - if (i == FF_ARRAY_ELEMS(sar_idc)) { + if (i == FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { sps->vui.aspect_ratio_idc = 255; sps->vui.sar_width = num; sps->vui.sar_height = den; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/h274.h b/arm/raspi/third_party/ffmpeg/libavcodec/h274.h index 807b3a01..920f6991 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/h274.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/h274.h @@ -28,7 +28,7 @@ #ifndef AVCODEC_H274_H #define AVCODEC_H274_H -#include +#include "libavutil/film_grain_params.h" // Must be initialized to {0} prior to first usage typedef struct H274FilmGrainDatabase { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hapenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/hapenc.c index a890dc64..7de7358e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hapenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hapenc.c @@ -351,7 +351,8 @@ const FFCodec ff_hap_encoder = { CODEC_LONG_NAME("Vidvox Hap"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_HAP, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(HapContext), .p.priv_class = &hapenc_class, .init = hap_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hdrdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/hdrdec.c index 21d3e7f6..99822774 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hdrdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hdrdec.c @@ -58,6 +58,8 @@ static int decompress(uint8_t *scanline, int w, GetByteContext *gb, const uint8_ int rshift = 0; while (w > 0) { + if (bytestream2_get_bytes_left(gb) < 4) + return AVERROR_INVALIDDATA; scanline[0] = bytestream2_get_byte(gb); scanline[1] = bytestream2_get_byte(gb); scanline[2] = bytestream2_get_byte(gb); @@ -143,13 +145,17 @@ static int hdr_decode_frame(AVCodecContext *avctx, AVFrame *p, int i; if (width < MINELEN || width > MAXELEN) { - decompress(scanline, width, &gb, scanline); + ret = decompress(scanline, width, &gb, scanline); + if (ret < 0) + return ret; goto convert; } i = bytestream2_peek_byte(&gb); if (i != 2) { - decompress(scanline, width, &gb, scanline); + ret = decompress(scanline, width, &gb, scanline); + if (ret < 0) + return ret; goto convert; } bytestream2_skip(&gb, 1); @@ -161,7 +167,9 @@ static int hdr_decode_frame(AVCodecContext *avctx, AVFrame *p, if (scanline[1] != 2 || scanline[2] & 128) { scanline[0] = 2; scanline[3] = i; - decompress(scanline + 4, width - 1, &gb, scanline); + ret = decompress(scanline + 4, width - 1, &gb, scanline); + if (ret < 0) + return ret; goto convert; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hdrenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/hdrenc.c index d8c3111c..40d283ee 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hdrenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hdrenc.c @@ -177,7 +177,8 @@ const FFCodec ff_hdr_encoder = { .priv_data_size = sizeof(HDREncContext), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_RADIANCE_HDR, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = hdr_encode_init, FF_CODEC_ENCODE_CB(hdr_encode_frame), .close = hdr_encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.c b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.c index f665d805..5fe62ec3 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.c @@ -25,6 +25,7 @@ #include "libavutil/imgutils.h" #include "golomb.h" +#include "h2645_vui.h" #include "hevc_data.h" #include "hevc_ps.h" @@ -50,26 +51,6 @@ static const uint8_t default_scaling_list_inter[] = { 24, 25, 28, 33, 41, 54, 71, 91 }; -static const AVRational vui_sar[] = { - { 0, 1 }, - { 1, 1 }, - { 12, 11 }, - { 10, 11 }, - { 16, 11 }, - { 40, 33 }, - { 24, 11 }, - { 20, 11 }, - { 32, 11 }, - { 80, 33 }, - { 18, 11 }, - { 15, 11 }, - { 64, 33 }, - { 160, 99 }, - { 4, 3 }, - { 3, 2 }, - { 2, 1 }, -}; - static const uint8_t hevc_sub_width_c[] = { 1, 2, 2, 1 }; @@ -587,47 +568,15 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, { VUI backup_vui, *vui = &sps->vui; GetBitContext backup; - int sar_present, alt = 0; + int alt = 0; - av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n"); + ff_h2645_decode_common_vui_params(gb, &sps->vui.common, avctx); - sar_present = get_bits1(gb); - if (sar_present) { - uint8_t sar_idx = get_bits(gb, 8); - if (sar_idx < FF_ARRAY_ELEMS(vui_sar)) - vui->sar = vui_sar[sar_idx]; - else if (sar_idx == 255) { - vui->sar.num = get_bits(gb, 16); - vui->sar.den = get_bits(gb, 16); - } else - av_log(avctx, AV_LOG_WARNING, - "Unknown SAR index: %u.\n", sar_idx); - } - - vui->overscan_info_present_flag = get_bits1(gb); - if (vui->overscan_info_present_flag) - vui->overscan_appropriate_flag = get_bits1(gb); - - vui->video_signal_type_present_flag = get_bits1(gb); - if (vui->video_signal_type_present_flag) { - vui->video_format = get_bits(gb, 3); - vui->video_full_range_flag = get_bits1(gb); - vui->colour_description_present_flag = get_bits1(gb); - if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P) + if (vui->common.video_signal_type_present_flag) { + if (vui->common.video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P) sps->pix_fmt = AV_PIX_FMT_YUVJ420P; - if (vui->colour_description_present_flag) { - vui->colour_primaries = get_bits(gb, 8); - vui->transfer_characteristic = get_bits(gb, 8); - vui->matrix_coeffs = get_bits(gb, 8); - - // Set invalid values to "unspecified" - if (!av_color_primaries_name(vui->colour_primaries)) - vui->colour_primaries = AVCOL_PRI_UNSPECIFIED; - if (!av_color_transfer_name(vui->transfer_characteristic)) - vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED; - if (!av_color_space_name(vui->matrix_coeffs)) - vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED; - if (vui->matrix_coeffs == AVCOL_SPC_RGB) { + if (vui->common.colour_description_present_flag) { + if (vui->common.matrix_coeffs == AVCOL_SPC_RGB) { switch (sps->pix_fmt) { case AV_PIX_FMT_YUV444P: sps->pix_fmt = AV_PIX_FMT_GBRP; @@ -643,12 +592,6 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, } } - vui->chroma_loc_info_present_flag = get_bits1(gb); - if (vui->chroma_loc_info_present_flag) { - vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb); - vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb); - } - vui->neutra_chroma_indication_flag = get_bits1(gb); vui->field_seq_flag = get_bits1(gb); vui->frame_field_info_present_flag = get_bits1(gb); @@ -1123,7 +1066,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->sps_temporal_mvp_enabled_flag = get_bits1(gb); sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb); - sps->vui.sar = (AVRational){0, 1}; + sps->vui.common.sar = (AVRational){0, 1}; vui_present = get_bits1(gb); if (vui_present) decode_vui(gb, avctx, apply_defdispwin, sps); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.h b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.h index 2a1bbf64..18894cfe 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_ps.h @@ -29,6 +29,7 @@ #include "avcodec.h" #include "get_bits.h" +#include "h2645_vui.h" #include "hevc.h" typedef struct ShortTermRPS { @@ -47,22 +48,8 @@ typedef struct HEVCWindow { } HEVCWindow; typedef struct VUI { - AVRational sar; + H2645VUI common; - int overscan_info_present_flag; - int overscan_appropriate_flag; - - int video_signal_type_present_flag; - int video_format; - int video_full_range_flag; - int colour_description_present_flag; - uint8_t colour_primaries; - uint8_t transfer_characteristic; - uint8_t matrix_coeffs; - - int chroma_loc_info_present_flag; - int chroma_sample_loc_type_top_field; - int chroma_sample_loc_type_bottom_field; int neutra_chroma_indication_flag; int field_seq_flag; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.c b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.c index 631373e0..3c6bde1b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.c @@ -22,10 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "atsc_a53.h" #include "bytestream.h" -#include "dynamic_hdr10_plus.h" -#include "dynamic_hdr_vivid.h" #include "golomb.h" #include "hevc_ps.h" #include "hevc_sei.h" @@ -98,38 +95,6 @@ static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s, return 0; } -static int decode_nal_sei_frame_packing_arrangement(HEVCSEIFramePacking *s, GetBitContext *gb) -{ - get_ue_golomb_long(gb); // frame_packing_arrangement_id - s->present = !get_bits1(gb); - - if (s->present) { - s->arrangement_type = get_bits(gb, 7); - s->quincunx_subsampling = get_bits1(gb); - s->content_interpretation_type = get_bits(gb, 6); - - // spatial_flipping_flag, frame0_flipped_flag, field_views_flag - skip_bits(gb, 3); - s->current_frame_is_frame0_flag = get_bits1(gb); - } - return 0; -} - -static int decode_nal_sei_display_orientation(HEVCSEIDisplayOrientation *s, GetBitContext *gb) -{ - s->present = !get_bits1(gb); - - if (s->present) { - s->hflip = get_bits1(gb); // hor_flip - s->vflip = get_bits1(gb); // ver_flip - - s->anticlockwise_rotation = get_bits(gb, 16); - // skip_bits1(gb); // display_orientation_persistence_flag - } - - return 0; -} - static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, const HEVCParamSets *ps, void *logctx) { @@ -161,182 +126,6 @@ static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, return 0; } -static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s, - GetByteContext *gb) -{ - int ret; - - ret = ff_parse_a53_cc(&s->buf_ref, gb->buffer, - bytestream2_get_bytes_left(gb)); - if (ret < 0) - return ret; - - return 0; -} - -static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s, - GetByteContext *gb) -{ - AVBufferRef *buf_ref, **tmp; - int size = bytestream2_get_bytes_left(gb); - - if (size < 16 || size >= INT_MAX - 1) - return AVERROR_INVALIDDATA; - - tmp = av_realloc_array(s->buf_ref, s->nb_buf_ref + 1, sizeof(*s->buf_ref)); - if (!tmp) - return AVERROR(ENOMEM); - s->buf_ref = tmp; - - buf_ref = av_buffer_alloc(size + 1); - if (!buf_ref) - return AVERROR(ENOMEM); - - bytestream2_get_bufferu(gb, buf_ref->data, size); - buf_ref->data[size] = 0; - buf_ref->size = size; - s->buf_ref[s->nb_buf_ref++] = buf_ref; - - return 0; -} - -static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s, - GetByteContext *gb) -{ - size_t meta_size; - int err; - AVDynamicHDRPlus *metadata = av_dynamic_hdr_plus_alloc(&meta_size); - if (!metadata) - return AVERROR(ENOMEM); - - err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer, - bytestream2_get_bytes_left(gb)); - if (err < 0) { - av_free(metadata); - return err; - } - - av_buffer_unref(&s->info); - s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0); - if (!s->info) { - av_free(metadata); - return AVERROR(ENOMEM); - } - - return 0; -} - -static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid *s, - GetByteContext *gb) -{ - size_t meta_size; - int err; - AVDynamicHDRVivid *metadata = av_dynamic_hdr_vivid_alloc(&meta_size); - if (!metadata) - return AVERROR(ENOMEM); - - err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata, - gb->buffer, bytestream2_get_bytes_left(gb)); - if (err < 0) { - av_free(metadata); - return err; - } - - av_buffer_unref(&s->info); - s->info = av_buffer_create((uint8_t *)metadata, meta_size, NULL, NULL, 0); - if (!s->info) { - av_free(metadata); - return AVERROR(ENOMEM); - } - - return 0; -} - -static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetByteContext *gb, - void *logctx) -{ - int country_code, provider_code; - - if (bytestream2_get_bytes_left(gb) < 3) - return AVERROR_INVALIDDATA; - - country_code = bytestream2_get_byteu(gb); - if (country_code == 0xFF) { - if (bytestream2_get_bytes_left(gb) < 3) - return AVERROR_INVALIDDATA; - - bytestream2_skipu(gb, 1); - } - - if (country_code != 0xB5 && country_code != 0x26) { // usa_country_code and cn_country_code - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (country_code = 0x%x)\n", - country_code); - return 0; - } - - provider_code = bytestream2_get_be16u(gb); - - switch (provider_code) { - case 0x04: { // cuva_provider_code - const uint16_t cuva_provider_oriented_code = 0x0005; - uint16_t provider_oriented_code; - - if (bytestream2_get_bytes_left(gb) < 2) - return AVERROR_INVALIDDATA; - - provider_oriented_code = bytestream2_get_be16u(gb); - if (provider_oriented_code == cuva_provider_oriented_code) { - return decode_registered_user_data_dynamic_hdr_vivid(&s->dynamic_hdr_vivid, gb); - } - break; - } - case 0x3C: { // smpte_provider_code - // A/341 Amendment - 2094-40 - const uint16_t smpte2094_40_provider_oriented_code = 0x0001; - const uint8_t smpte2094_40_application_identifier = 0x04; - uint16_t provider_oriented_code; - uint8_t application_identifier; - - if (bytestream2_get_bytes_left(gb) < 3) - return AVERROR_INVALIDDATA; - - provider_oriented_code = bytestream2_get_be16u(gb); - application_identifier = bytestream2_get_byteu(gb); - if (provider_oriented_code == smpte2094_40_provider_oriented_code && - application_identifier == smpte2094_40_application_identifier) { - return decode_registered_user_data_dynamic_hdr_plus(&s->dynamic_hdr_plus, gb); - } - break; - } - case 0x31: { // atsc_provider_code - uint32_t user_identifier; - - if (bytestream2_get_bytes_left(gb) < 4) - return AVERROR_INVALIDDATA; - - user_identifier = bytestream2_get_be32u(gb); - switch (user_identifier) { - case MKBETAG('G', 'A', '9', '4'): - return decode_registered_user_data_closed_caption(&s->a53_caption, gb); - default: - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", - user_identifier); - break; - } - break; - } - default: - av_log(logctx, AV_LOG_VERBOSE, - "Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n", - provider_code); - break; - } - - return 0; -} - static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, void *logctx) { int num_sps_ids_minus1; @@ -362,18 +151,6 @@ static int decode_nal_sei_active_parameter_sets(HEVCSEI *s, GetBitContext *gb, v return 0; } -static int decode_nal_sei_alternative_transfer(HEVCSEIAlternativeTransfer *s, - GetByteContext *gb) -{ - if (bytestream2_get_bytes_left(gb) < 1) - return AVERROR_INVALIDDATA; - - s->present = 1; - s->preferred_transfer_characteristics = bytestream2_get_byteu(gb); - - return 0; -} - static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) { s->num_clock_ts = get_bits(gb, 2); @@ -420,49 +197,6 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) return 0; } -static int decode_film_grain_characteristics(HEVCSEIFilmGrainCharacteristics *h, - GetBitContext *gb) -{ - h->present = !get_bits1(gb); // film_grain_characteristics_cancel_flag - - if (h->present) { - memset(h, 0, sizeof(*h)); - h->model_id = get_bits(gb, 2); - h->separate_colour_description_present_flag = get_bits1(gb); - if (h->separate_colour_description_present_flag) { - h->bit_depth_luma = get_bits(gb, 3) + 8; - h->bit_depth_chroma = get_bits(gb, 3) + 8; - h->full_range = get_bits1(gb); - h->color_primaries = get_bits(gb, 8); - h->transfer_characteristics = get_bits(gb, 8); - h->matrix_coeffs = get_bits(gb, 8); - } - h->blending_mode_id = get_bits(gb, 2); - h->log2_scale_factor = get_bits(gb, 4); - for (int c = 0; c < 3; c++) - h->comp_model_present_flag[c] = get_bits1(gb); - for (int c = 0; c < 3; c++) { - if (h->comp_model_present_flag[c]) { - h->num_intensity_intervals[c] = get_bits(gb, 8) + 1; - h->num_model_values[c] = get_bits(gb, 3) + 1; - if (h->num_model_values[c] > 6) - return AVERROR_INVALIDDATA; - for (int i = 0; i < h->num_intensity_intervals[c]; i++) { - h->intensity_interval_lower_bound[c][i] = get_bits(gb, 8); - h->intensity_interval_upper_bound[c][i] = get_bits(gb, 8); - for (int j = 0; j < h->num_model_values[c]; j++) - h->comp_model_value[c][i][j] = get_se_golomb_long(gb); - } - } - } - h->persistence_flag = get_bits1(gb); - - h->present = 1; - } - - return 0; -} - static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type) @@ -470,10 +204,6 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, switch (type) { case 256: // Mismatched value from HM 8.1 return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte); - case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: - return decode_nal_sei_frame_packing_arrangement(&s->frame_packing, gb); - case SEI_TYPE_DISPLAY_ORIENTATION: - return decode_nal_sei_display_orientation(&s->display_orientation, gb); case SEI_TYPE_PIC_TIMING: return decode_nal_sei_pic_timing(s, gb, ps, logctx); case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: @@ -482,19 +212,15 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, return decode_nal_sei_content_light_info(&s->content_light, gbyte); case SEI_TYPE_ACTIVE_PARAMETER_SETS: return decode_nal_sei_active_parameter_sets(s, gb, logctx); - case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - return decode_nal_sei_user_data_registered_itu_t_t35(s, gbyte, logctx); - case SEI_TYPE_USER_DATA_UNREGISTERED: - return decode_nal_sei_user_data_unregistered(&s->unregistered, gbyte); - case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: - return decode_nal_sei_alternative_transfer(&s->alternative_transfer, gbyte); case SEI_TYPE_TIME_CODE: return decode_nal_sei_timecode(&s->timecode, gb); - case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: - return decode_film_grain_characteristics(&s->film_grain_characteristics, gb); - default: - av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); - return 0; + default: { + int ret = ff_h2645_sei_message_decode(&s->common, type, AV_CODEC_ID_HEVC, + gb, gbyte, logctx); + if (ret == FF_H2645_SEI_MESSAGE_UNHANDLED) + av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); + return ret; + } } } @@ -566,15 +292,3 @@ int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, } while (bytestream2_get_bytes_left(&gbyte) > 0); return 1; } - -void ff_hevc_reset_sei(HEVCSEI *s) -{ - av_buffer_unref(&s->a53_caption.buf_ref); - - for (int i = 0; i < s->unregistered.nb_buf_ref; i++) - av_buffer_unref(&s->unregistered.buf_ref[i]); - s->unregistered.nb_buf_ref = 0; - av_freep(&s->unregistered.buf_ref); - av_buffer_unref(&s->dynamic_hdr_plus.info); - av_buffer_unref(&s->dynamic_hdr_vivid.info); -} diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.h b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.h index ef987f67..4189f5e6 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hevc_sei.h @@ -27,6 +27,7 @@ #include "get_bits.h" #include "hevc.h" +#include "h2645_sei.h" #include "sei.h" @@ -48,25 +49,10 @@ typedef struct HEVCSEIFramePacking { int current_frame_is_frame0_flag; } HEVCSEIFramePacking; -typedef struct HEVCSEIDisplayOrientation { - int present; - int anticlockwise_rotation; - int hflip, vflip; -} HEVCSEIDisplayOrientation; - typedef struct HEVCSEIPictureTiming { int picture_struct; } HEVCSEIPictureTiming; -typedef struct HEVCSEIA53Caption { - AVBufferRef *buf_ref; -} HEVCSEIA53Caption; - -typedef struct HEVCSEIUnregistered { - AVBufferRef **buf_ref; - int nb_buf_ref; -} HEVCSEIUnregistered; - typedef struct HEVCSEIMasteringDisplay { int present; uint16_t display_primaries[3][2]; @@ -75,14 +61,6 @@ typedef struct HEVCSEIMasteringDisplay { uint32_t min_luminance; } HEVCSEIMasteringDisplay; -typedef struct HEVCSEIDynamicHDRPlus { - AVBufferRef *info; -} HEVCSEIDynamicHDRPlus; - -typedef struct HEVCSEIDynamicHDRVivid { - AVBufferRef *info; -} HEVCSEIDynamicHDRVivid; - typedef struct HEVCSEIContentLight { int present; uint16_t max_content_light_level; @@ -114,42 +92,14 @@ typedef struct HEVCSEITimeCode { int32_t time_offset_value[3]; } HEVCSEITimeCode; -typedef struct HEVCSEIFilmGrainCharacteristics { - int present; - int model_id; - int separate_colour_description_present_flag; - int bit_depth_luma; - int bit_depth_chroma; - int full_range; - int color_primaries; - int transfer_characteristics; - int matrix_coeffs; - int blending_mode_id; - int log2_scale_factor; - int comp_model_present_flag[3]; - uint16_t num_intensity_intervals[3]; - uint8_t num_model_values[3]; - uint8_t intensity_interval_lower_bound[3][256]; - uint8_t intensity_interval_upper_bound[3][256]; - int16_t comp_model_value[3][256][6]; - int persistence_flag; -} HEVCSEIFilmGrainCharacteristics; - typedef struct HEVCSEI { + H2645SEI common; HEVCSEIPictureHash picture_hash; - HEVCSEIFramePacking frame_packing; - HEVCSEIDisplayOrientation display_orientation; HEVCSEIPictureTiming picture_timing; - HEVCSEIA53Caption a53_caption; - HEVCSEIUnregistered unregistered; HEVCSEIMasteringDisplay mastering_display; - HEVCSEIDynamicHDRPlus dynamic_hdr_plus; - HEVCSEIDynamicHDRVivid dynamic_hdr_vivid; HEVCSEIContentLight content_light; int active_seq_parameter_set_id; - HEVCSEIAlternativeTransfer alternative_transfer; HEVCSEITimeCode timecode; - HEVCSEIFilmGrainCharacteristics film_grain_characteristics; } HEVCSEI; struct HEVCParamSets; @@ -157,13 +107,21 @@ struct HEVCParamSets; int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, const struct HEVCParamSets *ps, enum HEVCNALUnitType type); +static inline int ff_hevc_sei_ctx_replace(HEVCSEI *dst, const HEVCSEI *src) +{ + return ff_h2645_sei_ctx_replace(&dst->common, &src->common); +} + /** * Reset SEI values that are stored on the Context. * e.g. Caption data that was extracted during NAL * parsing. * - * @param s HEVCContext. + * @param sei HEVCSEI. */ -void ff_hevc_reset_sei(HEVCSEI *s); +static inline void ff_hevc_reset_sei(HEVCSEI *sei) +{ + ff_h2645_sei_reset(&sei->common); +} #endif /* AVCODEC_HEVC_SEI_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/hevcdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/hevcdec.c index fb44d8d3..567e8d81 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/hevcdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/hevcdec.c @@ -35,7 +35,6 @@ #include "libavutil/md5.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" -#include "libavutil/stereo3d.h" #include "libavutil/timecode.h" #include "bswapdsp.h" @@ -340,18 +339,18 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) avctx->profile = sps->ptl.general_ptl.profile_idc; avctx->level = sps->ptl.general_ptl.level_idc; - ff_set_sar(avctx, sps->vui.sar); + ff_set_sar(avctx, sps->vui.common.sar); - if (sps->vui.video_signal_type_present_flag) - avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG - : AVCOL_RANGE_MPEG; + if (sps->vui.common.video_signal_type_present_flag) + avctx->color_range = sps->vui.common.video_full_range_flag ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; else avctx->color_range = AVCOL_RANGE_MPEG; - if (sps->vui.colour_description_present_flag) { - avctx->color_primaries = sps->vui.colour_primaries; - avctx->color_trc = sps->vui.transfer_characteristic; - avctx->colorspace = sps->vui.matrix_coeffs; + if (sps->vui.common.colour_description_present_flag) { + avctx->color_primaries = sps->vui.common.colour_primaries; + avctx->color_trc = sps->vui.common.transfer_characteristics; + avctx->colorspace = sps->vui.common.matrix_coeffs; } else { avctx->color_primaries = AVCOL_PRI_UNSPECIFIED; avctx->color_trc = AVCOL_TRC_UNSPECIFIED; @@ -360,9 +359,9 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; if (sps->chroma_format_idc == 1) { - if (sps->vui.chroma_loc_info_present_flag) { - if (sps->vui.chroma_sample_loc_type_top_field <= 5) - avctx->chroma_sample_location = sps->vui.chroma_sample_loc_type_top_field + 1; + if (sps->vui.common.chroma_loc_info_present_flag) { + if (sps->vui.common.chroma_sample_loc_type_top_field <= 5) + avctx->chroma_sample_location = sps->vui.common.chroma_sample_loc_type_top_field + 1; } else avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; } @@ -384,16 +383,16 @@ static int export_stream_params_from_sei(HEVCContext *s) { AVCodecContext *avctx = s->avctx; - if (s->sei.a53_caption.buf_ref) + if (s->sei.common.a53_caption.buf_ref) s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; - if (s->sei.alternative_transfer.present && - av_color_transfer_name(s->sei.alternative_transfer.preferred_transfer_characteristics) && - s->sei.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { - avctx->color_trc = s->sei.alternative_transfer.preferred_transfer_characteristics; + if (s->sei.common.alternative_transfer.present && + av_color_transfer_name(s->sei.common.alternative_transfer.preferred_transfer_characteristics) && + s->sei.common.alternative_transfer.preferred_transfer_characteristics != AVCOL_TRC_UNSPECIFIED) { + avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics; } - if (s->sei.film_grain_characteristics.present) + if (s->sei.common.film_grain_characteristics.present) avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN; return 0; @@ -2726,67 +2725,6 @@ static int set_side_data(HEVCContext *s) AVFrame *out = s->ref->frame; int ret; - if (s->sei.frame_packing.present && - s->sei.frame_packing.arrangement_type >= 3 && - s->sei.frame_packing.arrangement_type <= 5 && - s->sei.frame_packing.content_interpretation_type > 0 && - s->sei.frame_packing.content_interpretation_type < 3) { - AVStereo3D *stereo = av_stereo3d_create_side_data(out); - if (!stereo) - return AVERROR(ENOMEM); - - switch (s->sei.frame_packing.arrangement_type) { - case 3: - if (s->sei.frame_packing.quincunx_subsampling) - stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; - else - stereo->type = AV_STEREO3D_SIDEBYSIDE; - break; - case 4: - stereo->type = AV_STEREO3D_TOPBOTTOM; - break; - case 5: - stereo->type = AV_STEREO3D_FRAMESEQUENCE; - break; - } - - if (s->sei.frame_packing.content_interpretation_type == 2) - stereo->flags = AV_STEREO3D_FLAG_INVERT; - - if (s->sei.frame_packing.arrangement_type == 5) { - if (s->sei.frame_packing.current_frame_is_frame0_flag) - stereo->view = AV_STEREO3D_VIEW_LEFT; - else - stereo->view = AV_STEREO3D_VIEW_RIGHT; - } - } - - if (s->sei.display_orientation.present && - (s->sei.display_orientation.anticlockwise_rotation || - s->sei.display_orientation.hflip || s->sei.display_orientation.vflip)) { - double angle = s->sei.display_orientation.anticlockwise_rotation * 360 / (double) (1 << 16); - AVFrameSideData *rotation = av_frame_new_side_data(out, - AV_FRAME_DATA_DISPLAYMATRIX, - sizeof(int32_t) * 9); - if (!rotation) - return AVERROR(ENOMEM); - - /* av_display_rotation_set() expects the angle in the clockwise - * direction, hence the first minus. - * The below code applies the flips after the rotation, yet - * the H.2645 specs require flipping to be applied first. - * Because of R O(phi) = O(-phi) R (where R is flipping around - * an arbitatry axis and O(phi) is the proper rotation by phi) - * we can create display matrices as desired by negating - * the degree once for every flip applied. */ - angle = -angle * (1 - 2 * !!s->sei.display_orientation.hflip) - * (1 - 2 * !!s->sei.display_orientation.vflip); - av_display_rotation_set((int32_t *)rotation->data, angle); - av_display_matrix_flip((int32_t *)rotation->data, - s->sei.display_orientation.hflip, - s->sei.display_orientation.vflip); - } - // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. if (s->sei.mastering_display.present > 0 && @@ -2856,28 +2794,12 @@ static int set_side_data(HEVCContext *s) metadata->MaxCLL, metadata->MaxFALL); } - if (s->sei.a53_caption.buf_ref) { - HEVCSEIA53Caption *a53 = &s->sei.a53_caption; - - AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref); - if (!sd) - av_buffer_unref(&a53->buf_ref); - a53->buf_ref = NULL; - } - - for (int i = 0; i < s->sei.unregistered.nb_buf_ref; i++) { - HEVCSEIUnregistered *unreg = &s->sei.unregistered; - - if (unreg->buf_ref[i]) { - AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, - AV_FRAME_DATA_SEI_UNREGISTERED, - unreg->buf_ref[i]); - if (!sd) - av_buffer_unref(&unreg->buf_ref[i]); - unreg->buf_ref[i] = NULL; - } - } - s->sei.unregistered.nb_buf_ref = 0; + ret = ff_h2645_sei_to_frame(out, &s->sei.common, AV_CODEC_ID_HEVC, NULL, + &s->ps.sps->vui.common, + s->ps.sps->bit_depth, s->ps.sps->bit_depth_chroma, + s->ref->poc /* no poc_offset in HEVC */); + if (ret < 0) + return ret; if (s->sei.timecode.present) { uint32_t *tc_sd; @@ -2905,63 +2827,8 @@ static int set_side_data(HEVCContext *s) s->sei.timecode.num_clock_ts = 0; } - if (s->sei.film_grain_characteristics.present) { - HEVCSEIFilmGrainCharacteristics *fgc = &s->sei.film_grain_characteristics; - AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(out); - if (!fgp) - return AVERROR(ENOMEM); - - fgp->type = AV_FILM_GRAIN_PARAMS_H274; - fgp->seed = s->ref->poc; /* no poc_offset in HEVC */ - - fgp->codec.h274.model_id = fgc->model_id; - if (fgc->separate_colour_description_present_flag) { - fgp->codec.h274.bit_depth_luma = fgc->bit_depth_luma; - fgp->codec.h274.bit_depth_chroma = fgc->bit_depth_chroma; - fgp->codec.h274.color_range = fgc->full_range + 1; - fgp->codec.h274.color_primaries = fgc->color_primaries; - fgp->codec.h274.color_trc = fgc->transfer_characteristics; - fgp->codec.h274.color_space = fgc->matrix_coeffs; - } else { - const HEVCSPS *sps = s->ps.sps; - const VUI *vui = &sps->vui; - fgp->codec.h274.bit_depth_luma = sps->bit_depth; - fgp->codec.h274.bit_depth_chroma = sps->bit_depth_chroma; - if (vui->video_signal_type_present_flag) - fgp->codec.h274.color_range = vui->video_full_range_flag + 1; - else - fgp->codec.h274.color_range = AVCOL_RANGE_UNSPECIFIED; - if (vui->colour_description_present_flag) { - fgp->codec.h274.color_primaries = vui->colour_primaries; - fgp->codec.h274.color_trc = vui->transfer_characteristic; - fgp->codec.h274.color_space = vui->matrix_coeffs; - } else { - fgp->codec.h274.color_primaries = AVCOL_PRI_UNSPECIFIED; - fgp->codec.h274.color_trc = AVCOL_TRC_UNSPECIFIED; - fgp->codec.h274.color_space = AVCOL_SPC_UNSPECIFIED; - } - } - fgp->codec.h274.blending_mode_id = fgc->blending_mode_id; - fgp->codec.h274.log2_scale_factor = fgc->log2_scale_factor; - - memcpy(&fgp->codec.h274.component_model_present, &fgc->comp_model_present_flag, - sizeof(fgp->codec.h274.component_model_present)); - memcpy(&fgp->codec.h274.num_intensity_intervals, &fgc->num_intensity_intervals, - sizeof(fgp->codec.h274.num_intensity_intervals)); - memcpy(&fgp->codec.h274.num_model_values, &fgc->num_model_values, - sizeof(fgp->codec.h274.num_model_values)); - memcpy(&fgp->codec.h274.intensity_interval_lower_bound, &fgc->intensity_interval_lower_bound, - sizeof(fgp->codec.h274.intensity_interval_lower_bound)); - memcpy(&fgp->codec.h274.intensity_interval_upper_bound, &fgc->intensity_interval_upper_bound, - sizeof(fgp->codec.h274.intensity_interval_upper_bound)); - memcpy(&fgp->codec.h274.comp_model_value, &fgc->comp_model_value, - sizeof(fgp->codec.h274.comp_model_value)); - - fgc->present = fgc->persistence_flag; - } - - if (s->sei.dynamic_hdr_plus.info) { - AVBufferRef *info_ref = av_buffer_ref(s->sei.dynamic_hdr_plus.info); + if (s->sei.common.dynamic_hdr_plus.info) { + AVBufferRef *info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_plus.info); if (!info_ref) return AVERROR(ENOMEM); @@ -2982,8 +2849,8 @@ static int set_side_data(HEVCContext *s) if ((ret = ff_dovi_attach_side_data(&s->dovi_ctx, out)) < 0) return ret; - if (s->sei.dynamic_hdr_vivid.info) { - AVBufferRef *info_ref = av_buffer_ref(s->sei.dynamic_hdr_vivid.info); + if (s->sei.common.dynamic_hdr_vivid.info) { + AVBufferRef *info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_vivid.info); if (!info_ref) return AVERROR(ENOMEM); @@ -3029,7 +2896,7 @@ static int hevc_frame_start(HEVCContext *s) s->ref->frame->key_frame = IS_IRAP(s); - s->ref->needs_fg = s->sei.film_grain_characteristics.present && + s->ref->needs_fg = s->sei.common.film_grain_characteristics.present && !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && !s->avctx->hwaccel; @@ -3729,30 +3596,12 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->max_ra = INT_MAX; } - ret = av_buffer_replace(&s->sei.a53_caption.buf_ref, s0->sei.a53_caption.buf_ref); + ret = ff_h2645_sei_ctx_replace(&s->sei.common, &s0->sei.common); if (ret < 0) return ret; - for (i = 0; i < s->sei.unregistered.nb_buf_ref; i++) - av_buffer_unref(&s->sei.unregistered.buf_ref[i]); - s->sei.unregistered.nb_buf_ref = 0; - - if (s0->sei.unregistered.nb_buf_ref) { - ret = av_reallocp_array(&s->sei.unregistered.buf_ref, - s0->sei.unregistered.nb_buf_ref, - sizeof(*s->sei.unregistered.buf_ref)); - if (ret < 0) - return ret; - - for (i = 0; i < s0->sei.unregistered.nb_buf_ref; i++) { - s->sei.unregistered.buf_ref[i] = av_buffer_ref(s0->sei.unregistered.buf_ref[i]); - if (!s->sei.unregistered.buf_ref[i]) - return AVERROR(ENOMEM); - s->sei.unregistered.nb_buf_ref++; - } - } - - ret = av_buffer_replace(&s->sei.dynamic_hdr_plus.info, s0->sei.dynamic_hdr_plus.info); + ret = av_buffer_replace(&s->sei.common.dynamic_hdr_plus.info, + s0->sei.common.dynamic_hdr_plus.info); if (ret < 0) return ret; @@ -3764,15 +3613,16 @@ static int hevc_update_thread_context(AVCodecContext *dst, if (ret < 0) return ret; - ret = av_buffer_replace(&s->sei.dynamic_hdr_vivid.info, s0->sei.dynamic_hdr_vivid.info); + ret = av_buffer_replace(&s->sei.common.dynamic_hdr_vivid.info, + s0->sei.common.dynamic_hdr_vivid.info); if (ret < 0) return ret; - s->sei.frame_packing = s0->sei.frame_packing; - s->sei.display_orientation = s0->sei.display_orientation; + s->sei.common.frame_packing = s0->sei.common.frame_packing; + s->sei.common.display_orientation = s0->sei.common.display_orientation; + s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; s->sei.mastering_display = s0->sei.mastering_display; s->sei.content_light = s0->sei.content_light; - s->sei.alternative_transfer = s0->sei.alternative_transfer; ret = export_stream_params_from_sei(s); if (ret < 0) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/huffyuvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/huffyuvenc.c index db274e37..72d6246e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/huffyuvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/huffyuvenc.c @@ -1082,7 +1082,8 @@ const FFCodec ff_huffyuv_encoder = { CODEC_LONG_NAME("Huffyuv / HuffYUV"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_HUFFYUV, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(HYuvEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), @@ -1101,7 +1102,8 @@ const FFCodec ff_ffvhuff_encoder = { CODEC_LONG_NAME("Huffyuv FFmpeg variant"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_FFVHUFF, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(HYuvEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/internal.h b/arm/raspi/third_party/ffmpeg/libavcodec/internal.h index 76a6ea6b..a283c52e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/internal.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/internal.h @@ -88,7 +88,6 @@ typedef struct AVCodecInternal { * for decoding. */ AVPacket *last_pkt_props; - struct AVFifo *pkt_props; /** * temporary buffer used for encoders to store their bitstream diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ituh263enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/ituh263enc.c index 22e5a836..c30ecad4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ituh263enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ituh263enc.c @@ -105,7 +105,7 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){ return FF_ASPECT_EXTENDED; } -void ff_h263_encode_picture_header(MpegEncContext * s, int picture_number) +void ff_h263_encode_picture_header(MpegEncContext * s) { int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; int best_clock_code=1; @@ -903,6 +903,7 @@ const FFCodec ff_h263_encoder = { .p.id = AV_CODEC_ID_H263, .p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE}, .p.priv_class = &h263_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(MpegEncContext), .init = ff_mpv_encode_init, @@ -933,7 +934,7 @@ const FFCodec ff_h263p_encoder = { .p.id = AV_CODEC_ID_H263P, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .p.priv_class = &h263p_class, - .p.capabilities = AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(MpegEncContext), .init = ff_mpv_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/j2kenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/j2kenc.c index e883d5de..6406f90a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/j2kenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/j2kenc.c @@ -1835,7 +1835,7 @@ const FFCodec ff_jpeg2000_encoder = { CODEC_LONG_NAME("JPEG 2000"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_JPEG2000, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(Jpeg2000EncoderContext), .init = j2kenc_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsdec.c index 2e6d018e..ec163b89 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsdec.c @@ -558,8 +558,7 @@ const FFCodec ff_jpegls_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_DECODE_CB(ff_mjpeg_decode_frame), .p.capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_SETS_PKT_DTS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsenc.c index 7b6362c7..891f4330 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/jpeglsenc.c @@ -476,7 +476,8 @@ const FFCodec ff_jpegls_encoder = { CODEC_LONG_NAME("JPEG-LS"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_JPEGLS, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(JPEGLSContext), .p.priv_class = &jpegls_class, .init = encode_jpegls_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/lclenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/lclenc.c index 2c9add52..dd5eed9d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/lclenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/lclenc.c @@ -156,7 +156,8 @@ const FFCodec ff_zlib_encoder = { CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ZLIB, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(LclEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libaomenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libaomenc.c index bd576fdd..0b88102c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libaomenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libaomenc.c @@ -23,6 +23,8 @@ * AV1 encoder support via libaom */ +#include + #define AOM_DISABLE_CTRL_TYPECHECKS 1 #include #include @@ -1094,6 +1096,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, } memcpy(pkt->data, cx_frame->buf, pkt->size); pkt->pts = pkt->dts = cx_frame->pts; + pkt->duration = cx_frame->duration; if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) { pkt->flags |= AV_PKT_FLAG_KEY; @@ -1275,6 +1278,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt, AOMContext *ctx = avctx->priv_data; struct aom_image *rawimg = NULL; int64_t timestamp = 0; + unsigned long duration = 0; int res, coded_size; aom_enc_frame_flags_t flags = 0; @@ -1287,6 +1291,13 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt, rawimg->stride[AOM_PLANE_U] = frame->linesize[1]; rawimg->stride[AOM_PLANE_V] = frame->linesize[2]; timestamp = frame->pts; + + if (frame->duration > ULONG_MAX) { + av_log(avctx, AV_LOG_WARNING, + "Frame duration too large: %"PRId64"\n", frame->duration); + } else + duration = frame->duration ? frame->duration : avctx->ticks_per_frame; + switch (frame->color_range) { case AVCOL_RANGE_MPEG: rawimg->range = AOM_CR_STUDIO_RANGE; @@ -1300,8 +1311,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt, flags |= AOM_EFLAG_FORCE_KF; } - res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, - avctx->ticks_per_frame, flags); + res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags); if (res != AOM_CODEC_OK) { log_encoder_error(avctx, "Error encoding frame"); return AVERROR_INVALIDDATA; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libcodec2.c b/arm/raspi/third_party/ffmpeg/libavcodec/libcodec2.c index 5728d915..83f68e85 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libcodec2.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libcodec2.c @@ -197,7 +197,8 @@ const FFCodec ff_libcodec2_encoder = { CODEC_LONG_NAME("codec2 encoder using libcodec2"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_CODEC2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.supported_samplerates = (const int[]){ 8000, 0 }, .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libdav1d.c b/arm/raspi/third_party/ffmpeg/libavcodec/libdav1d.c index 02892940..b43af037 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libdav1d.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libdav1d.c @@ -41,9 +41,6 @@ typedef struct Libdav1dContext { AVClass *class; Dav1dContext *c; - /* This packet coincides with AVCodecInternal.in_pkt - * and is not owned by us. */ - AVPacket *pkt; AVBufferPool *pool; int pool_size; @@ -219,8 +216,6 @@ static av_cold int libdav1d_init(AVCodecContext *c) #endif int res; - dav1d->pkt = c->internal->in_pkt; - av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version()); dav1d_default_settings(&s); @@ -265,6 +260,15 @@ static av_cold int libdav1d_init(AVCodecContext *c) s.n_frame_threads, s.n_tile_threads); #endif +#if FF_DAV1D_VERSION_AT_LEAST(6,8) + if (c->skip_frame >= AVDISCARD_NONKEY) + s.decode_frame_type = DAV1D_DECODEFRAMETYPE_KEY; + else if (c->skip_frame >= AVDISCARD_NONINTRA) + s.decode_frame_type = DAV1D_DECODEFRAMETYPE_INTRA; + else if (c->skip_frame >= AVDISCARD_NONREF) + s.decode_frame_type = DAV1D_DECODEFRAMETYPE_REFERENCE; +#endif + res = libdav1d_parse_extradata(c); if (res < 0) return res; @@ -291,8 +295,10 @@ static void libdav1d_data_free(const uint8_t *data, void *opaque) { } static void libdav1d_user_data_free(const uint8_t *data, void *opaque) { + AVPacket *pkt = opaque; av_assert0(data == opaque); - av_free(opaque); + av_free(pkt->opaque); + av_packet_free(&pkt); } static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) @@ -300,52 +306,58 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) Libdav1dContext *dav1d = c->priv_data; Dav1dData *data = &dav1d->data; Dav1dPicture pic = { 0 }, *p = &pic; + AVPacket *pkt; #if FF_DAV1D_VERSION_AT_LEAST(5,1) enum Dav1dEventFlags event_flags = 0; #endif int res; if (!data->sz) { - AVPacket *const pkt = dav1d->pkt; + pkt = av_packet_alloc(); + + if (!pkt) + return AVERROR(ENOMEM); res = ff_decode_get_packet(c, pkt); - if (res < 0 && res != AVERROR_EOF) + if (res < 0 && res != AVERROR_EOF) { + av_packet_free(&pkt); return res; + } if (pkt->size) { res = dav1d_data_wrap(data, pkt->data, pkt->size, libdav1d_data_free, pkt->buf); if (res < 0) { - av_packet_unref(pkt); + av_packet_free(&pkt); return res; } - data->m.timestamp = pkt->pts; - data->m.offset = pkt->pos; - data->m.duration = pkt->duration; - pkt->buf = NULL; - av_packet_unref(pkt); + pkt->opaque = NULL; if (c->reordered_opaque != AV_NOPTS_VALUE) { - uint8_t *reordered_opaque = av_memdup(&c->reordered_opaque, - sizeof(c->reordered_opaque)); - if (!reordered_opaque) { + pkt->opaque = av_memdup(&c->reordered_opaque, + sizeof(c->reordered_opaque)); + if (!pkt->opaque) { + av_packet_free(&pkt); dav1d_data_unref(data); return AVERROR(ENOMEM); } - - res = dav1d_data_wrap_user_data(data, reordered_opaque, - libdav1d_user_data_free, reordered_opaque); - if (res < 0) { - av_free(reordered_opaque); - dav1d_data_unref(data); - return res; - } } - } else if (res >= 0) { - av_packet_unref(pkt); - return AVERROR(EAGAIN); + + res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt, + libdav1d_user_data_free, pkt); + if (res < 0) { + av_free(pkt->opaque); + av_packet_free(&pkt); + dav1d_data_unref(data); + return res; + } + pkt = NULL; + } else { + av_packet_free(&pkt); + if (res >= 0) + return AVERROR(EAGAIN); } } @@ -410,17 +422,18 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) INT_MAX); ff_set_sar(c, frame->sample_aspect_ratio); - if (p->m.user_data.data) - memcpy(&frame->reordered_opaque, p->m.user_data.data, sizeof(frame->reordered_opaque)); + pkt = (AVPacket *)p->m.user_data.data; + if (pkt->opaque) + memcpy(&frame->reordered_opaque, pkt->opaque, sizeof(frame->reordered_opaque)); else frame->reordered_opaque = AV_NOPTS_VALUE; // match timestamps and packet size - frame->pts = p->m.timestamp; - frame->pkt_dts = p->m.timestamp; - frame->pkt_pos = p->m.offset; - frame->pkt_size = p->m.size; - frame->duration = p->m.duration; + res = ff_decode_frame_props_from_pkt(frame, pkt); + if (res < 0) + goto fail; + + frame->pkt_dts = pkt->pts; frame->key_frame = p->frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY; switch (p->frame_hdr->frame_type) { @@ -594,7 +607,7 @@ const FFCodec ff_libdav1d_decoder = { .flush = libdav1d_flush, FF_CODEC_RECEIVE_FRAME_CB(libdav1d_receive_frame), .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, - .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | + .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_SETS_FRAME_PROPS | FF_CODEC_CAP_AUTO_THREADS, .p.priv_class = &libdav1d_class, .p.wrapper_name = "libdav1d", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libfdk-aacenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libfdk-aacenc.c index d5899644..54549de4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libfdk-aacenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libfdk-aacenc.c @@ -187,6 +187,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) case 4: mode = MODE_1_2_1; sce = 2; cpe = 1; break; case 5: mode = MODE_1_2_2; sce = 1; cpe = 2; break; case 6: mode = MODE_1_2_2_1; sce = 2; cpe = 2; break; +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + case 7: mode = MODE_6_1; sce = 3; cpe = 2; break; +#endif /* The version macro is introduced the same time as the 7.1 support, so this should suffice. */ #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12 @@ -195,6 +198,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) cpe = 3; if (!av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1)) { mode = MODE_7_1_REAR_SURROUND; +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + } else if (!av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK)) { + mode = MODE_7_1_TOP_FRONT; +#endif } else { // MODE_1_2_2_2_1 and MODE_7_1_FRONT_CENTER use the same channel layout mode = MODE_7_1_FRONT_CENTER; @@ -448,9 +455,15 @@ static const uint64_t aac_channel_layout[] = { AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + AV_CH_LAYOUT_6POINT1_BACK, +#endif #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12 AV_CH_LAYOUT_7POINT1_WIDE_BACK, AV_CH_LAYOUT_7POINT1, +#endif +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + AV_CH_LAYOUT_7POINT1_TOP_BACK, #endif 0, }; @@ -463,9 +476,15 @@ static const AVChannelLayout aac_ch_layouts[16] = { AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_5POINT0_BACK, AV_CHANNEL_LAYOUT_5POINT1_BACK, -#ifdef AACENCODER_LIB_VL0 +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + AV_CHANNEL_LAYOUT_6POINT1_BACK, +#endif +#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12 AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK, AV_CHANNEL_LAYOUT_7POINT1, +#endif +#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0 + AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK, #endif { 0 }, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libgsmenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libgsmenc.c index bd3b1420..64095449 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libgsmenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libgsmenc.c @@ -122,7 +122,7 @@ const FFCodec ff_libgsm_encoder = { CODEC_LONG_NAME("libgsm GSM"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_GSM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = libgsm_encode_init, FF_CODEC_ENCODE_CB(libgsm_encode_frame), .close = libgsm_encode_close, @@ -141,7 +141,7 @@ const FFCodec ff_libgsm_ms_encoder = { CODEC_LONG_NAME("libgsm GSM Microsoft variant"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_GSM_MS, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = libgsm_encode_init, FF_CODEC_ENCODE_CB(libgsm_encode_frame), .close = libgsm_encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libilbc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libilbc.c index 9ef6e16b..9ca90bf0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libilbc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libilbc.c @@ -205,7 +205,7 @@ const FFCodec ff_libilbc_encoder = { CODEC_LONG_NAME("iLBC (Internet Low Bitrate Codec)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ILBC, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, .priv_data_size = sizeof(ILBCEncContext), .init = ilbc_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libjxldec.c b/arm/raspi/third_party/ffmpeg/libavcodec/libjxldec.c index de48bea4..abe08eb4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libjxldec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libjxldec.c @@ -47,6 +47,7 @@ typedef struct LibJxlDecodeContext { JxlDecoder *decoder; JxlBasicInfo basic_info; JxlPixelFormat jxl_pixfmt; + JxlBitDepth jxl_bit_depth; JxlDecoderStatus events; AVBufferRef *iccp; } LibJxlDecodeContext; @@ -93,10 +94,14 @@ static av_cold int libjxl_decode_init(AVCodecContext *avctx) return libjxl_init_jxl_decoder(avctx); } -static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *basic_info, JxlPixelFormat *format) +static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, const JxlBasicInfo *basic_info, + JxlPixelFormat *format, JxlBitDepth *depth) { format->endianness = JXL_NATIVE_ENDIAN; format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0); + depth->bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample; + depth->type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT; + depth->exponent_bits_per_sample = basic_info->exponent_bits_per_sample; /* Gray */ if (basic_info->num_color_channels == 1) { if (basic_info->bits_per_sample <= 8) { @@ -119,10 +124,10 @@ static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *ba format->data_type = JXL_TYPE_UINT8; return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24; } - if (basic_info->bits_per_sample > 16) - av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n"); if (basic_info->exponent_bits_per_sample) av_log(avctx, AV_LOG_WARNING, "Downsampling float to 16-bit integer via libjxl\n"); + else if (basic_info->bits_per_sample > 16) + av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n"); format->data_type = JXL_TYPE_UINT16; return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48; } @@ -167,9 +172,9 @@ static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlC case JXL_TRANSFER_FUNCTION_DCI: return AVCOL_TRC_SMPTE428; case JXL_TRANSFER_FUNCTION_HLG: return AVCOL_TRC_ARIB_STD_B67; case JXL_TRANSFER_FUNCTION_GAMMA: - if (jxl_color->gamma > 2.199 && jxl_color->gamma < 2.201) + if (jxl_color->gamma > 0.45355 && jxl_color->gamma < 0.45555) return AVCOL_TRC_GAMMA22; - else if (jxl_color->gamma > 2.799 && jxl_color->gamma < 2.801) + else if (jxl_color->gamma > 0.35614 && jxl_color->gamma < 0.35814) return AVCOL_TRC_GAMMA28; else av_log(avctx, AV_LOG_WARNING, "Unsupported gamma transfer: %f\n", jxl_color->gamma); @@ -367,7 +372,7 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n"); return AVERROR_EXTERNAL; } - avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt); + avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt, &ctx->jxl_bit_depth); if (avctx->pix_fmt == AV_PIX_FMT_NONE) { av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n"); return AVERROR_EXTERNAL; @@ -390,6 +395,10 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n"); return AVERROR_EXTERNAL; } + if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n"); + return AVERROR_EXTERNAL; + } continue; case JXL_DEC_FULL_IMAGE: /* full image is one frame, even if animated */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libjxlenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libjxlenc.c index 0793ed25..c51024f1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libjxlenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libjxlenc.c @@ -250,6 +250,7 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra JxlBasicInfo info; JxlColorEncoding jxl_color; JxlPixelFormat jxl_fmt; + JxlBitDepth jxl_bit_depth; JxlEncoderStatus jret; int ret; size_t available = ctx->buffer_size; @@ -269,17 +270,22 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra info.ysize = frame->height; info.num_extra_channels = (jxl_fmt.num_channels + 1) % 2; info.num_color_channels = jxl_fmt.num_channels - info.num_extra_channels; - info.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels; + jxl_bit_depth.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels; + info.bits_per_sample = avctx->bits_per_raw_sample > 0 && !(pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) + ? avctx->bits_per_raw_sample : jxl_bit_depth.bits_per_sample; info.alpha_bits = (info.num_extra_channels > 0) * info.bits_per_sample; if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) { info.exponent_bits_per_sample = info.bits_per_sample > 16 ? 8 : 5; info.alpha_exponent_bits = info.alpha_bits ? info.exponent_bits_per_sample : 0; jxl_fmt.data_type = info.bits_per_sample > 16 ? JXL_TYPE_FLOAT : JXL_TYPE_FLOAT16; + jxl_bit_depth.exponent_bits_per_sample = info.exponent_bits_per_sample; } else { info.exponent_bits_per_sample = 0; info.alpha_exponent_bits = 0; jxl_fmt.data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16; + jxl_bit_depth.exponent_bits_per_sample = 0; } + jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT; /* JPEG XL format itself does not support limited range */ if (avctx->color_range == AVCOL_RANGE_MPEG || @@ -356,6 +362,8 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra av_log(avctx, AV_LOG_WARNING, "Could not set ICC Profile\n"); if (JxlEncoderSetColorEncoding(ctx->encoder, &jxl_color) != JXL_ENC_SUCCESS) av_log(avctx, AV_LOG_WARNING, "Failed to set JxlColorEncoding\n"); + if (JxlEncoderSetFrameBitDepth(ctx->options, &jxl_bit_depth) != JXL_ENC_SUCCESS) + av_log(avctx, AV_LOG_WARNING, "Failed to set JxlBitDepth\n"); /* depending on basic info, level 10 might * be required instead of level 5 */ @@ -467,7 +475,8 @@ const FFCodec ff_libjxl_encoder = { .init = libjxl_encode_init, FF_CODEC_ENCODE_CB(libjxl_encode_frame), .close = libjxl_encode_close, - .p.capabilities = AV_CODEC_CAP_OTHER_THREADS, + .p.capabilities = AV_CODEC_CAP_OTHER_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_ICC_PROFILES, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libopenh264enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libopenh264enc.c index bbd69695..6934fd48 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libopenh264enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libopenh264enc.c @@ -456,7 +456,8 @@ const FFCodec ff_libopenh264_encoder = { CODEC_LONG_NAME("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_H264, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SVCContext), .init = svc_encode_init, FF_CODEC_ENCODE_CB(svc_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libopenjpegenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libopenjpegenc.c index 6f777803..009c7a43 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libopenjpegenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libopenjpegenc.c @@ -763,7 +763,8 @@ const FFCodec ff_libopenjpeg_encoder = { .priv_data_size = sizeof(LibOpenJPEGContext), .init = libopenjpeg_encode_init, FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame), - .p.capabilities = AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/librav1e.c b/arm/raspi/third_party/ffmpeg/libavcodec/librav1e.c index 4f424caf..00d69328 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/librav1e.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/librav1e.c @@ -22,6 +22,7 @@ #include +#include "libavutil/buffer.h" #include "libavutil/internal.h" #include "libavutil/avassert.h" #include "libavutil/base64.h" @@ -53,6 +54,15 @@ typedef struct librav1eContext { int tile_cols; } librav1eContext; +typedef struct FrameData { + int64_t pts; + int64_t duration; + int64_t reordered_opaque; + + void *frame_opaque; + AVBufferRef *frame_opaque_ref; +} FrameData; + static inline RaPixelRange range_map(enum AVPixelFormat pix_fmt, enum AVColorRange range) { switch (pix_fmt) { @@ -243,10 +253,9 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx) } { - AVDictionaryEntry *en = NULL; - while ((en = av_dict_get(ctx->rav1e_opts, "", en, AV_DICT_IGNORE_SUFFIX))) { - int parse_ret = rav1e_config_parse(cfg, en->key, en->value); - if (parse_ret < 0) + const AVDictionaryEntry *en = NULL; + while ((en = av_dict_iterate(ctx->rav1e_opts, en))) { + if (rav1e_config_parse(cfg, en->key, en->value) < 0) av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s.\n", en->key, en->value); } } @@ -420,11 +429,23 @@ end: return ret; } +static void frame_data_free(void *data) +{ + FrameData *fd = data; + + if (!fd) + return; + + av_buffer_unref(&fd->frame_opaque_ref); + av_free(data); +} + static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { librav1eContext *ctx = avctx->priv_data; RaFrame *rframe = ctx->rframe; RaPacket *rpkt = NULL; + FrameData *fd; int ret; if (!rframe) { @@ -437,18 +458,30 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) if (frame->buf[0]) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - int64_t *pts = av_malloc(sizeof(int64_t)); - if (!pts) { + fd = av_mallocz(sizeof(*fd)); + if (!fd) { av_log(avctx, AV_LOG_ERROR, "Could not allocate PTS buffer.\n"); return AVERROR(ENOMEM); } - *pts = frame->pts; + fd->pts = frame->pts; + fd->duration = frame->duration; + fd->reordered_opaque = frame->reordered_opaque; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + fd->frame_opaque = frame->opaque; + ret = av_buffer_replace(&fd->frame_opaque_ref, frame->opaque_ref); + if (ret < 0) { + frame_data_free(fd); + av_frame_unref(frame); + return ret; + } + } rframe = rav1e_frame_new(ctx->ctx); if (!rframe) { av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n"); av_frame_unref(frame); - av_freep(&pts); + frame_data_free(fd); return AVERROR(ENOMEM); } @@ -460,7 +493,7 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) frame->linesize[i], bytes); } av_frame_unref(frame); - rav1e_frame_set_opaque(rframe, pts, av_free); + rav1e_frame_set_opaque(rframe, fd, frame_data_free); } } @@ -536,8 +569,18 @@ retry: if (rpkt->frame_type == RA_FRAME_TYPE_KEY) pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pkt->dts = *((int64_t *) rpkt->opaque); - av_free(rpkt->opaque); + fd = rpkt->opaque; + pkt->pts = pkt->dts = fd->pts; + pkt->duration = fd->duration; + avctx->reordered_opaque = fd->reordered_opaque; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = fd->frame_opaque; + pkt->opaque_ref = fd->frame_opaque_ref; + fd->frame_opaque_ref = NULL; + } + + frame_data_free(fd); if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME) { AVCodecInternal *avci = avctx->internal; @@ -627,7 +670,8 @@ const FFCodec ff_librav1e_encoder = { .defaults = librav1e_defaults, .p.pix_fmts = librav1e_pix_fmts, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | - AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS, .p.wrapper_name = "librav1e", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libsvtav1.c b/arm/raspi/third_party/ffmpeg/libavcodec/libsvtav1.c index 7605badd..56e1e22b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libsvtav1.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libsvtav1.c @@ -155,14 +155,19 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param, // Update param from options #if FF_API_SVTAV1_OPTS - param->hierarchical_levels = svt_enc->hierarchical_level; - param->tier = svt_enc->tier; - param->scene_change_detection = svt_enc->scd; - param->tile_columns = svt_enc->tile_columns; - param->tile_rows = svt_enc->tile_rows; + if (svt_enc->hierarchical_level >= 0) + param->hierarchical_levels = svt_enc->hierarchical_level; + if (svt_enc->tier >= 0) + param->tier = svt_enc->tier; + if (svt_enc->scd >= 0) + param->scene_change_detection = svt_enc->scd; + if (svt_enc->tile_columns >= 0) + param->tile_columns = svt_enc->tile_columns; + if (svt_enc->tile_rows >= 0) + param->tile_rows = svt_enc->tile_rows; if (svt_enc->la_depth >= 0) - param->look_ahead_distance = svt_enc->la_depth; + param->look_ahead_distance = svt_enc->la_depth; #endif if (svt_enc->enc_mode >= 0) @@ -572,7 +577,7 @@ static av_cold int eb_enc_close(AVCodecContext *avctx) static const AVOption options[] = { #if FF_API_SVTAV1_OPTS { "hielevel", "Hierarchical prediction levels setting (Deprecated, use svtav1-params)", OFFSET(hierarchical_level), - AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"}, + AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"}, { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" }, { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" }, @@ -580,7 +585,7 @@ static const AVOption options[] = { AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE | AV_OPT_FLAG_DEPRECATED }, { "tier", "Set operating point tier (Deprecated, use svtav1-params)", OFFSET(tier), - AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" }, + AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" }, { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" }, { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" }, #endif @@ -623,10 +628,10 @@ static const AVOption options[] = { AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE }, #if FF_API_SVTAV1_OPTS { "sc_detection", "Scene change detection (Deprecated, use svtav1-params)", OFFSET(scd), - AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED }, + AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE | AV_OPT_FLAG_DEPRECATED }, - { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VE | AV_OPT_FLAG_DEPRECATED }, - { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE | AV_OPT_FLAG_DEPRECATED }, + { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 4, VE | AV_OPT_FLAG_DEPRECATED }, + { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, VE | AV_OPT_FLAG_DEPRECATED }, #endif { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libtheoraenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libtheoraenc.c index da16c637..06eeaae0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libtheoraenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libtheoraenc.c @@ -346,7 +346,13 @@ static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt, // HACK: assumes no encoder delay, this is true until libtheora becomes // multithreaded (which will be disabled unless explicitly requested) - pkt->pts = pkt->dts = frame->pts; + pkt->pts = frame->pts; + pkt->duration = frame->duration; + + ret = ff_encode_reordered_opaque(avc_context, pkt, frame); + if (ret < 0) + return ret; + if (!(o_packet.granulepos & h->keyframe_mask)) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; @@ -373,7 +379,9 @@ const FFCodec ff_libtheora_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_THEORA, .p.capabilities = AV_CODEC_CAP_DR1 | - AV_CODEC_CAP_DELAY /* for statsfile summary */, + /* for statsfile summary */ + AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, .priv_data_size = sizeof(TheoraContext), .init = encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libvo-amrwbenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libvo-amrwbenc.c index 76a6b699..02b8941a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libvo-amrwbenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libvo-amrwbenc.c @@ -144,7 +144,8 @@ const FFCodec ff_libvo_amrwbenc_encoder = { CODEC_LONG_NAME("Android VisualOn AMR-WB (Adaptive Multi-Rate Wide-Band)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_AMR_WB, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.priv_class = &amrwb_class, .p.wrapper_name = "libvo_amrwbenc", .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libvpx.h b/arm/raspi/third_party/ffmpeg/libavcodec/libvpx.h index 0caed8cd..331feb87 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libvpx.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libvpx.h @@ -25,6 +25,8 @@ #include "codec_internal.h" +#define MAX_VPX_THREADS 64 + void ff_vp9_init_static(FFCodec *codec); #if 0 enum AVPixelFormat ff_vpx_imgfmt_to_pixfmt(vpx_img_fmt_t img); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libvpxdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/libvpxdec.c index 9cd2c56c..0ae19c3f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libvpxdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libvpxdec.c @@ -88,7 +88,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, const struct vpx_codec_iface *iface) { struct vpx_codec_dec_cfg deccfg = { - .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16) + .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), MAX_VPX_THREADS) }; av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libvpxenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libvpxenc.c index 667cffc2..339d4d81 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libvpxenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libvpxenc.c @@ -900,7 +900,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, vpx_codec_caps_t codec_caps = vpx_codec_get_caps(iface); vpx_svc_extra_cfg_t svc_params; #endif - AVDictionaryEntry* en = NULL; + const AVDictionaryEntry* en = NULL; av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); @@ -942,7 +942,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, enccfg.g_timebase.num = avctx->time_base.num; enccfg.g_timebase.den = avctx->time_base.den; enccfg.g_threads = - FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16); + FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), MAX_VPX_THREADS); enccfg.g_lag_in_frames= ctx->lag_in_frames; if (avctx->flags & AV_CODEC_FLAG_PASS1) @@ -1072,7 +1072,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, enccfg.g_error_resilient = ctx->error_resilient || ctx->flags & VP8F_ERROR_RESILIENT; - while ((en = av_dict_get(ctx->vpx_ts_parameters, "", en, AV_DICT_IGNORE_SUFFIX))) { + while ((en = av_dict_iterate(ctx->vpx_ts_parameters, en))) { if (vpx_ts_param_parse(ctx, &enccfg, en->key, en->value, avctx->codec_id) < 0) av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc.c index ee5795f0..d6edd866 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc.c @@ -92,7 +92,7 @@ const FFCodec ff_libwebp_encoder = { CODEC_LONG_NAME("libwebp WebP image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_WEBP, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = ff_libwebpenc_pix_fmts, .p.priv_class = &ff_libwebpenc_class, .p.wrapper_name = "libwebp", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc_animencoder.c b/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc_animencoder.c index 0f2c190c..440cae1d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc_animencoder.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libwebpenc_animencoder.c @@ -24,6 +24,8 @@ * WebP encoder using libwebp (WebPAnimEncoder API) */ +#include "libavutil/buffer.h" + #include "config.h" #include "codec_internal.h" #include "encode.h" @@ -35,6 +37,12 @@ typedef struct LibWebPAnimContext { LibWebPContextCommon cc; WebPAnimEncoder *enc; // the main AnimEncoder object int64_t first_frame_pts; // pts of the first encoded frame. + int64_t end_pts; // pts + duration of the last frame + + int64_t reordered_opaque; + void *first_frame_opaque; + AVBufferRef *first_frame_opaque_ref; + int done; // If true, we have assembled the bitstream already } LibWebPAnimContext; @@ -77,7 +85,18 @@ static int libwebp_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt, memcpy(pkt->data, assembled_data.bytes, assembled_data.size); WebPDataClear(&assembled_data); s->done = 1; - pkt->pts = pkt->dts = s->first_frame_pts; + pkt->pts = s->first_frame_pts; + + if (pkt->pts != AV_NOPTS_VALUE && s->end_pts > pkt->pts) + pkt->duration = s->end_pts - pkt->pts; + + avctx->reordered_opaque = s->reordered_opaque; + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = s->first_frame_opaque; + pkt->opaque_ref = s->first_frame_opaque_ref; + s->first_frame_opaque_ref = NULL; + } + *got_packet = 1; return 0; } else { @@ -107,8 +126,21 @@ static int libwebp_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt, goto end; } - if (!avctx->frame_number) + if (!avctx->frame_number) { s->first_frame_pts = frame->pts; + s->reordered_opaque = frame->reordered_opaque; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + s->first_frame_opaque = frame->opaque; + ret = av_buffer_replace(&s->first_frame_opaque_ref, frame->opaque_ref); + if (ret < 0) + goto end; + } + } + + if (frame->pts != AV_NOPTS_VALUE) + s->end_pts = frame->pts + frame->duration; + ret = 0; *got_packet = 0; @@ -126,6 +158,8 @@ static int libwebp_anim_encode_close(AVCodecContext *avctx) av_frame_free(&s->cc.ref); WebPAnimEncoderDelete(s->enc); + av_buffer_unref(&s->first_frame_opaque_ref); + return 0; } @@ -134,7 +168,8 @@ const FFCodec ff_libwebp_anim_encoder = { CODEC_LONG_NAME("libwebp WebP image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_WEBP, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = ff_libwebpenc_pix_fmts, .p.priv_class = &ff_libwebpenc_class, .p.wrapper_name = "libwebp", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libx264.c b/arm/raspi/third_party/ffmpeg/libavcodec/libx264.c index ca0b5a14..2742fb11 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libx264.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libx264.c @@ -21,6 +21,7 @@ #include "config_components.h" +#include "libavutil/buffer.h" #include "libavutil/eval.h" #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -51,6 +52,10 @@ typedef struct X264Opaque { int64_t reordered_opaque; int64_t wallclock; + int64_t duration; + + void *frame_opaque; + AVBufferRef *frame_opaque_ref; } X264Opaque; typedef struct X264Context { @@ -133,6 +138,11 @@ static void X264_log(void *p, int level, const char *fmt, va_list args) av_vlog(p, level_map[level], fmt, args); } +static void opaque_uninit(X264Opaque *o) +{ + av_buffer_unref(&o->frame_opaque_ref); + memset(o, 0, sizeof(*o)); +} static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, const x264_nal_t *nals, int nnal) @@ -333,189 +343,232 @@ static enum AVPixelFormat csp_to_pixfmt(int csp) return AV_PIX_FMT_NONE; } -static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, - int *got_packet) +static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth, + const AVFrame *frame, const uint8_t *data, size_t size) { X264Context *x4 = ctx->priv_data; - x264_nal_t *nal; - int nnal, i, ret; - x264_picture_t pic_out = {0}; - int pict_type; - int bit_depth; + + int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE; + int mby = (frame->height + MB_SIZE - 1) / MB_SIZE; + int qp_range = 51 + 6 * (bit_depth - 8); + int nb_rois; + const AVRegionOfInterest *roi; + uint32_t roi_size; + float *qoffsets; + + if (x4->params.rc.i_aq_mode == X264_AQ_NONE) { + if (!x4->roi_warned) { + x4->roi_warned = 1; + av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n"); + } + return 0; + } else if (frame->interlaced_frame) { + if (!x4->roi_warned) { + x4->roi_warned = 1; + av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n"); + } + return 0; + } + + roi = (const AVRegionOfInterest*)data; + roi_size = roi->self_size; + if (!roi_size || size % roi_size != 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); + return AVERROR(EINVAL); + } + nb_rois = size / roi_size; + + qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets)); + if (!qoffsets) + return AVERROR(ENOMEM); + + // This list must be iterated in reverse because the first + // region in the list applies when regions overlap. + for (int i = nb_rois - 1; i >= 0; i--) { + int startx, endx, starty, endy; + float qoffset; + + roi = (const AVRegionOfInterest*)(data + roi_size * i); + + starty = FFMIN(mby, roi->top / MB_SIZE); + endy = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE); + startx = FFMIN(mbx, roi->left / MB_SIZE); + endx = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE); + + if (roi->qoffset.den == 0) { + av_free(qoffsets); + av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n"); + return AVERROR(EINVAL); + } + qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den; + qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range); + + for (int y = starty; y < endy; y++) { + for (int x = startx; x < endx; x++) { + qoffsets[x + y*mbx] = qoffset; + } + } + } + + pic->prop.quant_offsets = qoffsets; + pic->prop.quant_offsets_free = av_free; + + return 0; +} + +static int setup_frame(AVCodecContext *ctx, const AVFrame *frame, + x264_picture_t **ppic) +{ + X264Context *x4 = ctx->priv_data; + X264Opaque *opaque = &x4->reordered_opaque[x4->next_reordered_opaque]; + x264_picture_t *pic = &x4->pic; + x264_sei_t *sei = &pic->extra_sei; + unsigned int sei_data_size = 0; int64_t wallclock = 0; - X264Opaque *out_opaque; + int bit_depth, ret; AVFrameSideData *sd; - x264_picture_init( &x4->pic ); - x4->pic.img.i_csp = x4->params.i_csp; + *ppic = NULL; + if (!frame) + return 0; + + x264_picture_init(pic); + pic->img.i_csp = x4->params.i_csp; #if X264_BUILD >= 153 bit_depth = x4->params.i_bitdepth; #else bit_depth = x264_bit_depth; #endif if (bit_depth > 8) - x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; - x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); + pic->img.i_csp |= X264_CSP_HIGH_DEPTH; + pic->img.i_plane = avfmt2_num_planes(ctx->pix_fmt); - if (frame) { - x264_sei_t *sei = &x4->pic.extra_sei; - unsigned int sei_data_size = 0; + for (int i = 0; i < pic->img.i_plane; i++) { + pic->img.plane[i] = frame->data[i]; + pic->img.i_stride[i] = frame->linesize[i]; + } - for (i = 0; i < x4->pic.img.i_plane; i++) { - x4->pic.img.plane[i] = frame->data[i]; - x4->pic.img.i_stride[i] = frame->linesize[i]; - } + pic->i_pts = frame->pts; - x4->pic.i_pts = frame->pts; + opaque_uninit(opaque); - x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque; - x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock; - if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT) - x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime(); - x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque]; - x4->next_reordered_opaque++; - x4->next_reordered_opaque %= x4->nb_reordered_opaque; + if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + opaque->frame_opaque = frame->opaque; + ret = av_buffer_replace(&opaque->frame_opaque_ref, frame->opaque_ref); + if (ret < 0) + goto fail; + } - switch (frame->pict_type) { - case AV_PICTURE_TYPE_I: - x4->pic.i_type = x4->forced_idr > 0 ? X264_TYPE_IDR - : X264_TYPE_KEYFRAME; - break; - case AV_PICTURE_TYPE_P: - x4->pic.i_type = X264_TYPE_P; - break; - case AV_PICTURE_TYPE_B: - x4->pic.i_type = X264_TYPE_B; - break; - default: - x4->pic.i_type = X264_TYPE_AUTO; - break; - } - reconfig_encoder(ctx, frame); + opaque->reordered_opaque = frame->reordered_opaque; + opaque->duration = frame->duration; + opaque->wallclock = wallclock; + if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT) + opaque->wallclock = av_gettime(); - if (x4->a53_cc) { - void *sei_data; - size_t sei_size; + pic->opaque = opaque; - ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); - } else if (sei_data) { - x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); - if (x4->pic.extra_sei.payloads == NULL) { - av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); - av_free(sei_data); - } else { - x4->pic.extra_sei.sei_free = av_free; + x4->next_reordered_opaque++; + x4->next_reordered_opaque %= x4->nb_reordered_opaque; - x4->pic.extra_sei.payloads[0].payload_size = sei_size; - x4->pic.extra_sei.payloads[0].payload = sei_data; - x4->pic.extra_sei.num_payloads = 1; - x4->pic.extra_sei.payloads[0].payload_type = 4; - } + switch (frame->pict_type) { + case AV_PICTURE_TYPE_I: + pic->i_type = x4->forced_idr > 0 ? X264_TYPE_IDR : X264_TYPE_KEYFRAME; + break; + case AV_PICTURE_TYPE_P: + pic->i_type = X264_TYPE_P; + break; + case AV_PICTURE_TYPE_B: + pic->i_type = X264_TYPE_B; + break; + default: + pic->i_type = X264_TYPE_AUTO; + break; + } + reconfig_encoder(ctx, frame); + + if (x4->a53_cc) { + void *sei_data; + size_t sei_size; + + ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size); + if (ret < 0) + goto fail; + + if (sei_data) { + pic->extra_sei.payloads = av_mallocz(sizeof(pic->extra_sei.payloads[0])); + if (pic->extra_sei.payloads == NULL) { + ret = AVERROR(ENOMEM); + goto fail; } - } - sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST); - if (sd) { - if (x4->params.rc.i_aq_mode == X264_AQ_NONE) { - if (!x4->roi_warned) { - x4->roi_warned = 1; - av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n"); - } - } else { - if (frame->interlaced_frame == 0) { - int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE; - int mby = (frame->height + MB_SIZE - 1) / MB_SIZE; - int qp_range = 51 + 6 * (bit_depth - 8); - int nb_rois; - const AVRegionOfInterest *roi; - uint32_t roi_size; - float *qoffsets; + pic->extra_sei.sei_free = av_free; - roi = (const AVRegionOfInterest*)sd->data; - roi_size = roi->self_size; - if (!roi_size || sd->size % roi_size != 0) { - free_picture(ctx); - av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); - return AVERROR(EINVAL); - } - nb_rois = sd->size / roi_size; - - qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets)); - if (!qoffsets) { - free_picture(ctx); - return AVERROR(ENOMEM); - } - // This list must be iterated in reverse because the first - // region in the list applies when regions overlap. - for (int i = nb_rois - 1; i >= 0; i--) { - int startx, endx, starty, endy; - float qoffset; - - roi = (const AVRegionOfInterest*)(sd->data + roi_size * i); - - starty = FFMIN(mby, roi->top / MB_SIZE); - endy = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE); - startx = FFMIN(mbx, roi->left / MB_SIZE); - endx = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE); - - if (roi->qoffset.den == 0) { - av_free(qoffsets); - free_picture(ctx); - av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n"); - return AVERROR(EINVAL); - } - qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den; - qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range); - - for (int y = starty; y < endy; y++) { - for (int x = startx; x < endx; x++) { - qoffsets[x + y*mbx] = qoffset; - } - } - } - - x4->pic.prop.quant_offsets = qoffsets; - x4->pic.prop.quant_offsets_free = av_free; - } else { - if (!x4->roi_warned) { - x4->roi_warned = 1; - av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n"); - } - } - } - } - - if (x4->udu_sei) { - for (int j = 0; j < frame->nb_side_data; j++) { - AVFrameSideData *side_data = frame->side_data[j]; - void *tmp; - x264_sei_payload_t *sei_payload; - if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED) - continue; - tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload)); - if (!tmp) { - free_picture(ctx); - return AVERROR(ENOMEM); - } - sei->payloads = tmp; - sei->sei_free = av_free; - sei_payload = &sei->payloads[sei->num_payloads]; - sei_payload->payload = av_memdup(side_data->data, side_data->size); - if (!sei_payload->payload) { - free_picture(ctx); - return AVERROR(ENOMEM); - } - sei_payload->payload_size = side_data->size; - sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED; - sei->num_payloads++; - } + pic->extra_sei.payloads[0].payload_size = sei_size; + pic->extra_sei.payloads[0].payload = sei_data; + pic->extra_sei.num_payloads = 1; + pic->extra_sei.payloads[0].payload_type = 4; } } + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST); + if (sd) { + ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size); + if (ret < 0) + goto fail; + } + + if (x4->udu_sei) { + for (int j = 0; j < frame->nb_side_data; j++) { + AVFrameSideData *side_data = frame->side_data[j]; + void *tmp; + x264_sei_payload_t *sei_payload; + if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED) + continue; + tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload)); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + sei->payloads = tmp; + sei->sei_free = av_free; + sei_payload = &sei->payloads[sei->num_payloads]; + sei_payload->payload = av_memdup(side_data->data, side_data->size); + if (!sei_payload->payload) { + ret = AVERROR(ENOMEM); + goto fail; + } + sei_payload->payload_size = side_data->size; + sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED; + sei->num_payloads++; + } + } + + *ppic = pic; + return 0; + +fail: + free_picture(ctx); + *ppic = NULL; + return ret; +} + +static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, + int *got_packet) +{ + X264Context *x4 = ctx->priv_data; + x264_nal_t *nal; + int nnal, ret; + x264_picture_t pic_out = {0}, *pic_in; + int pict_type; + int64_t wallclock = 0; + X264Opaque *out_opaque; + + ret = setup_frame(ctx, frame, &pic_in); + if (ret < 0) + return ret; + do { - if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) + if (x264_encoder_encode(x4->enc, &nal, &nnal, pic_in, &pic_out) < 0) return AVERROR_EXTERNAL; if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) { @@ -561,8 +614,19 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) { ctx->reordered_opaque = out_opaque->reordered_opaque; wallclock = out_opaque->wallclock; + pkt->duration = out_opaque->duration; + + if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = out_opaque->frame_opaque; + pkt->opaque_ref = out_opaque->frame_opaque_ref; + out_opaque->frame_opaque_ref = NULL; + } + + opaque_uninit(out_opaque); } else { // Unexpected opaque pointer on picture output + av_log(ctx, AV_LOG_ERROR, "Unexpected opaque pointer; " + "this is a bug, please report it.\n"); ctx->reordered_opaque = 0; } @@ -599,6 +663,9 @@ static av_cold int X264_close(AVCodecContext *avctx) X264Context *x4 = avctx->priv_data; av_freep(&x4->sei); + + for (int i = 0; i < x4->nb_reordered_opaque; i++) + opaque_uninit(&x4->reordered_opaque[i]); av_freep(&x4->reordered_opaque); #if X264_BUILD >= 161 @@ -1070,10 +1137,12 @@ static av_cold int X264_init(AVCodecContext *avctx) // Overestimate the reordered opaque buffer size, in case a runtime // reconfigure would increase the delay (which it shouldn't). x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 17; - x4->reordered_opaque = av_malloc_array(x4->nb_reordered_opaque, - sizeof(*x4->reordered_opaque)); - if (!x4->reordered_opaque) + x4->reordered_opaque = av_calloc(x4->nb_reordered_opaque, + sizeof(*x4->reordered_opaque)); + if (!x4->reordered_opaque) { + x4->nb_reordered_opaque = 0; return AVERROR(ENOMEM); + } return 0; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libx265.c b/arm/raspi/third_party/ffmpeg/libavcodec/libx265.c index e87dea60..6fc189f1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libx265.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libx265.c @@ -27,6 +27,8 @@ #include #include +#include "libavutil/avassert.h" +#include "libavutil/buffer.h" #include "libavutil/internal.h" #include "libavutil/common.h" #include "libavutil/opt.h" @@ -39,6 +41,16 @@ #include "atsc_a53.h" #include "sei.h" +typedef struct ReorderedData { + int64_t reordered_opaque; + int64_t duration; + + void *frame_opaque; + AVBufferRef *frame_opaque_ref; + + int in_use; +} ReorderedData; + typedef struct libx265Context { const AVClass *class; @@ -59,6 +71,9 @@ typedef struct libx265Context { int udu_sei; int a53_cc; + ReorderedData *rd; + int nb_rd; + /** * If the encoder does not support ROI then warn the first time we * encounter a frame with ROI side data. @@ -81,6 +96,40 @@ static int is_keyframe(NalUnitType naltype) } } +static int rd_get(libx265Context *ctx) +{ + const int add = 16; + + ReorderedData *tmp; + int idx; + + for (int i = 0; i < ctx->nb_rd; i++) + if (!ctx->rd[i].in_use) { + ctx->rd[i].in_use = 1; + return i; + } + + tmp = av_realloc_array(ctx->rd, ctx->nb_rd + add, sizeof(*ctx->rd)); + if (!tmp) + return AVERROR(ENOMEM); + memset(tmp + ctx->nb_rd, 0, sizeof(*tmp) * add); + + ctx->rd = tmp; + ctx->nb_rd += add; + + idx = ctx->nb_rd - add; + ctx->rd[idx].in_use = 1; + + return idx; +} + +static void rd_release(libx265Context *ctx, int idx) +{ + av_assert0(idx >= 0 && idx < ctx->nb_rd); + av_buffer_unref(&ctx->rd[idx].frame_opaque_ref); + memset(&ctx->rd[idx], 0, sizeof(ctx->rd[idx])); +} + static av_cold int libx265_encode_close(AVCodecContext *avctx) { libx265Context *ctx = avctx->priv_data; @@ -88,6 +137,10 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) ctx->api->param_free(ctx->params); av_freep(&ctx->sei_data); + for (int i = 0; i < ctx->nb_rd; i++) + rd_release(ctx, i); + av_freep(&ctx->rd); + if (ctx->encoder) ctx->api->encoder_close(ctx->encoder); @@ -499,12 +552,18 @@ static av_cold int libx265_encode_set_roi(libx265Context *ctx, const AVFrame *fr return 0; } -static void free_picture(x265_picture *pic) +static void free_picture(libx265Context *ctx, x265_picture *pic) { x265_sei *sei = &pic->userSEI; for (int i = 0; i < sei->numPayloads; i++) av_free(sei->payloads[i].payload); - av_freep(&pic->userData); + + if (pic->userData) { + int idx = (int)(intptr_t)pic->userData - 1; + rd_release(ctx, idx); + pic->userData = NULL; + } + av_freep(&pic->quantOffsets); sei->numPayloads = 0; } @@ -530,6 +589,9 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, sei->numPayloads = 0; if (pic) { + ReorderedData *rd; + int rd_idx; + for (i = 0; i < 3; i++) { x265pic.planes[i] = pic->data[i]; x265pic.stride[i] = pic->linesize[i]; @@ -548,15 +610,26 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (ret < 0) return ret; - if (pic->reordered_opaque) { - x265pic.userData = av_malloc(sizeof(pic->reordered_opaque)); - if (!x265pic.userData) { - free_picture(&x265pic); - return AVERROR(ENOMEM); - } - - memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque)); + rd_idx = rd_get(ctx); + if (rd_idx < 0) { + free_picture(ctx, &x265pic); + return rd_idx; } + rd = &ctx->rd[rd_idx]; + + rd->duration = pic->duration; + rd->reordered_opaque = pic->reordered_opaque; + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + rd->frame_opaque = pic->opaque; + ret = av_buffer_replace(&rd->frame_opaque_ref, pic->opaque_ref); + if (ret < 0) { + rd_release(ctx, rd_idx); + free_picture(ctx, &x265pic); + return ret; + } + } + + x265pic.userData = (void*)(intptr_t)(rd_idx + 1); if (ctx->a53_cc) { void *sei_data; @@ -574,7 +647,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, (sei->numPayloads + 1) * sizeof(*sei_payload)); if (!tmp) { av_free(sei_data); - free_picture(&x265pic); + free_picture(ctx, &x265pic); return AVERROR(ENOMEM); } ctx->sei_data = tmp; @@ -600,7 +673,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, &ctx->sei_data_size, (sei->numPayloads + 1) * sizeof(*sei_payload)); if (!tmp) { - free_picture(&x265pic); + free_picture(ctx, &x265pic); return AVERROR(ENOMEM); } ctx->sei_data = tmp; @@ -608,7 +681,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, sei_payload = &sei->payloads[sei->numPayloads]; sei_payload->payload = av_memdup(side_data->data, side_data->size); if (!sei_payload->payload) { - free_picture(&x265pic); + free_picture(ctx, &x265pic); return AVERROR(ENOMEM); } sei_payload->payloadSize = side_data->size; @@ -680,8 +753,19 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type); if (x265pic_out.userData) { - memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque)); - av_freep(&x265pic_out.userData); + int idx = (int)(intptr_t)x265pic_out.userData - 1; + ReorderedData *rd = &ctx->rd[idx]; + + avctx->reordered_opaque = rd->reordered_opaque; + pkt->duration = rd->duration; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = rd->frame_opaque; + pkt->opaque_ref = rd->frame_opaque_ref; + rd->frame_opaque_ref = NULL; + } + + rd_release(ctx, idx); } else avctx->reordered_opaque = 0; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libxavs2.c b/arm/raspi/third_party/ffmpeg/libavcodec/libxavs2.c index 1672edfc..c493ddc3 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libxavs2.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libxavs2.c @@ -96,8 +96,8 @@ static av_cold int xavs2_init(AVCodecContext *avctx) xavs2_opt_set2("OpenGOP", "%d", !(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)); { - AVDictionaryEntry *en = NULL; - while ((en = av_dict_get(cae->xavs2_opts, "", en, AV_DICT_IGNORE_SUFFIX))) + const AVDictionaryEntry *en = NULL; + while ((en = av_dict_iterate(cae->xavs2_opts, en))) xavs2_opt_set2(en->key, "%s", en->value); } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/libxvid.c b/arm/raspi/third_party/ffmpeg/libavcodec/libxvid.c index 4e04b3c0..aba875b6 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/libxvid.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/libxvid.c @@ -902,7 +902,7 @@ const FFCodec ff_libxvid_encoder = { CODEC_LONG_NAME("libxvidcore MPEG-4 part 2"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_MPEG4, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(struct xvid_context), .init = xvid_encode_init, FF_CODEC_ENCODE_CB(xvid_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ljpegenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/ljpegenc.c index 81c52a7c..aa62beac 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ljpegenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ljpegenc.c @@ -316,7 +316,8 @@ const FFCodec ff_ljpeg_encoder = { CODEC_LONG_NAME("Lossless JPEG"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_LJPEG, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(LJpegEncContext), .p.priv_class = &ljpeg_class, .init = ljpeg_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/magicyuvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/magicyuvenc.c index 7f9ff728..9e41c1b0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/magicyuvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/magicyuvenc.c @@ -569,7 +569,8 @@ const FFCodec ff_magicyuv_encoder = { CODEC_LONG_NAME("MagicYUV video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_MAGICYUV, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(MagicYUVContext), .p.priv_class = &magicyuv_class, .init = magy_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mathops.h b/arm/raspi/third_party/ffmpeg/libavcodec/mathops.h index c89054d6..a1dc3233 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mathops.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mathops.h @@ -138,6 +138,15 @@ static inline av_const int sign_extend(int val, unsigned bits) } #endif +#ifndef sign_extend64 +static inline av_const int64_t sign_extend64(int64_t val, unsigned bits) +{ + unsigned shift = 8 * sizeof(int64_t) - bits; + union { uint64_t u; int64_t s; } v = { (uint64_t) val << shift }; + return v.s >> shift; +} +#endif + #ifndef zero_extend static inline av_const unsigned zero_extend(unsigned val, unsigned bits) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/media100_to_mjpegb_bsf.c b/arm/raspi/third_party/ffmpeg/libavcodec/media100_to_mjpegb_bsf.c new file mode 100644 index 00000000..6e117ae2 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/media100_to_mjpegb_bsf.c @@ -0,0 +1,168 @@ +/* + * Media 100 to MJPEGB bitstream filter + * Copyright (c) 2023 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Media 100 to MJPEGB bitstream filter. + */ + +#include "libavutil/intreadwrite.h" +#include "bsf.h" +#include "bsf_internal.h" +#include "bytestream.h" + +static av_cold int init(AVBSFContext *ctx) +{ + ctx->par_out->codec_id = AV_CODEC_ID_MJPEGB; + return 0; +} + +static int filter(AVBSFContext *ctx, AVPacket *out) +{ + unsigned second_field_offset = 0; + unsigned next_field = 0; + unsigned dht_offset[2]; + unsigned dqt_offset[2]; + unsigned sod_offset[2]; + unsigned sof_offset[2]; + unsigned sos_offset[2]; + unsigned field = 0; + GetByteContext gb; + PutByteContext pb; + AVPacket *in; + int ret; + + ret = ff_bsf_get_packet(ctx, &in); + if (ret < 0) + return ret; + + ret = av_new_packet(out, in->size + 1024); + if (ret < 0) + goto fail; + + bytestream2_init(&gb, in->data, in->size); + bytestream2_init_writer(&pb, out->data, out->size); + +second_field: + bytestream2_put_be32(&pb, 0); + bytestream2_put_be32(&pb, AV_RB32("mjpg")); + bytestream2_put_be32(&pb, 0); + bytestream2_put_be32(&pb, 0); + for (int i = 0; i < 6; i++) + bytestream2_put_be32(&pb, 0); + + sof_offset[field] = bytestream2_tell_p(&pb); + bytestream2_put_be16(&pb, 17); + bytestream2_put_byte(&pb, 8); + bytestream2_put_be16(&pb, ctx->par_in->height / 2); + bytestream2_put_be16(&pb, ctx->par_in->width); + bytestream2_put_byte(&pb, 3); + bytestream2_put_byte(&pb, 1); + bytestream2_put_byte(&pb, 0x21); + bytestream2_put_byte(&pb, 0); + bytestream2_put_byte(&pb, 2); + bytestream2_put_byte(&pb, 0x11); + bytestream2_put_byte(&pb, 1); + bytestream2_put_byte(&pb, 3); + bytestream2_put_byte(&pb, 0x11); + bytestream2_put_byte(&pb, 1); + + sos_offset[field] = bytestream2_tell_p(&pb); + bytestream2_put_be16(&pb, 12); + bytestream2_put_byte(&pb, 3); + bytestream2_put_byte(&pb, 1); + bytestream2_put_byte(&pb, 0); + bytestream2_put_byte(&pb, 2); + bytestream2_put_byte(&pb, 0x11); + bytestream2_put_byte(&pb, 3); + bytestream2_put_byte(&pb, 0x11); + bytestream2_put_byte(&pb, 0); + bytestream2_put_byte(&pb, 0); + bytestream2_put_byte(&pb, 0); + + dqt_offset[field] = bytestream2_tell_p(&pb); + bytestream2_put_be16(&pb, 132); + bytestream2_put_byte(&pb, 0); + bytestream2_skip(&gb, 4); + for (int i = 0; i < 64; i++) + bytestream2_put_byte(&pb, bytestream2_get_be32(&gb)); + bytestream2_put_byte(&pb, 1); + for (int i = 0; i < 64; i++) + bytestream2_put_byte(&pb, bytestream2_get_be32(&gb)); + + dht_offset[field] = 0; + sod_offset[field] = bytestream2_tell_p(&pb); + + for (int i = bytestream2_tell(&gb) + 8; next_field == 0 && i < in->size - 4; i++) { + if (AV_RB32(in->data + i) == 0x00000001) { + next_field = i; + break; + } + } + + bytestream2_skip(&gb, 8); + bytestream2_copy_buffer(&pb, &gb, next_field - bytestream2_tell(&gb)); + bytestream2_put_be64(&pb, 0); + + if (field == 0) { + field = 1; + second_field_offset = bytestream2_tell_p(&pb); + next_field = in->size; + goto second_field; + } + + AV_WB32(out->data + 8, second_field_offset); + AV_WB32(out->data + 12, second_field_offset); + AV_WB32(out->data + 16, second_field_offset); + AV_WB32(out->data + 20, dqt_offset[0]); + AV_WB32(out->data + 24, dht_offset[0]); + AV_WB32(out->data + 28, sof_offset[0]); + AV_WB32(out->data + 32, sos_offset[0]); + AV_WB32(out->data + 36, sod_offset[0]); + + AV_WB32(out->data + second_field_offset + 8, bytestream2_tell_p(&pb) - second_field_offset); + AV_WB32(out->data + second_field_offset + 12, bytestream2_tell_p(&pb) - second_field_offset); + AV_WB32(out->data + second_field_offset + 16, 0); + AV_WB32(out->data + second_field_offset + 20, dqt_offset[1] - second_field_offset); + AV_WB32(out->data + second_field_offset + 24, dht_offset[1]); + AV_WB32(out->data + second_field_offset + 28, sof_offset[1] - second_field_offset); + AV_WB32(out->data + second_field_offset + 32, sos_offset[1] - second_field_offset); + AV_WB32(out->data + second_field_offset + 36, sod_offset[1] - second_field_offset); + + out->size = bytestream2_tell_p(&pb); + + ret = av_packet_copy_props(out, in); + if (ret < 0) + goto fail; + +fail: + if (ret < 0) + av_packet_unref(out); + av_packet_free(&in); + return ret; +} + +const FFBitStreamFilter ff_media100_to_mjpegb_bsf = { + .p.name = "media100_to_mjpegb", + .p.codec_ids = (const enum AVCodecID []){ AV_CODEC_ID_MEDIA100, AV_CODEC_ID_NONE }, + .init = init, + .filter = filter, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.c b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.c index 555058e9..34ec2134 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -57,19 +58,6 @@ struct JNIAMediaCodecListFields { jclass codec_profile_level_class; jfieldID profile_id; jfieldID level_id; - - jfieldID avc_profile_baseline_id; - jfieldID avc_profile_main_id; - jfieldID avc_profile_extended_id; - jfieldID avc_profile_high_id; - jfieldID avc_profile_high10_id; - jfieldID avc_profile_high422_id; - jfieldID avc_profile_high444_id; - - jfieldID hevc_profile_main_id; - jfieldID hevc_profile_main10_id; - jfieldID hevc_profile_main10_hdr10_id; - }; static const struct FFJniField jni_amediacodeclist_mapping[] = { @@ -95,18 +83,6 @@ static const struct FFJniField jni_amediacodeclist_mapping[] = { { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 }, { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileBaseline", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_baseline_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_main_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileExtended", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_extended_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high10_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh422", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high422_id), 1 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh444", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high444_id), 1 }, - - { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main_id), 0 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_id), 0 }, - { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10HDR10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_hdr10_id), 0 }, - { NULL } }; @@ -326,71 +302,64 @@ static const FFAMediaCodec media_codec_jni; int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx) { - int ret = -1; + // Copy and modified from MediaCodecInfo.java + static const int AVCProfileBaseline = 0x01; + static const int AVCProfileMain = 0x02; + static const int AVCProfileExtended = 0x04; + static const int AVCProfileHigh = 0x08; + static const int AVCProfileHigh10 = 0x10; + static const int AVCProfileHigh422 = 0x20; + static const int AVCProfileHigh444 = 0x40; + static const int AVCProfileConstrainedBaseline = 0x10000; + static const int AVCProfileConstrainedHigh = 0x80000; - JNIEnv *env = NULL; - struct JNIAMediaCodecListFields jfields = { 0 }; - jfieldID field_id = 0; + static const int HEVCProfileMain = 0x01; + static const int HEVCProfileMain10 = 0x02; + static const int HEVCProfileMainStill = 0x04; + static const int HEVCProfileMain10HDR10 = 0x1000; + static const int HEVCProfileMain10HDR10Plus = 0x2000; - JNI_GET_ENV_OR_RETURN(env, avctx, -1); - - if (ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx) < 0) { - goto done; - } + // Unused yet. + (void)AVCProfileConstrainedHigh; + (void)HEVCProfileMain10HDR10; + (void)HEVCProfileMain10HDR10Plus; if (avctx->codec_id == AV_CODEC_ID_H264) { switch(avctx->profile) { case FF_PROFILE_H264_BASELINE: + return AVCProfileBaseline; case FF_PROFILE_H264_CONSTRAINED_BASELINE: - field_id = jfields.avc_profile_baseline_id; - break; + return AVCProfileConstrainedBaseline; case FF_PROFILE_H264_MAIN: - field_id = jfields.avc_profile_main_id; + return AVCProfileMain; break; case FF_PROFILE_H264_EXTENDED: - field_id = jfields.avc_profile_extended_id; - break; + return AVCProfileExtended; case FF_PROFILE_H264_HIGH: - field_id = jfields.avc_profile_high_id; - break; + return AVCProfileHigh; case FF_PROFILE_H264_HIGH_10: case FF_PROFILE_H264_HIGH_10_INTRA: - field_id = jfields.avc_profile_high10_id; - break; + return AVCProfileHigh10; case FF_PROFILE_H264_HIGH_422: case FF_PROFILE_H264_HIGH_422_INTRA: - field_id = jfields.avc_profile_high422_id; - break; + return AVCProfileHigh422; case FF_PROFILE_H264_HIGH_444: case FF_PROFILE_H264_HIGH_444_INTRA: case FF_PROFILE_H264_HIGH_444_PREDICTIVE: - field_id = jfields.avc_profile_high444_id; - break; + return AVCProfileHigh444; } } else if (avctx->codec_id == AV_CODEC_ID_HEVC) { switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: + return HEVCProfileMain; case FF_PROFILE_HEVC_MAIN_STILL_PICTURE: - field_id = jfields.hevc_profile_main_id; - break; + return HEVCProfileMainStill; case FF_PROFILE_HEVC_MAIN_10: - field_id = jfields.hevc_profile_main10_id; - break; + return HEVCProfileMain10; } } - if (field_id) { - ret = (*env)->GetStaticIntField(env, jfields.codec_profile_level_class, field_id); - if (ff_jni_exception_check(env, 1, avctx) < 0) { - ret = -1; - goto done; - } - } - -done: - ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx); - - return ret; + return -1; } char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx) @@ -1861,12 +1830,16 @@ typedef struct FFAMediaFormatNdk { bool (*getSize)(AMediaFormat*, const char *name, size_t *out); bool (*getBuffer)(AMediaFormat*, const char *name, void** data, size_t *size); bool (*getString)(AMediaFormat*, const char *name, const char **out); + bool (*getRect)(AMediaFormat *, const char *name, + int32_t *left, int32_t *top, int32_t *right, int32_t *bottom); void (*setInt32)(AMediaFormat*, const char* name, int32_t value); void (*setInt64)(AMediaFormat*, const char* name, int64_t value); void (*setFloat)(AMediaFormat*, const char* name, float value); void (*setString)(AMediaFormat*, const char* name, const char* value); void (*setBuffer)(AMediaFormat*, const char* name, const void* data, size_t size); + void (*setRect)(AMediaFormat *, const char *name, + int32_t left, int32_t top, int32_t right, int32_t bottom); } FFAMediaFormatNdk; typedef struct FFAMediaCodecNdk { @@ -1940,9 +1913,12 @@ static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl) if (!format->libmedia) goto error; -#define GET_SYMBOL(sym) \ - format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym); \ - if (!format->sym) \ +#define GET_OPTIONAL_SYMBOL(sym) \ + format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym); + +#define GET_SYMBOL(sym) \ + GET_OPTIONAL_SYMBOL(sym) \ + if (!format->sym) \ goto error; GET_SYMBOL(new) @@ -1956,14 +1932,17 @@ static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl) GET_SYMBOL(getSize) GET_SYMBOL(getBuffer) GET_SYMBOL(getString) + GET_OPTIONAL_SYMBOL(getRect) GET_SYMBOL(setInt32) GET_SYMBOL(setInt64) GET_SYMBOL(setFloat) GET_SYMBOL(setString) GET_SYMBOL(setBuffer) + GET_OPTIONAL_SYMBOL(setRect) #undef GET_SYMBOL +#undef GET_OPTIONAL_SYMBOL if (impl) { format->impl = impl; @@ -2047,6 +2026,15 @@ static int mediaformat_ndk_getString(FFAMediaFormat* ctx, const char *name, cons return ret; } +static int mediaformat_ndk_getRect(FFAMediaFormat *ctx, const char *name, + int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) +{ + FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx; + if (!format->getRect) + return AVERROR_EXTERNAL; + return format->getRect(format->impl, name, left, top, right, bottom); +} + static void mediaformat_ndk_setInt32(FFAMediaFormat* ctx, const char* name, int32_t value) { FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx; @@ -2077,6 +2065,17 @@ static void mediaformat_ndk_setBuffer(FFAMediaFormat* ctx, const char* name, voi format->setBuffer(format->impl, name, data, size); } +static void mediaformat_ndk_setRect(FFAMediaFormat *ctx, const char *name, + int32_t left, int32_t top, int32_t right, int32_t bottom) +{ + FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx; + if (!format->setRect) { + av_log(ctx, AV_LOG_WARNING, "Doesn't support setRect\n"); + return; + } + format->setRect(format->impl, name, left, top, right, bottom); +} + static char *mediacodec_ndk_getName(FFAMediaCodec *ctx) { FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; @@ -2433,12 +2432,14 @@ static const FFAMediaFormat media_format_ndk = { .getFloat = mediaformat_ndk_getFloat, .getBuffer = mediaformat_ndk_getBuffer, .getString = mediaformat_ndk_getString, + .getRect = mediaformat_ndk_getRect, .setInt32 = mediaformat_ndk_setInt32, .setInt64 = mediaformat_ndk_setInt64, .setFloat = mediaformat_ndk_setFloat, .setString = mediaformat_ndk_setString, .setBuffer = mediaformat_ndk_setBuffer, + .setRect = mediaformat_ndk_setRect, }; static const FFAMediaCodec media_codec_ndk = { @@ -2512,6 +2513,21 @@ FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk int ff_Build_SDK_INT(AVCodecContext *avctx) { int ret = -1; + +#if __ANDROID_API__ >= 24 + // android_get_device_api_level() is a static inline before API level 29. + // dlsym() might doesn't work. + // + // We can implement android_get_device_api_level() by + // __system_property_get(), but __system_property_get() has created a lot of + // troubles and is deprecated. So avoid using __system_property_get() for + // now. + // + // Hopy we can remove the conditional compilation finally by bumping the + // required API level. + // + ret = android_get_device_api_level(); +#else JNIEnv *env = NULL; jclass versionClass; jfieldID sdkIntFieldID; @@ -2521,5 +2537,8 @@ int ff_Build_SDK_INT(AVCodecContext *avctx) sdkIntFieldID = (*env)->GetStaticFieldID(env, versionClass, "SDK_INT", "I"); ret = (*env)->GetStaticIntField(env, versionClass, sdkIntFieldID); (*env)->DeleteLocalRef(env, versionClass); +#endif + av_log(avctx, AV_LOG_DEBUG, "device api level %d\n", ret); + return ret; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.h b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.h index f15ad66d..1b81e6db 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodec_wrapper.h @@ -73,12 +73,18 @@ struct FFAMediaFormat { int (*getFloat)(FFAMediaFormat* format, const char *name, float *out); int (*getBuffer)(FFAMediaFormat* format, const char *name, void** data, size_t *size); int (*getString)(FFAMediaFormat* format, const char *name, const char **out); + // NDK only, introduced in API level 28 + int (*getRect)(FFAMediaFormat *, const char *name, + int32_t *left, int32_t *top, int32_t *right, int32_t *bottom); void (*setInt32)(FFAMediaFormat* format, const char* name, int32_t value); void (*setInt64)(FFAMediaFormat* format, const char* name, int64_t value); void (*setFloat)(FFAMediaFormat* format, const char* name, float value); void (*setString)(FFAMediaFormat* format, const char* name, const char* value); void (*setBuffer)(FFAMediaFormat* format, const char* name, void* data, size_t size); + // NDK only, introduced in API level 28 + void (*setRect)(FFAMediaFormat*, const char* name, + int32_t left, int32_t top, int32_t right, int32_t bottom); }; FFAMediaFormat *ff_AMediaFormat_new(int ndk); @@ -118,6 +124,14 @@ static inline int ff_AMediaFormat_getString(FFAMediaFormat* format, const char * return format->getString(format, name, out); } +static inline int ff_AMediaFormat_getRect(FFAMediaFormat *format, const char *name, + int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) +{ + if (!format->getRect) + return AVERROR_EXTERNAL; + return format->getRect(format, name, left, top, right, bottom); +} + static inline void ff_AMediaFormat_setInt32(FFAMediaFormat* format, const char* name, int32_t value) { format->setInt32(format, name, value); @@ -143,6 +157,16 @@ static inline void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char* format->setBuffer(format, name, data, size); } +static inline void ff_AMediaFormat_setRect(FFAMediaFormat* format, const char* name, + int32_t left, int32_t top, int32_t right, int32_t bottom) +{ + if (!format->setRect) { + av_log(format, AV_LOG_WARNING, "Doesn't support setRect\n"); + return; + } + format->setRect(format, name, left, top, right, bottom); +} + typedef struct FFAMediaCodecCryptoInfo FFAMediaCodecCryptoInfo; struct FFAMediaCodecBufferInfo { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec.c index 2c231d1a..21464900 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec.c @@ -289,7 +289,8 @@ done: #if CONFIG_MPEG2_MEDIACODEC_DECODER || \ CONFIG_MPEG4_MEDIACODEC_DECODER || \ CONFIG_VP8_MEDIACODEC_DECODER || \ - CONFIG_VP9_MEDIACODEC_DECODER + CONFIG_VP9_MEDIACODEC_DECODER || \ + CONFIG_AV1_MEDIACODEC_DECODER static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) { int ret = 0; @@ -323,6 +324,15 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx) } switch (avctx->codec_id) { +#if CONFIG_AV1_MEDIACODEC_DECODER + case AV_CODEC_ID_AV1: + codec_mime = "video/av01"; + + ret = common_set_extradata(avctx, format); + if (ret < 0) + goto done; + break; +#endif #if CONFIG_H264_MEDIACODEC_DECODER case AV_CODEC_ID_H264: codec_mime = "video/avc"; @@ -405,7 +415,13 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx) s->ctx->codec_name, ret); sdk_int = ff_Build_SDK_INT(avctx); - if (sdk_int <= 23 && + /* ff_Build_SDK_INT can fail when target API < 24 and JVM isn't available. + * If we don't check sdk_int > 0, the workaround might be enabled by + * mistake. + * JVM is required to make the workaround works reliably. On the other hand, + * missing a workaround should not be a serious issue, we do as best we can. + */ + if (sdk_int > 0 && sdk_int <= 23 && strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) { av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n", s->ctx->codec_name, sdk_int); @@ -591,3 +607,7 @@ DECLARE_MEDIACODEC_VDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL) #if CONFIG_VP9_MEDIACODEC_DECODER DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL) #endif + +#if CONFIG_AV1_MEDIACODEC_DECODER +DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL) +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec_common.c b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec_common.c index 80089439..03bee119 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec_common.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecdec_common.c @@ -486,6 +486,10 @@ static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecConte AMEDIAFORMAT_GET_INT32(s->crop_left, "crop-left", 0); AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0); + // Try "crop" for NDK + if (!(s->crop_right && s->crop_bottom) && s->use_ndk_codec) + ff_AMediaFormat_getRect(s->format, "crop", &s->crop_left, &s->crop_top, &s->crop_right, &s->crop_bottom); + if (s->crop_right && s->crop_bottom) { width = s->crop_right + 1 - s->crop_left; height = s->crop_bottom + 1 - s->crop_top; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecenc.c index 7cdde599..a92a8dc5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mediacodecenc.c @@ -28,6 +28,7 @@ #include "libavutil/opt.h" #include "avcodec.h" +#include "bsf.h" #include "codec_internal.h" #include "encode.h" #include "hwconfig.h" @@ -39,10 +40,22 @@ #define INPUT_DEQUEUE_TIMEOUT_US 8000 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000 +enum BitrateMode { + /* Constant quality mode */ + BITRATE_MODE_CQ = 0, + /* Variable bitrate mode */ + BITRATE_MODE_VBR = 1, + /* Constant bitrate mode */ + BITRATE_MODE_CBR = 2, + /* Constant bitrate mode with frame drops */ + BITRATE_MODE_CBR_FD = 3, +}; + typedef struct MediaCodecEncContext { AVClass *avclass; FFAMediaCodec *codec; int use_ndk_codec; + const char *name; FFANativeWindow *window; int fps; @@ -51,21 +64,14 @@ typedef struct MediaCodecEncContext { uint8_t *extradata; int extradata_size; - - // Since MediaCodec doesn't output DTS, use a timestamp queue to save pts - // of AVFrame and generate DTS for AVPacket. - // - // This doesn't work when use Surface as input, in that case frames can be - // sent to encoder without our notice. One exception is frames come from - // our MediaCodec decoder wrapper, since we can control it's render by - // av_mediacodec_release_buffer. - int64_t timestamps[32]; - int ts_head; - int ts_tail; - int eof_sent; AVFrame *frame; + AVBSFContext *bsf; + + int bitrate_mode; + int level; + int pts_as_dts; } MediaCodecEncContext; enum { @@ -104,6 +110,42 @@ static void mediacodec_output_format(AVCodecContext *avctx) ff_AMediaFormat_delete(out_format); } +static int mediacodec_init_bsf(AVCodecContext *avctx) +{ + MediaCodecEncContext *s = avctx->priv_data; + char str[128]; + int ret; + int crop_right = s->width - avctx->width; + int crop_bottom = s->height - avctx->height; + + if (!crop_right && !crop_bottom) + return 0; + + if (avctx->codec_id == AV_CODEC_ID_H264) + ret = snprintf(str, sizeof(str), "h264_metadata=crop_right=%d:crop_bottom=%d", + crop_right, crop_bottom); + else if (avctx->codec_id == AV_CODEC_ID_HEVC) + ret = snprintf(str, sizeof(str), "hevc_metadata=crop_right=%d:crop_bottom=%d", + crop_right, crop_bottom); + else + return 0; + + if (ret >= sizeof(str)) + return AVERROR_BUFFER_TOO_SMALL; + + ret = av_bsf_list_parse_str(str, &s->bsf); + if (ret < 0) + return ret; + + ret = avcodec_parameters_from_context(s->bsf->par_in, avctx); + if (ret < 0) + return ret; + s->bsf->time_base_in = avctx->time_base; + ret = av_bsf_init(s->bsf); + + return ret; +} + static av_cold int mediacodec_init(AVCodecContext *avctx) { const char *codec_mime = NULL; @@ -126,7 +168,10 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) av_assert0(0); } - s->codec = ff_AMediaCodec_createEncoderByType(codec_mime, s->use_ndk_codec); + if (s->name) + s->codec = ff_AMediaCodec_createCodecByName(s->name, s->use_ndk_codec); + else + s->codec = ff_AMediaCodec_createEncoderByType(codec_mime, s->use_ndk_codec); if (!s->codec) { av_log(avctx, AV_LOG_ERROR, "Failed to create encoder for type %s\n", codec_mime); @@ -140,8 +185,19 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) } ff_AMediaFormat_setString(format, "mime", codec_mime); - s->width = FFALIGN(avctx->width, 16); - s->height = avctx->height; + // Workaround the alignment requirement of mediacodec. We can't do it + // silently for AV_PIX_FMT_MEDIACODEC. + if (avctx->pix_fmt != AV_PIX_FMT_MEDIACODEC) { + s->width = FFALIGN(avctx->width, 16); + s->height = FFALIGN(avctx->height, 16); + } else { + s->width = avctx->width; + s->height = avctx->height; + if (s->width % 16 || s->height % 16) + av_log(avctx, AV_LOG_WARNING, + "Video size %dx%d isn't align to 16, it may have device compatibility issue\n", + s->width, s->height); + } ff_AMediaFormat_setInt32(format, "width", s->width); ff_AMediaFormat_setInt32(format, "height", s->height); @@ -167,6 +223,16 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Missing hw_device_ctx or hwaccel_context for AV_PIX_FMT_MEDIACODEC\n"); goto bailout; } + /* Although there is a method ANativeWindow_toSurface() introduced in + * API level 26, it's easier and safe to always require a Surface for + * Java MediaCodec. + */ + if (!s->use_ndk_codec && !s->window->surface) { + ret = AVERROR(EINVAL); + av_log(avctx, AV_LOG_ERROR, "Missing jobject Surface for AV_PIX_FMT_MEDIACODEC. " + "Please note that Java MediaCodec doesn't work with ANativeWindow.\n"); + goto bailout; + } } for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { @@ -179,6 +245,8 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) if (avctx->bit_rate) ff_AMediaFormat_setInt32(format, "bitrate", avctx->bit_rate); + if (s->bitrate_mode >= 0) + ff_AMediaFormat_setInt32(format, "bitrate-mode", s->bitrate_mode); // frame-rate and i-frame-interval are required to configure codec if (avctx->framerate.num >= avctx->framerate.den && avctx->framerate.den > 0) { s->fps = avctx->framerate.num / avctx->framerate.den; @@ -199,6 +267,27 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) ff_AMediaFormat_setInt32(format, "frame-rate", s->fps); ff_AMediaFormat_setInt32(format, "i-frame-interval", gop); + ret = ff_AMediaCodecProfile_getProfileFromAVCodecContext(avctx); + if (ret > 0) { + av_log(avctx, AV_LOG_DEBUG, "set profile to 0x%x\n", ret); + ff_AMediaFormat_setInt32(format, "profile", ret); + } + if (s->level > 0) { + av_log(avctx, AV_LOG_DEBUG, "set level to 0x%x\n", s->level); + ff_AMediaFormat_setInt32(format, "level", s->level); + } + if (avctx->max_b_frames > 0) { + if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_ERROR, + "Enabling B frames will produce packets with no DTS. " + "Use -strict experimental to use it anyway.\n"); + ret = AVERROR(EINVAL); + goto bailout; + } + ff_AMediaFormat_setInt32(format, "max-bframes", avctx->max_b_frames); + } + if (s->pts_as_dts == -1) + s->pts_as_dts = avctx->max_b_frames <= 0; ret = ff_AMediaCodec_getConfigureFlagEncode(s->codec); ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret); @@ -213,6 +302,10 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) goto bailout; } + ret = mediacodec_init_bsf(avctx); + if (ret) + goto bailout; + mediacodec_output_format(avctx); s->frame = av_frame_alloc(); @@ -287,11 +380,8 @@ static int mediacodec_receive(AVCodecContext *avctx, } memcpy(pkt->data + extradata_size, out_buf + out_info.offset, out_info.size); pkt->pts = av_rescale_q(out_info.presentationTimeUs, AV_TIME_BASE_Q, avctx->time_base); - if (s->ts_tail != s->ts_head) { - pkt->dts = s->timestamps[s->ts_tail]; - s->ts_tail = (s->ts_tail + 1) % FF_ARRAY_ELEMS(s->timestamps); - } - + if (s->pts_as_dts) + pkt->dts = pkt->pts; if (out_info.flags & ff_AMediaCodec_getBufferFlagKeyFrame(codec)) pkt->flags |= AV_PKT_FLAG_KEY; ret = 0; @@ -356,14 +446,8 @@ static int mediacodec_send(AVCodecContext *avctx, return ff_AMediaCodec_signalEndOfInputStream(codec); } - - if (frame->data[3]) { - pts = av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q); - s->timestamps[s->ts_head] = frame->pts; - s->ts_head = (s->ts_head + 1) % FF_ARRAY_ELEMS(s->timestamps); - + if (frame->data[3]) av_mediacodec_release_buffer((AVMediaCodecBuffer *)frame->data[3], 1); - } return 0; } @@ -382,9 +466,6 @@ static int mediacodec_send(AVCodecContext *avctx, copy_frame_to_buffer(avctx, frame, input_buf, input_size); pts = av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q); - - s->timestamps[s->ts_head] = frame->pts; - s->ts_head = (s->ts_head + 1) % FF_ARRAY_ELEMS(s->timestamps); } else { flags |= ff_AMediaCodec_getBufferFlagEndOfStream(codec); s->eof_sent = 1; @@ -405,10 +486,24 @@ static int mediacodec_encode(AVCodecContext *avctx, AVPacket *pkt) // 2. Got a packet success // 3. No AVFrame is available yet (don't return if get_frame return EOF) while (1) { + if (s->bsf) { + ret = av_bsf_receive_packet(s->bsf, pkt); + if (!ret) + return 0; + if (ret != AVERROR(EAGAIN)) + return ret; + } + ret = mediacodec_receive(avctx, pkt, &got_packet); - if (!ret) - return 0; - else if (ret != AVERROR(EAGAIN)) + if (s->bsf) { + if (!ret || ret == AVERROR_EOF) + ret = av_bsf_send_packet(s->bsf, pkt); + } else { + if (!ret) + return 0; + } + + if (ret != AVERROR(EAGAIN)) return ret; if (!s->frame->buf[0]) { @@ -441,6 +536,7 @@ static av_cold int mediacodec_close(AVCodecContext *avctx) s->window = NULL; } + av_bsf_free(&s->bsf); av_frame_free(&s->frame); return 0; @@ -461,17 +557,31 @@ static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = { #define OFFSET(x) offsetof(MediaCodecEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM -static const AVOption common_options[] = { - { "ndk_codec", "Use MediaCodec from NDK", - OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, - { NULL }, -}; +#define COMMON_OPTION \ + { "ndk_codec", "Use MediaCodec from NDK", \ + OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \ + { "codec_name", "Select codec by name", \ + OFFSET(name), AV_OPT_TYPE_STRING, {0}, 0, 0, VE }, \ + { "bitrate_mode", "Bitrate control method", \ + OFFSET(bitrate_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "bitrate_mode" }, \ + { "cq", "Constant quality mode", \ + 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, 0, 0, VE, "bitrate_mode" }, \ + { "vbr", "Variable bitrate mode", \ + 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, 0, 0, VE, "bitrate_mode" }, \ + { "cbr", "Constant bitrate mode", \ + 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, 0, 0, VE, "bitrate_mode" }, \ + { "cbr_fd", "Constant bitrate mode with frame drops", \ + 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR_FD}, 0, 0, VE, "bitrate_mode" }, \ + { "pts_as_dts", "Use PTS as DTS. It is enabled automatically if avctx max_b_frames <= 0, " \ + "since most of Android devices don't output B frames by default.", \ + OFFSET(pts_as_dts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \ + #define MEDIACODEC_ENCODER_CLASS(name) \ static const AVClass name ## _mediacodec_class = { \ .class_name = #name "_mediacodec", \ .item_name = av_default_item_name, \ - .option = common_options, \ + .option = name ## _options, \ .version = LIBAVUTIL_VERSION_INT, \ }; \ @@ -496,9 +606,151 @@ const FFCodec ff_ ## short_name ## _mediacodec_encoder = { \ }; \ #if CONFIG_H264_MEDIACODEC_ENCODER + +enum MediaCodecAvcLevel { + AVCLevel1 = 0x01, + AVCLevel1b = 0x02, + AVCLevel11 = 0x04, + AVCLevel12 = 0x08, + AVCLevel13 = 0x10, + AVCLevel2 = 0x20, + AVCLevel21 = 0x40, + AVCLevel22 = 0x80, + AVCLevel3 = 0x100, + AVCLevel31 = 0x200, + AVCLevel32 = 0x400, + AVCLevel4 = 0x800, + AVCLevel41 = 0x1000, + AVCLevel42 = 0x2000, + AVCLevel5 = 0x4000, + AVCLevel51 = 0x8000, + AVCLevel52 = 0x10000, + AVCLevel6 = 0x20000, + AVCLevel61 = 0x40000, + AVCLevel62 = 0x80000, +}; + +static const AVOption h264_options[] = { + COMMON_OPTION + { "level", "Specify level", + OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, "level" }, + { "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel1 }, 0, 0, VE, "level" }, + { "1b", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel1b }, 0, 0, VE, "level" }, + { "1.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel11 }, 0, 0, VE, "level" }, + { "1.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel12 }, 0, 0, VE, "level" }, + { "1.3", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel13 }, 0, 0, VE, "level" }, + { "2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel2 }, 0, 0, VE, "level" }, + { "2.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel21 }, 0, 0, VE, "level" }, + { "2.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel22 }, 0, 0, VE, "level" }, + { "3", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel3 }, 0, 0, VE, "level" }, + { "3.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel31 }, 0, 0, VE, "level" }, + { "3.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel32 }, 0, 0, VE, "level" }, + { "4", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel4 }, 0, 0, VE, "level" }, + { "4.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel41 }, 0, 0, VE, "level" }, + { "4.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel42 }, 0, 0, VE, "level" }, + { "5", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel5 }, 0, 0, VE, "level" }, + { "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel51 }, 0, 0, VE, "level" }, + { "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel52 }, 0, 0, VE, "level" }, + { "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel6 }, 0, 0, VE, "level" }, + { "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel61 }, 0, 0, VE, "level" }, + { "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = AVCLevel62 }, 0, 0, VE, "level" }, + { NULL, } +}; + DECLARE_MEDIACODEC_ENCODER(h264, "H.264", AV_CODEC_ID_H264) -#endif + +#endif // CONFIG_H264_MEDIACODEC_ENCODER #if CONFIG_HEVC_MEDIACODEC_ENCODER + +enum MediaCodecHevcLevel { + HEVCMainTierLevel1 = 0x1, + HEVCHighTierLevel1 = 0x2, + HEVCMainTierLevel2 = 0x4, + HEVCHighTierLevel2 = 0x8, + HEVCMainTierLevel21 = 0x10, + HEVCHighTierLevel21 = 0x20, + HEVCMainTierLevel3 = 0x40, + HEVCHighTierLevel3 = 0x80, + HEVCMainTierLevel31 = 0x100, + HEVCHighTierLevel31 = 0x200, + HEVCMainTierLevel4 = 0x400, + HEVCHighTierLevel4 = 0x800, + HEVCMainTierLevel41 = 0x1000, + HEVCHighTierLevel41 = 0x2000, + HEVCMainTierLevel5 = 0x4000, + HEVCHighTierLevel5 = 0x8000, + HEVCMainTierLevel51 = 0x10000, + HEVCHighTierLevel51 = 0x20000, + HEVCMainTierLevel52 = 0x40000, + HEVCHighTierLevel52 = 0x80000, + HEVCMainTierLevel6 = 0x100000, + HEVCHighTierLevel6 = 0x200000, + HEVCMainTierLevel61 = 0x400000, + HEVCHighTierLevel61 = 0x800000, + HEVCMainTierLevel62 = 0x1000000, + HEVCHighTierLevel62 = 0x2000000, +}; + +static const AVOption hevc_options[] = { + COMMON_OPTION + { "level", "Specify tier and level", + OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, "level" }, + { "m1", "Main tier level 1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel1 }, 0, 0, VE, "level" }, + { "h1", "High tier level 1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel1 }, 0, 0, VE, "level" }, + { "m2", "Main tier level 2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel2 }, 0, 0, VE, "level" }, + { "h2", "High tier level 2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel2 }, 0, 0, VE, "level" }, + { "m2.1", "Main tier level 2.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel21 }, 0, 0, VE, "level" }, + { "h2.1", "High tier level 2.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel21 }, 0, 0, VE, "level" }, + { "m3", "Main tier level 3", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel3 }, 0, 0, VE, "level" }, + { "h3", "High tier level 3", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel3 }, 0, 0, VE, "level" }, + { "m3.1", "Main tier level 3.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel31 }, 0, 0, VE, "level" }, + { "h3.1", "High tier level 3.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel31 }, 0, 0, VE, "level" }, + { "m4", "Main tier level 4", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel4 }, 0, 0, VE, "level" }, + { "h4", "High tier level 4", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel4 }, 0, 0, VE, "level" }, + { "m4.1", "Main tier level 4.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel41 }, 0, 0, VE, "level" }, + { "h4.1", "High tier level 4.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel41 }, 0, 0, VE, "level" }, + { "m5", "Main tier level 5", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel5 }, 0, 0, VE, "level" }, + { "h5", "High tier level 5", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel5 }, 0, 0, VE, "level" }, + { "m5.1", "Main tier level 5.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel51 }, 0, 0, VE, "level" }, + { "h5.1", "High tier level 5.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel51 }, 0, 0, VE, "level" }, + { "m5.2", "Main tier level 5.2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel52 }, 0, 0, VE, "level" }, + { "h5.2", "High tier level 5.2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel52 }, 0, 0, VE, "level" }, + { "m6", "Main tier level 6", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel6 }, 0, 0, VE, "level" }, + { "h6", "High tier level 6", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel6 }, 0, 0, VE, "level" }, + { "m6.1", "Main tier level 6.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel61 }, 0, 0, VE, "level" }, + { "h6.1", "High tier level 6.1", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel61 }, 0, 0, VE, "level" }, + { "m6.2", "Main tier level 6.2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCMainTierLevel62 }, 0, 0, VE, "level" }, + { "h6.2", "High tier level 6.2", + 0, AV_OPT_TYPE_CONST, { .i64 = HEVCHighTierLevel62 }, 0, 0, VE, "level" }, + { NULL, } +}; + DECLARE_MEDIACODEC_ENCODER(hevc, "H.265", AV_CODEC_ID_HEVC) -#endif + +#endif // CONFIG_HEVC_MEDIACODEC_ENCODER diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mfenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mfenc.c index 36a6d848..f3415df1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mfenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mfenc.c @@ -1214,7 +1214,6 @@ static int mf_init(AVCodecContext *avctx) return 0; } } - mf_close(avctx); return ret; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegbdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegbdec.c index 98c64b44..4db1d9a8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegbdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegbdec.c @@ -141,9 +141,10 @@ read_header: av_log(avctx, AV_LOG_WARNING, "no picture\n"); return buf_size; } - av_frame_move_ref(rframe, s->picture_ptr); s->got_picture = 0; + if (avctx->skip_frame == AVDISCARD_ALL) + return buf_size; *got_frame = 1; if (!s->lossless && avctx->debug & FF_DEBUG_QP) { @@ -167,3 +168,18 @@ const FFCodec ff_mjpegb_decoder = { .p.max_lowres = 3, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; + +const FFCodec ff_media100_decoder = { + .p.name = "media100", + CODEC_LONG_NAME("Media 100"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_MEDIA100, + .priv_data_size = sizeof(MJpegDecodeContext), + .init = ff_mjpeg_decode_init, + .close = ff_mjpeg_decode_end, + FF_CODEC_DECODE_CB(mjpegb_decode_frame), + .p.capabilities = AV_CODEC_CAP_DR1, + .p.max_lowres = 3, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .bsfs = "media100_to_mjpegb", +}; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.c index 9b7465ab..f33911e1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.c @@ -131,8 +131,6 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->picture_ptr = s->picture; } - s->pkt = avctx->internal->in_pkt; - s->avctx = avctx; ff_blockdsp_init(&s->bdsp); ff_hpeldsp_init(&s->hdsp, avctx->flags); @@ -452,7 +450,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (ret < 0) return ret; - if ((s->avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || + if (s->avctx->codec_id != AV_CODEC_ID_SMVJPEG && + (s->avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || s->avctx->codec_tag == MKTAG('A', 'V', 'D', 'J')) && s->orig_height < height) s->avctx->height = AV_CEIL_RSHIFT(s->orig_height, s->avctx->lowres); @@ -1512,7 +1511,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } - if (ptr) { + if (ptr && linesize[c]) { s->idsp.idct_put(ptr, linesize[c], s->block); if (s->bits & 7) shift_output(s, ptr, linesize[c]); @@ -2346,67 +2345,9 @@ static void reset_icc_profile(MJpegDecodeContext *s) s->iccnum = 0; } -// SMV JPEG just stacks several output frames into one JPEG picture -// we handle that by setting up the cropping parameters appropriately -static int smv_process_frame(AVCodecContext *avctx, AVFrame *frame) -{ - MJpegDecodeContext *s = avctx->priv_data; - int ret; - - if (s->smv_next_frame > 0) { - av_assert0(s->smv_frame->buf[0]); - av_frame_unref(frame); - ret = av_frame_ref(frame, s->smv_frame); - if (ret < 0) - return ret; - } else { - av_assert0(frame->buf[0]); - av_frame_unref(s->smv_frame); - ret = av_frame_ref(s->smv_frame, frame); - if (ret < 0) - return ret; - } - - av_assert0((s->smv_next_frame + 1) * avctx->height <= avctx->coded_height); - - frame->width = avctx->coded_width; - frame->height = avctx->coded_height; - frame->crop_top = FFMIN(s->smv_next_frame * avctx->height, frame->height); - frame->crop_bottom = frame->height - (s->smv_next_frame + 1) * avctx->height; - - s->smv_next_frame = (s->smv_next_frame + 1) % s->smv_frames_per_jpeg; - - if (s->smv_next_frame == 0) - av_frame_unref(s->smv_frame); - - return 0; -} - -static int mjpeg_get_packet(AVCodecContext *avctx) -{ - MJpegDecodeContext *s = avctx->priv_data; - int ret; - - av_packet_unref(s->pkt); - ret = ff_decode_get_packet(avctx, s->pkt); - if (ret < 0) - return ret; - -#if CONFIG_SP5X_DECODER || CONFIG_AMV_DECODER - if (avctx->codec_id == AV_CODEC_ID_SP5X || - avctx->codec_id == AV_CODEC_ID_AMV) { - ret = ff_sp5x_process_packet(avctx, s->pkt); - if (ret < 0) - return ret; - } -#endif - - s->buf_size = s->pkt->size; - - return 0; -} - -int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) +int ff_mjpeg_decode_frame_from_buf(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, const AVPacket *avpkt, + const uint8_t *buf, const int buf_size) { MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; @@ -2421,8 +2362,7 @@ int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) s->force_pal8 = 0; - if (avctx->codec_id == AV_CODEC_ID_SMVJPEG && s->smv_next_frame > 0) - return smv_process_frame(avctx, frame); + s->buf_size = buf_size; av_dict_free(&s->exif_metadata); av_freep(&s->stereo3d); @@ -2431,12 +2371,9 @@ int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) if (s->iccnum != 0) reset_icc_profile(s); - ret = mjpeg_get_packet(avctx); - if (ret < 0) - return ret; redo_for_pal8: - buf_ptr = s->pkt->data; - buf_end = s->pkt->data + s->pkt->size; + buf_ptr = buf; + buf_end = buf + buf_size; while (buf_ptr < buf_end) { /* find start next marker */ start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end, @@ -2448,7 +2385,7 @@ redo_for_pal8: } else if (unescaped_buf_size > INT_MAX / 8) { av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", - start_code, unescaped_buf_size, s->pkt->size); + start_code, unescaped_buf_size, buf_size); return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n", @@ -2587,7 +2524,6 @@ eoi_parser: } if (avctx->skip_frame == AVDISCARD_ALL) { s->got_picture = 0; - ret = AVERROR(EAGAIN); goto the_end_no_picture; } if (s->avctx->hwaccel) { @@ -2599,10 +2535,9 @@ eoi_parser: } if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) return ret; + *got_frame = 1; s->got_picture = 0; - frame->pkt_dts = s->pkt->dts; - if (!s->lossless && avctx->debug & FF_DEBUG_QP) { int qp = FFMAX3(s->qscale[0], s->qscale[1], @@ -2920,29 +2855,28 @@ the_end: av_dict_copy(&frame->metadata, s->exif_metadata, 0); av_dict_free(&s->exif_metadata); - if (avctx->codec_id == AV_CODEC_ID_SMVJPEG) { - ret = smv_process_frame(avctx, frame); - if (ret < 0) { - av_frame_unref(frame); - return ret; - } - } - if ((avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || + if (avctx->codec_id != AV_CODEC_ID_SMVJPEG && + (avctx->codec_tag == MKTAG('A', 'V', 'R', 'n') || avctx->codec_tag == MKTAG('A', 'V', 'D', 'J')) && avctx->coded_height > s->orig_height) { frame->height = AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres); frame->crop_top = frame->height - avctx->height; } - ret = 0; - the_end_no_picture: av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n", buf_end - buf_ptr); - - return ret; + return buf_ptr - buf; } +int ff_mjpeg_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, + AVPacket *avpkt) +{ + return ff_mjpeg_decode_frame_from_buf(avctx, frame, got_frame, + avpkt, avpkt->data, avpkt->size); +} + + /* mxpeg may call the following function (with a blank MJpegDecodeContext) * even without having called ff_mjpeg_decode_init(). */ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) @@ -3018,7 +2952,7 @@ const FFCodec ff_mjpeg_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_DECODE_CB(ff_mjpeg_decode_frame), .flush = decode_flush, .p.capabilities = AV_CODEC_CAP_DR1, .p.max_lowres = 3, @@ -3026,7 +2960,6 @@ const FFCodec ff_mjpeg_decoder = { .p.profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles), .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | - FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_ICC_PROFILES, .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_MJPEG_NVDEC_HWACCEL @@ -3048,16 +2981,77 @@ const FFCodec ff_thp_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_DECODE_CB(ff_mjpeg_decode_frame), .flush = decode_flush, .p.capabilities = AV_CODEC_CAP_DR1, .p.max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_SETS_PKT_DTS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_SMVJPEG_DECODER +// SMV JPEG just stacks several output frames into one JPEG picture +// we handle that by setting up the cropping parameters appropriately +static void smv_process_frame(AVCodecContext *avctx, AVFrame *frame) +{ + MJpegDecodeContext *s = avctx->priv_data; + + av_assert0((s->smv_next_frame + 1) * avctx->height <= avctx->coded_height); + + frame->width = avctx->coded_width; + frame->height = avctx->coded_height; + frame->crop_top = FFMIN(s->smv_next_frame * avctx->height, frame->height); + frame->crop_bottom = frame->height - (s->smv_next_frame + 1) * avctx->height; + + s->smv_next_frame = (s->smv_next_frame + 1) % s->smv_frames_per_jpeg; + + if (s->smv_next_frame == 0) + av_frame_unref(s->smv_frame); +} + +static int smvjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + MJpegDecodeContext *s = avctx->priv_data; + AVPacket *const pkt = avctx->internal->in_pkt; + int64_t pkt_dts; + int got_frame = 0; + int ret; + + if (s->smv_next_frame > 0) { + av_assert0(s->smv_frame->buf[0]); + ret = av_frame_ref(frame, s->smv_frame); + if (ret < 0) + return ret; + + smv_process_frame(avctx, frame); + return 0; + } + + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0) + return ret; + + ret = ff_mjpeg_decode_frame(avctx, frame, &got_frame, pkt); + pkt_dts = pkt->dts; + av_packet_unref(pkt); + if (ret < 0) + return ret; + + if (!got_frame) + return AVERROR(EAGAIN); + + frame->pkt_dts = pkt_dts; + + av_assert0(frame->buf[0]); + av_frame_unref(s->smv_frame); + ret = av_frame_ref(s->smv_frame, frame); + if (ret < 0) + return ret; + + smv_process_frame(avctx, frame); + return 0; +} + const FFCodec ff_smvjpeg_decoder = { .p.name = "smvjpeg", CODEC_LONG_NAME("SMV JPEG"), @@ -3066,7 +3060,7 @@ const FFCodec ff_smvjpeg_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_RECEIVE_FRAME_CB(smvjpeg_receive_frame), .flush = decode_flush, .p.capabilities = AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.h b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.h index 2cb21890..13c524d5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegdec.h @@ -57,8 +57,6 @@ typedef struct MJpegDecodeContext { GetBitContext gb; int buf_size; - AVPacket *pkt; - int start_code; /* current start code */ int buffer_size; uint8_t *buffer; @@ -173,7 +171,12 @@ int ff_mjpeg_build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table, int is_ac, void *logctx); int ff_mjpeg_decode_init(AVCodecContext *avctx); int ff_mjpeg_decode_end(AVCodecContext *avctx); -int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame); +int ff_mjpeg_decode_frame(AVCodecContext *avctx, + AVFrame *frame, int *got_frame, + AVPacket *avpkt); +int ff_mjpeg_decode_frame_from_buf(AVCodecContext *avctx, + AVFrame *frame, int *got_frame, + const AVPacket *avpkt, const uint8_t *buf, int buf_size); int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); int ff_mjpeg_decode_dht(MJpegDecodeContext *s); int ff_mjpeg_decode_sof(MJpegDecodeContext *s); @@ -184,6 +187,4 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); -int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt); - #endif /* AVCODEC_MJPEGDEC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc.c index eafe7130..50877298 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc.c @@ -651,7 +651,8 @@ const FFCodec ff_mjpeg_encoder = { .init = ff_mpv_encode_init, FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), .close = mjpeg_encode_close, - .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_ICC_PROFILES, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, @@ -685,5 +686,6 @@ const FFCodec ff_amv_encoder = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }, .p.priv_class = &amv_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, }; #endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc_common.c b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc_common.c index 6dfc4469..049ae3d9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc_common.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mjpegenc_common.c @@ -308,7 +308,7 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, default: av_assert0(0); } - put_bits(pb, 16, 17); + put_bits(pb, 16, 8 + 3 * components); if (lossless && ( avctx->pix_fmt == AV_PIX_FMT_BGR0 || avctx->pix_fmt == AV_PIX_FMT_BGRA || avctx->pix_fmt == AV_PIX_FMT_BGR24)) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.c b/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.c index 45715352..924c7314 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.c @@ -159,7 +159,11 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) mh->num_substreams = get_bits(gb, 4); - skip_bits_long(gb, 4 + (header_size - 17) * 8); + skip_bits(gb, 2); + mh->extended_substream_info = get_bits(gb, 2); + mh->substream_info = get_bits(gb, 8); + + skip_bits_long(gb, (header_size - 18) * 8); return 0; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.h b/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.h index f0d7b41c..fa6e3d52 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mlp_parse.h @@ -58,6 +58,9 @@ typedef struct MLPHeaderInfo int peak_bitrate; ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR int num_substreams; ///< Number of substreams within stream + + int extended_substream_info; ///< Which substream of substreams carry 16-channel presentation + int substream_info; ///< Which substream of substreams carry 2/6/8-channel presentation } MLPHeaderInfo; static const uint8_t thd_chancount[13] = { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mlpdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/mlpdec.c index 0b0eb759..0ee1f098 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mlpdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mlpdec.c @@ -153,6 +153,12 @@ typedef struct MLPDecodeContext { /// Number of substreams contained within this stream. uint8_t num_substreams; + /// Which substream of substreams carry 16-channel presentation + uint8_t extended_substream_info; + + /// Which substream of substreams carry 2/6/8-channel presentation + uint8_t substream_info; + /// Index of the last substream to decode - further substreams are skipped. uint8_t max_decoded_substream; @@ -384,6 +390,7 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) m->access_unit_size_pow2 = mh.access_unit_size_pow2; m->num_substreams = mh.num_substreams; + m->substream_info = mh.substream_info; /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */ m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2); @@ -539,7 +546,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, /* This should happen for TrueHD streams with >6 channels and MLP's noise * type. It is not yet known if this is allowed. */ - if (max_channel > MAX_MATRIX_CHANNEL_MLP && !noise_type) { + if (max_matrix_channel > MAX_MATRIX_CHANNEL_MLP && !noise_type) { avpriv_request_sample(m->avctx, "%d channels (more than the " "maximum supported by the decoder)", @@ -1286,7 +1293,13 @@ static int read_access_unit(AVCodecContext *avctx, AVFrame *frame, if (!s->restart_seen) goto next_substr; - if (substr > 0 && substr < m->max_decoded_substream && + if (((avctx->ch_layout.nb_channels == 6 && + ((m->substream_info >> 2) & 0x3) != 0x3) || + (avctx->ch_layout.nb_channels == 8 && + ((m->substream_info >> 4) & 0x7) != 0x7 && + ((m->substream_info >> 4) & 0x7) != 0x6 && + ((m->substream_info >> 4) & 0x7) != 0x3)) && + substr > 0 && substr < m->max_decoded_substream && (s->min_channel <= m->substream[substr - 1].max_channel)) { av_log(avctx, AV_LOG_DEBUG, "Previous substream(%d) channels overlaps current substream(%d) channels, skipping.\n", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mobiclip.c b/arm/raspi/third_party/ffmpeg/libavcodec/mobiclip.c index aca46242..c3b2383d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mobiclip.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mobiclip.c @@ -1216,6 +1216,9 @@ static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe, AVFrame *frame = s->pic[s->current_pic]; int ret; + if (avctx->height/16 * (avctx->width/16) * 2 > 8LL*FFALIGN(pkt->size, 2)) + return AVERROR_INVALIDDATA; + av_fast_padded_malloc(&s->bitstream, &s->bitstream_size, pkt->size); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12dec.c index fdff3fc4..3e85d905 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12dec.c @@ -1694,7 +1694,10 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, av_assert0(mb_y < s->mb_height); - init_get_bits(&s->gb, *buf, buf_size * 8); + ret = init_get_bits8(&s->gb, *buf, buf_size); + if (ret < 0) + return ret; + if (s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16) skip_bits(&s->gb, 3); @@ -2063,7 +2066,9 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, int width, height; int i, v, j; - init_get_bits(&s->gb, buf, buf_size * 8); + int ret = init_get_bits8(&s->gb, buf, buf_size); + if (ret < 0) + return ret; width = get_bits(&s->gb, 12); height = get_bits(&s->gb, 12); @@ -2228,7 +2233,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, int cc_count = 0; int i, ret; - init_get_bits8(&gb, p + 2, buf_size - 2); + ret = init_get_bits8(&gb, p + 2, buf_size - 2); + if (ret < 0) + return ret; cc_count = get_bits(&gb, 5); if (cc_count > 0) { int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; @@ -2400,7 +2407,7 @@ static void mpeg_decode_user_data(AVCodecContext *avctx, } } -static void mpeg_decode_gop(AVCodecContext *avctx, +static int mpeg_decode_gop(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { Mpeg1Context *s1 = avctx->priv_data; @@ -2408,7 +2415,9 @@ static void mpeg_decode_gop(AVCodecContext *avctx, int broken_link; int64_t tc; - init_get_bits(&s->gb, buf, buf_size * 8); + int ret = init_get_bits8(&s->gb, buf, buf_size); + if (ret < 0) + return ret; tc = s1->timecode_frame_start = get_bits(&s->gb, 25); @@ -2425,6 +2434,8 @@ static void mpeg_decode_gop(AVCodecContext *avctx, "GOP (%s) closed_gop=%d broken_link=%d\n", tcbuf, s1->closed_gop, broken_link); } + + return 0; } static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, @@ -2550,7 +2561,9 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, } break; case EXT_START_CODE: - init_get_bits(&s2->gb, buf_ptr, input_size * 8); + ret = init_get_bits8(&s2->gb, buf_ptr, input_size); + if (ret < 0) + return ret; switch (get_bits(&s2->gb, 4)) { case 0x1: @@ -2592,7 +2605,9 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, case GOP_START_CODE: if (last_code == 0) { s2->first_field = 0; - mpeg_decode_gop(avctx, buf_ptr, input_size); + ret = mpeg_decode_gop(avctx, buf_ptr, input_size); + if (ret < 0) + return ret; s->sync = 1; } else { av_log(avctx, AV_LOG_ERROR, @@ -2732,7 +2747,9 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, if (ret < 0) return ret; } - init_get_bits(&thread_context->gb, buf_ptr, input_size * 8); + ret = init_get_bits8(&thread_context->gb, buf_ptr, input_size); + if (ret < 0) + return ret; s->slice_count++; } buf_ptr += 2; // FIXME add minimum number of bytes per slice @@ -2845,6 +2862,7 @@ static void flush(AVCodecContext *avctx) s->sync = 0; s->closed_gop = 0; + av_buffer_unref(&s->a53_buf_ref); ff_mpeg_flush(avctx); } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.c index 3ad1cd84..b5951e43 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.c @@ -468,7 +468,7 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s) put_bits(&s->pb, 1, 0); } -void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) +void ff_mpeg1_encode_picture_header(MpegEncContext *s) { MPEG12EncContext *const mpeg12 = (MPEG12EncContext*)s; AVFrameSideData *side_data; @@ -1246,7 +1246,8 @@ const FFCodec ff_mpeg1video_encoder = { .p.supported_framerates = ff_mpeg12_frame_rate_tab + 1, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .p.priv_class = &mpeg1_class, }; @@ -1264,7 +1265,8 @@ const FFCodec ff_mpeg2video_encoder = { .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }, - .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .p.priv_class = &mpeg2_class, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.h index 0455e5e4..0b35af8a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg12enc.h @@ -26,7 +26,7 @@ #include "mpegvideo.h" -void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_mpeg1_encode_picture_header(MpegEncContext *s); void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64], int motion_x, int motion_y); void ff_mpeg1_encode_init(MpegEncContext *s); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.c index a2a14afb..c3e9ebea 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.c @@ -1056,7 +1056,7 @@ static void mpeg4_encode_vol_header(MpegEncContext *s, } /* write MPEG-4 VOP header */ -int ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_mpeg4_encode_picture_header(MpegEncContext *s) { uint64_t time_incr; int64_t time_div, time_mod; @@ -1065,7 +1065,7 @@ int ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) if (!(s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) { if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) // HACK, the reference sw is buggy mpeg4_encode_visual_object_header(s); - if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number == 0) // HACK, the reference sw is buggy + if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0) // HACK, the reference sw is buggy mpeg4_encode_vol_header(s, 0, 0); } if (!(s->workaround_bugs & FF_BUG_MS)) @@ -1403,7 +1403,8 @@ const FFCodec ff_mpeg4_encoder = { FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), .close = ff_mpv_encode_end, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .p.priv_class = &mpeg4enc_class, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.h b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.h index 243cd297..f0d5c3d0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpeg4videoenc.h @@ -32,7 +32,7 @@ void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y); void ff_set_mpeg4_time(MpegEncContext *s); -int ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); +int ff_mpeg4_encode_picture_header(MpegEncContext *s); void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); void ff_mpeg4_stuffing(PutBitContext *pbc); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_fixed.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_fixed.c index afbffe76..a523b5d5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_fixed.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_fixed.c @@ -28,7 +28,7 @@ const FFCodec ff_mp2fixed_encoder = { CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_MP2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(MpegAudioContext), .init = MPA_encode_init, FF_CODEC_ENCODE_CB(MPA_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_float.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_float.c index 212709c2..6a13d095 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_float.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpegaudioenc_float.c @@ -29,7 +29,7 @@ const FFCodec ff_mp2_encoder = { CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_MP2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(MpegAudioContext), .init = MPA_encode_init, FF_CODEC_ENCODE_CB(MPA_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo.h b/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo.h index ccec0dd7..42275953 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo.h @@ -117,6 +117,7 @@ typedef struct MpegEncContext { int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else int picture_number; //FIXME remove, unclear definition + int extradata_parsed; int picture_in_gop_number; ///< 0-> first pic in gop, ... int mb_width, mb_height; ///< number of MBs horizontally & vertically int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 @@ -174,6 +175,7 @@ typedef struct MpegEncContext { Picture *last_picture_ptr; ///< pointer to the previous picture. Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) Picture *current_picture_ptr; ///< pointer to the current picture + int skipped_last_frame; int last_dc[3]; ///< last DC values for MPEG-1 int16_t *dc_val_base; int16_t *dc_val[3]; ///< used for MPEG-4 DC prediction, all 3 arrays must be continuous diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo_enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo_enc.c index 9b11c5c0..0e6a4c4e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo_enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mpegvideo_enc.c @@ -83,7 +83,7 @@ #define QMAT_SHIFT_MMX 16 #define QMAT_SHIFT 21 -static int encode_picture(MpegEncContext *s, int picture_number); +static int encode_picture(MpegEncContext *s); static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale); static int sse_mb(MpegEncContext *s); static void denoise_dct_c(MpegEncContext *s, int16_t *block); @@ -1795,7 +1795,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, if (ret < 0) return ret; vbv_retry: - ret = encode_picture(s, s->picture_number); + ret = encode_picture(s); if (growing_buffer) { av_assert0(s->pb.buf == avctx->internal->byte_buffer); pkt->data = s->pb.buf; @@ -1952,6 +1952,7 @@ vbv_retry: s->total_bits += s->frame_bits; pkt->pts = s->current_picture.f->pts; + pkt->duration = s->current_picture.f->duration; if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) { if (!s->current_picture.f->coded_picture_number) pkt->dts = pkt->pts - s->dts_delta; @@ -1960,6 +1961,14 @@ vbv_retry: s->reordered_pts = pkt->pts; } else pkt->dts = pkt->pts; + + // the no-delay case is handled in generic code + if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY) { + ret = ff_encode_reordered_opaque(avctx, pkt, s->current_picture.f); + if (ret < 0) + return ret; + } + if (s->current_picture.f->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; if (s->mb_info) @@ -3556,14 +3565,12 @@ static void set_frame_distances(MpegEncContext * s){ } } -static int encode_picture(MpegEncContext *s, int picture_number) +static int encode_picture(MpegEncContext *s) { int i, ret; int bits; int context_count = s->slice_context_count; - s->picture_number = picture_number; - /* Reset the average MB variance */ s->me.mb_var_sum_temp = s->me.mc_mb_var_sum_temp = 0; @@ -3788,32 +3795,32 @@ static int encode_picture(MpegEncContext *s, int picture_number) break; case FMT_H261: if (CONFIG_H261_ENCODER) - ff_h261_encode_picture_header(s, picture_number); + ff_h261_encode_picture_header(s); break; case FMT_H263: if (CONFIG_WMV2_ENCODER && s->codec_id == AV_CODEC_ID_WMV2) - ff_wmv2_encode_picture_header(s, picture_number); + ff_wmv2_encode_picture_header(s); else if (CONFIG_MSMPEG4ENC && s->msmpeg4_version) - ff_msmpeg4_encode_picture_header(s, picture_number); + ff_msmpeg4_encode_picture_header(s); else if (CONFIG_MPEG4_ENCODER && s->h263_pred) { - ret = ff_mpeg4_encode_picture_header(s, picture_number); + ret = ff_mpeg4_encode_picture_header(s); if (ret < 0) return ret; } else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) { - ret = ff_rv10_encode_picture_header(s, picture_number); + ret = ff_rv10_encode_picture_header(s); if (ret < 0) return ret; } else if (CONFIG_RV20_ENCODER && s->codec_id == AV_CODEC_ID_RV20) - ff_rv20_encode_picture_header(s, picture_number); + ff_rv20_encode_picture_header(s); else if (CONFIG_FLV_ENCODER && s->codec_id == AV_CODEC_ID_FLV1) - ff_flv_encode_picture_header(s, picture_number); + ff_flv_encode_picture_header(s); else if (CONFIG_H263_ENCODER) - ff_h263_encode_picture_header(s, picture_number); + ff_h263_encode_picture_header(s); break; case FMT_MPEG1: if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) - ff_mpeg1_encode_picture_header(s, picture_number); + ff_mpeg1_encode_picture_header(s); break; default: av_assert0(0); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.c index 9b6e5efa..54121438 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.c @@ -216,7 +216,7 @@ static void find_best_tables(MSMPEG4EncContext *ms) } /* write MSMPEG4 compatible frame header */ -void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) +void ff_msmpeg4_encode_picture_header(MpegEncContext * s) { MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)s; @@ -684,6 +684,7 @@ const FFCodec ff_msmpeg4v2_encoder = { .p.id = AV_CODEC_ID_MSMPEG4V2, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(MSMPEG4EncContext), .init = ff_mpv_encode_init, @@ -698,6 +699,7 @@ const FFCodec ff_msmpeg4v3_encoder = { .p.id = AV_CODEC_ID_MSMPEG4V3, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(MSMPEG4EncContext), .init = ff_mpv_encode_init, @@ -712,6 +714,7 @@ const FFCodec ff_wmv1_encoder = { .p.id = AV_CODEC_ID_WMV1, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(MSMPEG4EncContext), .init = ff_mpv_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.h index 602e6011..da9a45b5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/msmpeg4enc.h @@ -34,7 +34,7 @@ typedef struct MSMPEG4EncContext { } MSMPEG4EncContext; void ff_msmpeg4_encode_init(MpegEncContext *s); -void ff_msmpeg4_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_msmpeg4_encode_picture_header(MpegEncContext *s); void ff_msmpeg4_encode_ext_header(MpegEncContext *s); void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/msvideo1enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/msvideo1enc.c index a349b42c..36cfd39a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/msvideo1enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/msvideo1enc.c @@ -307,6 +307,7 @@ const FFCodec ff_msvideo1_encoder = { CODEC_LONG_NAME("Microsoft Video-1"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_MSVIDEO1, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(Msvideo1EncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/mvha.c b/arm/raspi/third_party/ffmpeg/libavcodec/mvha.c index b1661c1c..55056c91 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/mvha.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/mvha.c @@ -159,9 +159,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, if (size < 1 || size >= avpkt->size) return AVERROR_INVALIDDATA; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - if (type == MKTAG('L','Z','Y','V')) { z_stream *const zstream = &s->zstream.zstream; ret = inflateReset(zstream); @@ -170,6 +167,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, return AVERROR_EXTERNAL; } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + zstream->next_in = avpkt->data + 8; zstream->avail_in = avpkt->size - 8; @@ -218,10 +218,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, } } + if (get_bits_left(gb) < avctx->height * avctx->width) + return AVERROR_INVALIDDATA; + ret = build_vlc(avctx, &s->vlc); if (ret < 0) return ret; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + for (int p = 0; p < 3; p++) { int width = avctx->width >> (p > 0); ptrdiff_t stride = frame->linesize[p]; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/null.c b/arm/raspi/third_party/ffmpeg/libavcodec/null.c new file mode 100644 index 00000000..d8e33443 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/null.c @@ -0,0 +1,97 @@ +/* + * Null codecs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config_components.h" + +#include "codec_internal.h" +#include "decode.h" +#include "encode.h" + +#if CONFIG_VNULL_DECODER || CONFIG_ANULL_DECODER +static int null_decode(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, AVPacket *avpkt) +{ + *got_frame = 0; + return avpkt->size; +} + +#if CONFIG_VNULL_DECODER +const FFCodec ff_vnull_decoder = { + .p.name = "vnull", + CODEC_LONG_NAME("null video"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_VNULL, + .p.capabilities = AV_CODEC_CAP_DR1, + FF_CODEC_DECODE_CB(null_decode), +}; +#endif + +#if CONFIG_ANULL_DECODER +const FFCodec ff_anull_decoder = { + .p.name = "anull", + CODEC_LONG_NAME("null audio"), + .p.type = AVMEDIA_TYPE_AUDIO, + .p.id = AV_CODEC_ID_ANULL, + .p.capabilities = AV_CODEC_CAP_DR1, + FF_CODEC_DECODE_CB(null_decode), +}; +#endif + +#endif + +#if CONFIG_VNULL_ENCODER || CONFIG_ANULL_ENCODER +static int null_encode(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet) +{ + *got_packet = 0; + return 0; +} + +#if CONFIG_VNULL_ENCODER +const FFCodec ff_vnull_encoder = { + .p.name = "vnull", + CODEC_LONG_NAME("null video"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_VNULL, + FF_CODEC_ENCODE_CB(null_encode), +}; +#endif + +#if CONFIG_ANULL_ENCODER +const FFCodec ff_anull_encoder = { + .p.name = "anull", + CODEC_LONG_NAME("null audio"), + .p.type = AVMEDIA_TYPE_AUDIO, + .p.id = AV_CODEC_ID_ANULL, + .p.capabilities = AV_CODEC_CAP_VARIABLE_FRAME_SIZE, + .p.sample_fmts = (const enum AVSampleFormat[]){ + AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8P, + AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32P, + AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64P, + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE, + }, + FF_CODEC_ENCODE_CB(null_encode), +}; +#endif + +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/nvdec.c index fbaedf0b..a477449d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvdec.c @@ -51,6 +51,8 @@ typedef struct NVDECDecoder { CudaFunctions *cudl; CuvidFunctions *cvdl; + + int unsafe_output; } NVDECDecoder; typedef struct NVDECFramePool { @@ -344,6 +346,8 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) int cuvid_codec_type, cuvid_chroma_format, chroma_444; int ret = 0; + int unsafe_output = !!(avctx->hwaccel_flags & AV_HWACCEL_FLAG_UNSAFE_OUTPUT); + sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); if (!sw_desc) return AVERROR_BUG; @@ -402,7 +406,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) params.CodecType = cuvid_codec_type; params.ChromaFormat = cuvid_chroma_format; params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; - params.ulNumOutputSurfaces = frames_ctx->initial_pool_size; + params.ulNumOutputSurfaces = unsafe_output ? frames_ctx->initial_pool_size : 1; ret = nvdec_decoder_create(&ctx->decoder_ref, frames_ctx->device_ref, ¶ms, avctx); if (ret < 0) { @@ -417,6 +421,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) } decoder = (NVDECDecoder*)ctx->decoder_ref->data; + decoder->unsafe_output = unsafe_output; decoder->real_hw_frames_ref = real_hw_frames_ref; real_hw_frames_ref = NULL; @@ -554,7 +559,11 @@ copy_fail: finish: CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy)); - return ret; + + if (ret < 0 || decoder->unsafe_output) + return ret; + + return av_frame_make_writable(frame); } int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.c index 9726c565..ab42dc96 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.c @@ -28,6 +28,7 @@ #include "av1.h" #endif +#include "libavutil/buffer.h" #include "libavutil/hwcontext_cuda.h" #include "libavutil/hwcontext.h" #include "libavutil/cuda_check.h" @@ -162,6 +163,23 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, return ret; } +typedef struct FrameData { + int64_t pts; + int64_t duration; + int64_t reordered_opaque; + + void *frame_opaque; + AVBufferRef *frame_opaque_ref; +} FrameData; + +static void reorder_queue_flush(AVFifo *queue) +{ + FrameData fd; + + while (av_fifo_read(queue, &fd, 1) >= 0) + av_buffer_unref(&fd.frame_opaque_ref); +} + typedef struct GUIDTuple { const GUID guid; int flags; @@ -1076,6 +1094,7 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) ctx->encode_config.frameIntervalP - 4; if (lkd_bound < 0) { + ctx->encode_config.rcParams.enableLookahead = 0; av_log(avctx, AV_LOG_WARNING, "Lookahead not enabled. Increase buffer delay (-delay).\n"); } else { @@ -1088,6 +1107,9 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) ctx->encode_config.rcParams.lookaheadDepth, ctx->encode_config.rcParams.disableIadapt ? "disabled" : "enabled", ctx->encode_config.rcParams.disableBadapt ? "disabled" : "enabled"); + if (ctx->encode_config.rcParams.lookaheadDepth < ctx->rc_lookahead) + av_log(avctx, AV_LOG_WARNING, "Clipping lookahead depth to %d (from %d) due to lack of surfaces/delay", + ctx->encode_config.rcParams.lookaheadDepth, ctx->rc_lookahead); } } @@ -1110,8 +1132,9 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) av_log(avctx, AV_LOG_VERBOSE, "CQ(%d) mode enabled.\n", tmp_quality); - //CQ mode shall discard avg bitrate & honor max bitrate; + // CQ mode shall discard avg bitrate/vbv buffer size and honor only max bitrate ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate = 0; + ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size = 0; ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; } } @@ -1743,8 +1766,8 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx) if (!ctx->surfaces) return AVERROR(ENOMEM); - ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(int64_t), 0); - if (!ctx->timestamp_list) + ctx->reorder_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(FrameData), 0); + if (!ctx->reorder_queue) return AVERROR(ENOMEM); ctx->unused_surface_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0); @@ -1828,7 +1851,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) p_nvenc->nvEncEncodePicture(ctx->nvencoder, ¶ms); } - av_fifo_freep2(&ctx->timestamp_list); + reorder_queue_flush(ctx->reorder_queue); + av_fifo_freep2(&ctx->reorder_queue); av_fifo_freep2(&ctx->output_surface_ready_queue); av_fifo_freep2(&ctx->output_surface_queue); av_fifo_freep2(&ctx->unused_surface_queue); @@ -2172,18 +2196,45 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, } } -static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp) +static void reorder_queue_enqueue(AVFifo *queue, const AVCodecContext *avctx, + const AVFrame *frame, AVBufferRef **opaque_ref) { - av_fifo_write(queue, ×tamp, 1); + FrameData fd; + + fd.pts = frame->pts; + fd.duration = frame->duration; + fd.reordered_opaque = frame->reordered_opaque; + fd.frame_opaque = frame->opaque; + fd.frame_opaque_ref = *opaque_ref; + + *opaque_ref = NULL; + + av_fifo_write(queue, &fd, 1); } -static inline int64_t timestamp_queue_dequeue(AVFifo *queue) +static int64_t reorder_queue_dequeue(AVFifo *queue, AVCodecContext *avctx, + AVPacket *pkt) { - int64_t timestamp = AV_NOPTS_VALUE; - // The following call might fail if the queue is empty. - av_fifo_read(queue, ×tamp, 1); + FrameData fd; - return timestamp; + // The following call might fail if the queue is empty. + if (av_fifo_read(queue, &fd, 1) < 0) + return AV_NOPTS_VALUE; + + if (pkt) { + avctx->reordered_opaque = fd.reordered_opaque; + pkt->duration = fd.duration; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = fd.frame_opaque; + pkt->opaque_ref = fd.frame_opaque_ref; + fd.frame_opaque_ref = NULL; + } + } + + av_buffer_unref(&fd.frame_opaque_ref); + + return fd.pts; } static int nvenc_set_timestamp(AVCodecContext *avctx, @@ -2191,12 +2242,14 @@ static int nvenc_set_timestamp(AVCodecContext *avctx, AVPacket *pkt) { NvencContext *ctx = avctx->priv_data; + int64_t dts; pkt->pts = params->outputTimeStamp; + dts = reorder_queue_dequeue(ctx->reorder_queue, avctx, pkt); + if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) { - pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list); - pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1); + pkt->dts = dts - FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1); } else { pkt->dts = pkt->pts; } @@ -2293,7 +2346,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur return 0; error: - timestamp_queue_dequeue(ctx->timestamp_list); + reorder_queue_dequeue(ctx->reorder_queue, avctx, NULL); error2: return res; @@ -2523,6 +2576,8 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) int sei_count = 0; int i; + AVBufferRef *opaque_ref = NULL; + NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; @@ -2590,9 +2645,17 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } + // make a reference for enqueing in the reorder queue here, + // so that reorder_queue_enqueue() cannot fail + if (frame && frame->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + opaque_ref = av_buffer_ref(frame->opaque_ref); + if (!opaque_ref) + return AVERROR(ENOMEM); + } + res = nvenc_push_context(avctx); if (res < 0) - return res; + goto opaque_ref_fail; nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params); @@ -2601,17 +2664,17 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) res = nvenc_pop_context(avctx); if (res < 0) - return res; + goto opaque_ref_fail; if (nv_status != NV_ENC_SUCCESS && - nv_status != NV_ENC_ERR_NEED_MORE_INPUT) - return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); + nv_status != NV_ENC_ERR_NEED_MORE_INPUT) { + res = nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); + goto opaque_ref_fail; + } if (frame && frame->buf[0]) { av_fifo_write(ctx->output_surface_queue, &in_surf, 1); - - if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) - timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); + reorder_queue_enqueue(ctx->reorder_queue, avctx, frame, &opaque_ref); } /* all the pending buffers are now ready for output */ @@ -2621,6 +2684,10 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) } return 0; + +opaque_ref_fail: + av_buffer_unref(&opaque_ref); + return res; } int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) @@ -2679,5 +2746,5 @@ av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx) NvencContext *ctx = avctx->priv_data; nvenc_send_frame(avctx, NULL); - av_fifo_reset2(ctx->timestamp_list); + reorder_queue_flush(ctx->reorder_queue); } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.h b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.h index 05a7ac48..411c83aa 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc.h @@ -171,7 +171,7 @@ typedef struct NvencContext AVFifo *unused_surface_queue; AVFifo *output_surface_queue; AVFifo *output_surface_ready_queue; - AVFifo *timestamp_list; + AVFifo *reorder_queue; NV_ENC_SEI_PAYLOAD *sei_data; int sei_data_size; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_av1.c b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_av1.c index 2ed99d94..2b349c7b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_av1.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_av1.c @@ -181,7 +181,8 @@ const FFCodec ff_av1_nvenc_encoder = { .defaults = defaults, .p.pix_fmts = ff_nvenc_pix_fmts, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1, + AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .p.wrapper_name = "nvenc", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_h264.c b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_h264.c index a69358b0..5dc2961c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_h264.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_h264.c @@ -232,7 +232,8 @@ const FFCodec ff_h264_nvenc_encoder = { .p.priv_class = &h264_nvenc_class, .defaults = defaults, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1, + AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .p.pix_fmts = ff_nvenc_pix_fmts, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_hevc.c b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_hevc.c index 5ad42344..1362a927 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_hevc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/nvenc_hevc.c @@ -214,7 +214,8 @@ const FFCodec ff_hevc_nvenc_encoder = { .defaults = defaults, .p.pix_fmts = ff_nvenc_pix_fmts, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1, + AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .p.wrapper_name = "nvenc", diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/options_table.h b/arm/raspi/third_party/ffmpeg/libavcodec/options_table.h index cd02f509..322ec7a1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/options_table.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/options_table.h @@ -58,6 +58,8 @@ static const AVOption avcodec_options[] = { {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, {"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"}, {"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"}, +{"copy_opaque", "propagate opaque values", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_COPY_OPAQUE}, .unit = "flags"}, +{"frame_duration", "use frame durations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_FRAME_DURATION}, .unit = "flags"}, {"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"}, {"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"}, {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"}, @@ -399,6 +401,7 @@ static const AVOption avcodec_options[] = { {"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" }, {"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, {"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"unsafe_output", "allow potentially unsafe hwaccel frame output that might require special care to process successfully", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_UNSAFE_OUTPUT }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, {"extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, V|D }, {"discard_damaged_percentage", "Percentage of damaged samples to discard a frame", OFFSET(discard_damaged_percentage), AV_OPT_TYPE_INT, {.i64 = 95 }, 0, 100, V|D }, {NULL}, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pamenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pamenc.c index 7d01e89f..45ec29cc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pamenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pamenc.c @@ -133,7 +133,7 @@ const FFCodec ff_pam_encoder = { CODEC_LONG_NAME("PAM (Portable AnyMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PAM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pam_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pcm-blurayenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pcm-blurayenc.c index 62e86e72..bfbfa91d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pcm-blurayenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pcm-blurayenc.c @@ -304,5 +304,5 @@ const FFCodec ff_pcm_bluray_encoder = { { 0 } }, .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pcm-dvdenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pcm-dvdenc.c index 011d0a2f..a2e5cbdc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pcm-dvdenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pcm-dvdenc.c @@ -176,7 +176,8 @@ const FFCodec ff_pcm_dvd_encoder = { CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for DVD media"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_PCM_DVD, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PCMDVDContext), .init = pcm_dvd_encode_init, FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pcm.c b/arm/raspi/third_party/ffmpeg/libavcodec/pcm.c index ee36a364..23955ba2 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pcm.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pcm.c @@ -553,7 +553,8 @@ const FFCodec ff_ ## name_ ## _encoder = { \ CODEC_LONG_NAME(long_name_), \ .p.type = AVMEDIA_TYPE_AUDIO, \ .p.id = AV_CODEC_ID_ ## id_, \ - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE, \ + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE | \ + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, \ .init = pcm_encode_init, \ FF_CODEC_ENCODE_CB(pcm_encode_frame), \ .p.sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pcxenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pcxenc.c index 509158ba..cf9b41b7 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pcxenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pcxenc.c @@ -197,7 +197,7 @@ const FFCodec ff_pcx_encoder = { CODEC_LONG_NAME("PC Paintbrush PCX image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PCX, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pcx_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pictordec.c b/arm/raspi/third_party/ffmpeg/libavcodec/pictordec.c index 71bad40a..aef3d3de 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pictordec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pictordec.c @@ -162,6 +162,25 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; + + /* + There are 2 coding modes, RLE and RAW. + Undamaged RAW should be proportional to W*H and thus bigger than RLE + RLE codes the most compressed runs by + 1 byte for val (=marker) + 1 byte run (=0) + 2 bytes run + 1 byte val + thats 5 bytes and the maximum run we can code is 65535 + + The RLE decoder can exit prematurly but it does not on any image available + Based on this the formula is assumed correct for undamaged images. + If an image is found which exploits the special end + handling and breaks this formula then this needs to be adapted. + */ + if (bytestream2_get_bytes_left(&s->g) < s->width * s->height / 65535 * 5) + return AVERROR_INVALIDDATA; + if (s->width != avctx->width || s->height != avctx->height) { ret = ff_set_dimensions(avctx, s->width, s->height); if (ret < 0) @@ -243,8 +262,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, run = bytestream2_get_le16(&s->g); val = bytestream2_get_byte(&s->g); } - if (!bytestream2_get_bytes_left(&s->g)) - break; if (bits_per_plane == 8) { picmemset_8bpp(s, frame, val, run, &x, &y); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pngdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/pngdec.c index 8080094d..0d969dec 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pngdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pngdec.c @@ -26,10 +26,12 @@ #include "libavutil/avassert.h" #include "libavutil/bprint.h" #include "libavutil/crc.h" +#include "libavutil/csp.h" #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" #include "libavutil/stereo3d.h" -#include "libavutil/mastering_display_metadata.h" #include "avcodec.h" #include "bytestream.h" @@ -73,6 +75,11 @@ typedef struct PNGDecContext { int have_chrm; uint32_t white_point[2]; uint32_t display_primaries[3][2]; + int have_srgb; + int have_cicp; + enum AVColorPrimaries cicp_primaries; + enum AVColorTransferCharacteristic cicp_trc; + enum AVColorRange cicp_range; enum PNGHeaderState hdr_state; enum PNGImageState pic_state; @@ -1311,6 +1318,24 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } break; } + case MKTAG('c', 'I', 'C', 'P'): + s->cicp_primaries = bytestream2_get_byte(&gb_chunk); + s->cicp_trc = bytestream2_get_byte(&gb_chunk); + if (bytestream2_get_byte(&gb_chunk) != 0) + av_log(avctx, AV_LOG_WARNING, "nonzero cICP matrix\n"); + s->cicp_range = bytestream2_get_byte(&gb_chunk); + if (s->cicp_range != 0 && s->cicp_range != 1) { + av_log(avctx, AV_LOG_ERROR, "invalid cICP range: %d\n", s->cicp_range); + ret = AVERROR_INVALIDDATA; + goto fail; + } + s->have_cicp = 1; + break; + case MKTAG('s', 'R', 'G', 'B'): + /* skip rendering intent byte */ + bytestream2_skip(&gb_chunk, 1); + s->have_srgb = 1; + break; case MKTAG('i', 'C', 'C', 'P'): { if ((ret = decode_iccp_chunk(s, &gb_chunk, p)) < 0) goto fail; @@ -1362,8 +1387,10 @@ exit_loop: return 0; } - if (percent_missing(s) > avctx->discard_damaged_percentage) - return AVERROR_INVALIDDATA; + if (percent_missing(s) > avctx->discard_damaged_percentage) { + ret = AVERROR_INVALIDDATA; + goto fail; + } if (s->bits_per_pixel <= 4) handle_small_bpp(s, p); @@ -1464,15 +1491,29 @@ static void clear_frame_metadata(PNGDecContext *s) s->stereo_mode = -1; s->have_chrm = 0; + s->have_srgb = 0; + s->have_cicp = 0; av_dict_free(&s->frame_metadata); } static int output_frame(PNGDecContext *s, AVFrame *f) { + AVCodecContext *avctx = s->avctx; int ret; - if (s->iccp_data) { + if (s->have_cicp) { + if (s->cicp_primaries >= AVCOL_PRI_NB) + av_log(avctx, AV_LOG_WARNING, "unrecognized cICP primaries\n"); + else + avctx->color_primaries = f->color_primaries = s->cicp_primaries; + if (s->cicp_trc >= AVCOL_TRC_NB) + av_log(avctx, AV_LOG_WARNING, "unrecognized cICP transfer\n"); + else + avctx->color_trc = f->color_trc = s->cicp_trc; + avctx->color_range = f->color_range = + s->cicp_range == 0 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + } else if (s->iccp_data) { AVFrameSideData *sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, s->iccp_data_len); if (!sd) { ret = AVERROR(ENOMEM); @@ -1481,8 +1522,33 @@ static int output_frame(PNGDecContext *s, AVFrame *f) memcpy(sd->data, s->iccp_data, s->iccp_data_len); av_dict_set(&sd->metadata, "name", s->iccp_name, 0); + } else if (s->have_srgb) { + avctx->color_primaries = f->color_primaries = AVCOL_PRI_BT709; + avctx->color_trc = f->color_trc = AVCOL_TRC_IEC61966_2_1; + } else if (s->have_chrm) { + AVColorPrimariesDesc desc; + enum AVColorPrimaries prim; + desc.wp.x = av_make_q(s->white_point[0], 100000); + desc.wp.y = av_make_q(s->white_point[1], 100000); + desc.prim.r.x = av_make_q(s->display_primaries[0][0], 100000); + desc.prim.r.y = av_make_q(s->display_primaries[0][1], 100000); + desc.prim.g.x = av_make_q(s->display_primaries[1][0], 100000); + desc.prim.g.y = av_make_q(s->display_primaries[1][1], 100000); + desc.prim.b.x = av_make_q(s->display_primaries[2][0], 100000); + desc.prim.b.y = av_make_q(s->display_primaries[2][1], 100000); + prim = av_csp_primaries_id_from_desc(&desc); + if (prim != AVCOL_PRI_UNSPECIFIED) + avctx->color_primaries = f->color_primaries = prim; + else + av_log(avctx, AV_LOG_WARNING, "unknown cHRM primaries\n"); } + /* these chunks override gAMA */ + if (s->iccp_data || s->have_srgb || s->have_cicp) + av_dict_set(&s->frame_metadata, "gamma", NULL, 0); + + avctx->colorspace = f->colorspace = AVCOL_SPC_RGB; + if (s->stereo_mode >= 0) { AVStereo3D *stereo3d = av_stereo3d_create_side_data(f); if (!stereo3d) { @@ -1494,25 +1560,6 @@ static int output_frame(PNGDecContext *s, AVFrame *f) stereo3d->flags = s->stereo_mode ? 0 : AV_STEREO3D_FLAG_INVERT; } - if (s->have_chrm) { - AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(f); - if (!mdm) { - ret = AVERROR(ENOMEM); - goto fail; - } - - mdm->white_point[0] = av_make_q(s->white_point[0], 100000); - mdm->white_point[1] = av_make_q(s->white_point[1], 100000); - - /* RGB Primaries */ - for (int i = 0; i < 3; i++) { - mdm->display_primaries[i][0] = av_make_q(s->display_primaries[i][0], 100000); - mdm->display_primaries[i][1] = av_make_q(s->display_primaries[i][1], 100000); - } - - mdm->has_primaries = 1; - } - FFSWAP(AVDictionary*, f->metadata, s->frame_metadata); return 0; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pngenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pngenc.c index ca1a186c..2393161c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pngenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pngenc.c @@ -29,10 +29,12 @@ #include "zlib_wrapper.h" #include "libavutil/avassert.h" +#include "libavutil/color_utils.h" #include "libavutil/crc.h" +#include "libavutil/csp.h" #include "libavutil/libm.h" #include "libavutil/opt.h" -#include "libavutil/color_utils.h" +#include "libavutil/rational.h" #include "libavutil/stereo3d.h" #include @@ -294,45 +296,22 @@ static int png_write_row(AVCodecContext *avctx, const uint8_t *data, int size) } #define AV_WB32_PNG(buf, n) AV_WB32(buf, lrint((n) * 100000)) +#define AV_WB32_PNG_D(buf, d) AV_WB32_PNG(buf, av_q2d(d)) static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf) { - double rx, ry, gx, gy, bx, by, wx = 0.3127, wy = 0.3290; - switch (prim) { - case AVCOL_PRI_BT709: - rx = 0.640; ry = 0.330; - gx = 0.300; gy = 0.600; - bx = 0.150; by = 0.060; - break; - case AVCOL_PRI_BT470M: - rx = 0.670; ry = 0.330; - gx = 0.210; gy = 0.710; - bx = 0.140; by = 0.080; - wx = 0.310; wy = 0.316; - break; - case AVCOL_PRI_BT470BG: - rx = 0.640; ry = 0.330; - gx = 0.290; gy = 0.600; - bx = 0.150; by = 0.060; - break; - case AVCOL_PRI_SMPTE170M: - case AVCOL_PRI_SMPTE240M: - rx = 0.630; ry = 0.340; - gx = 0.310; gy = 0.595; - bx = 0.155; by = 0.070; - break; - case AVCOL_PRI_BT2020: - rx = 0.708; ry = 0.292; - gx = 0.170; gy = 0.797; - bx = 0.131; by = 0.046; - break; - default: - return 0; - } + const AVColorPrimariesDesc *desc = av_csp_primaries_desc_from_id(prim); + if (!desc) + return 0; + + AV_WB32_PNG_D(buf, desc->wp.x); + AV_WB32_PNG_D(buf + 4, desc->wp.y); + AV_WB32_PNG_D(buf + 8, desc->prim.r.x); + AV_WB32_PNG_D(buf + 12, desc->prim.r.y); + AV_WB32_PNG_D(buf + 16, desc->prim.g.x); + AV_WB32_PNG_D(buf + 20, desc->prim.g.y); + AV_WB32_PNG_D(buf + 24, desc->prim.b.x); + AV_WB32_PNG_D(buf + 28, desc->prim.b.y); - AV_WB32_PNG(buf , wx); AV_WB32_PNG(buf + 4 , wy); - AV_WB32_PNG(buf + 8 , rx); AV_WB32_PNG(buf + 12, ry); - AV_WB32_PNG(buf + 16, gx); AV_WB32_PNG(buf + 20, gy); - AV_WB32_PNG(buf + 24, bx); AV_WB32_PNG(buf + 28, by); return 1; } @@ -438,6 +417,14 @@ static int encode_headers(AVCodecContext *avctx, const AVFrame *pict) pict->color_trc == AVCOL_TRC_IEC61966_2_1) { s->buf[0] = 1; /* rendering intent, relative colorimetric by default */ png_write_chunk(&s->bytestream, MKTAG('s', 'R', 'G', 'B'), s->buf, 1); + } else if (pict->color_primaries != AVCOL_PRI_UNSPECIFIED || + pict->color_trc != AVCOL_TRC_UNSPECIFIED) { + /* these values match H.273 so no translation is needed */ + s->buf[0] = pict->color_primaries; + s->buf[1] = pict->color_trc; + s->buf[2] = 0; /* colorspace = RGB */ + s->buf[3] = pict->color_range == AVCOL_RANGE_MPEG ? 0 : 1; + png_write_chunk(&s->bytestream, MKTAG('c', 'I', 'C', 'P'), s->buf, 4); } if (png_get_chrm(pict->color_primaries, s->buf)) @@ -976,7 +963,12 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, return ret; memcpy(pkt->data, s->last_frame_packet, s->last_frame_packet_size); - pkt->pts = pkt->dts = s->last_frame->pts; + pkt->pts = s->last_frame->pts; + pkt->duration = s->last_frame->duration; + + ret = ff_encode_reordered_opaque(avctx, pkt, s->last_frame); + if (ret < 0) + return ret; } if (pict) { @@ -1196,7 +1188,8 @@ const FFCodec ff_png_encoder = { CODEC_LONG_NAME("PNG (Portable Network Graphics) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PNG, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PNGEncContext), .init = png_enc_init, .close = png_enc_close, @@ -1218,7 +1211,8 @@ const FFCodec ff_apng_encoder = { CODEC_LONG_NAME("APNG (Animated Portable Network Graphics) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_APNG, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PNGEncContext), .init = png_enc_init, .close = png_enc_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pnmdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/pnmdec.c index e95b4072..978e4c03 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pnmdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pnmdec.c @@ -346,6 +346,13 @@ static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p, } } } + /* PFM is encoded from bottom to top */ + p->data[0] += (avctx->height - 1) * p->linesize[0]; + p->data[1] += (avctx->height - 1) * p->linesize[1]; + p->data[2] += (avctx->height - 1) * p->linesize[2]; + p->linesize[0] = -p->linesize[0]; + p->linesize[1] = -p->linesize[1]; + p->linesize[2] = -p->linesize[2]; break; case AV_PIX_FMT_GRAYF32: if (!s->half) { @@ -395,6 +402,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p, } } } + /* PFM is encoded from bottom to top */ + p->data[0] += (avctx->height - 1) * p->linesize[0]; + p->linesize[0] = -p->linesize[0]; break; } *got_frame = 1; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pnmenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/pnmenc.c index 9eb66330..9e1b1138 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pnmenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pnmenc.c @@ -42,7 +42,10 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); - if ((ret = ff_get_encode_buffer(avctx, pkt, size + 200, 0)) < 0) + if (size < 0) + return size; + + if ((ret = ff_get_encode_buffer(avctx, pkt, size + 200U, 0)) < 0) return ret; bytestream_start = @@ -133,9 +136,10 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((avctx->pix_fmt == AV_PIX_FMT_GBRPF32LE || avctx->pix_fmt == AV_PIX_FMT_GBRPF32BE) && c == 'F') { - const float *r = (const float *)p->data[2]; - const float *g = (const float *)p->data[0]; - const float *b = (const float *)p->data[1]; + /* PFM is encoded from bottom to top */ + const float *r = (const float *)(p->data[2] + p->linesize[2] * (avctx->height - 1)); + const float *g = (const float *)(p->data[0] + p->linesize[0] * (avctx->height - 1)); + const float *b = (const float *)(p->data[1] + p->linesize[1] * (avctx->height - 1)); for (int i = 0; i < avctx->height; i++) { for (int j = 0; j < avctx->width; j++) { @@ -145,13 +149,14 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream += 12; } - r += p->linesize[2] / 4; - g += p->linesize[0] / 4; - b += p->linesize[1] / 4; + r -= p->linesize[2] / 4; + g -= p->linesize[0] / 4; + b -= p->linesize[1] / 4; } } else if ((avctx->pix_fmt == AV_PIX_FMT_GRAYF32LE || avctx->pix_fmt == AV_PIX_FMT_GRAYF32BE) && c == 'f') { - const float *g = (const float *)p->data[0]; + /* PFM is encoded from bottom to top */ + const float *g = (const float *)(p->data[0] + p->linesize[0] * (avctx->height - 1)); for (int i = 0; i < avctx->height; i++) { for (int j = 0; j < avctx->width; j++) { @@ -159,7 +164,7 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream += 4; } - g += p->linesize[0] / 4; + g -= p->linesize[0] / 4; } } else if (avctx->pix_fmt == AV_PIX_FMT_GBRPF32 && c == 'H') { const float *r = (const float *)p->data[2]; @@ -224,7 +229,7 @@ const FFCodec ff_pgm_encoder = { CODEC_LONG_NAME("PGM (Portable GrayMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PGM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pnm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE @@ -238,7 +243,7 @@ const FFCodec ff_pgmyuv_encoder = { CODEC_LONG_NAME("PGMYUV (Portable GrayMap YUV) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PGMYUV, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pnm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE @@ -252,7 +257,7 @@ const FFCodec ff_ppm_encoder = { CODEC_LONG_NAME("PPM (Portable PixelMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PPM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pnm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE @@ -266,7 +271,7 @@ const FFCodec ff_pbm_encoder = { CODEC_LONG_NAME("PBM (Portable BitMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PBM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pnm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, @@ -279,7 +284,7 @@ const FFCodec ff_pfm_encoder = { CODEC_LONG_NAME("PFM (Portable FloatMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PFM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(pnm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GBRPF32LE, AV_PIX_FMT_GRAYF32LE, @@ -304,7 +309,7 @@ const FFCodec ff_phm_encoder = { CODEC_LONG_NAME("PHM (Portable HalfFloatMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PHM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PHMEncContext), .init = phm_enc_init, FF_CODEC_ENCODE_CB(pnm_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/proresdec2.c b/arm/raspi/third_party/ffmpeg/libavcodec/proresdec2.c index b0d7f8d5..c821a078 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/proresdec2.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/proresdec2.c @@ -289,10 +289,10 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, avctx->pix_fmt = ret; } - avctx->color_primaries = buf[14]; - avctx->color_trc = buf[15]; - avctx->colorspace = buf[16]; - avctx->color_range = AVCOL_RANGE_MPEG; + ctx->frame->color_primaries = buf[14]; + ctx->frame->color_trc = buf[15]; + ctx->frame->colorspace = buf[16]; + ctx->frame->color_range = AVCOL_RANGE_MPEG; ptr = buf + 20; flags = buf[19]; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_anatoliy.c b/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_anatoliy.c index bd1b70cc..09196c7a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_anatoliy.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_anatoliy.c @@ -944,7 +944,8 @@ const FFCodec ff_prores_aw_encoder = { CODEC_LONG_NAME("Apple ProRes"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PRORES, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = pix_fmts, .priv_data_size = sizeof(ProresContext), .init = prores_encode_init, @@ -960,7 +961,8 @@ const FFCodec ff_prores_encoder = { CODEC_LONG_NAME("Apple ProRes"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_PRORES, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = pix_fmts, .priv_data_size = sizeof(ProresContext), .init = prores_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_kostya.c b/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_kostya.c index 5b38437d..1940e037 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_kostya.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/proresenc_kostya.c @@ -1428,7 +1428,8 @@ const FFCodec ff_prores_ks_encoder = { .init = encode_init, .close = encode_close, FF_CODEC_ENCODE_CB(encode_frame), - .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/pthread_frame.c b/arm/raspi/third_party/ffmpeg/libavcodec/pthread_frame.c index df82a412..62a0b18a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/pthread_frame.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/pthread_frame.c @@ -371,6 +371,8 @@ FF_ENABLE_DEPRECATION_WARNINGS */ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) { + int err; + dst->flags = src->flags; dst->draw_horiz_band= src->draw_horiz_band; @@ -406,6 +408,12 @@ FF_ENABLE_DEPRECATION_WARNINGS src->slice_count * sizeof(*dst->slice_offset)); } dst->slice_count = src->slice_count; + + av_packet_unref(dst->internal->last_pkt_props); + err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props); + if (err < 0) + return err; + return 0; } @@ -775,6 +783,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&ctx->slice_offset); av_buffer_unref(&ctx->internal->pool); + av_packet_free(&ctx->internal->last_pkt_props); av_freep(&ctx->internal); av_buffer_unref(&ctx->hw_frames_ctx); } @@ -848,11 +857,14 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, if (!(p->frame = av_frame_alloc()) || !(p->avpkt = av_packet_alloc())) return AVERROR(ENOMEM); - copy->internal->last_pkt_props = p->avpkt; if (!first) copy->internal->is_copy = 1; + copy->internal->last_pkt_props = av_packet_alloc(); + if (!copy->internal->last_pkt_props) + return AVERROR(ENOMEM); + if (codec->init) { err = codec->init(copy); if (err < 0) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/put_bits.h b/arm/raspi/third_party/ffmpeg/libavcodec/put_bits.h index 4b4f977a..4561dc13 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/put_bits.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/put_bits.h @@ -363,6 +363,13 @@ static inline void put_bits64(PutBitContext *s, int n, uint64_t value) } } +static inline void put_sbits63(PutBitContext *pb, int n, int64_t value) +{ + av_assert2(n >= 0 && n < 64); + + put_bits64(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); +} + /** * Return the pointer to the byte where the bitstream writer will put * the next bit. diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/put_golomb.h b/arm/raspi/third_party/ffmpeg/libavcodec/put_golomb.h index 9ca911fc..df47fd2c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/put_golomb.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/put_golomb.h @@ -151,18 +151,4 @@ static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, set_ur_golomb(pb, v, k, limit, esc_len); } -/** - * write signed golomb rice code (flac). - */ -static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, - int limit, int esc_len) -{ - int v; - - v = -2 * i - 1; - v ^= (v >> 31); - - set_ur_golomb_jpegls(pb, v, k, limit, esc_len); -} - #endif /* AVCODEC_PUT_GOLOMB_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qoienc.c b/arm/raspi/third_party/ffmpeg/libavcodec/qoienc.c index 6d574e0d..b9efdc2f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qoienc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qoienc.c @@ -131,7 +131,8 @@ const FFCodec ff_qoi_encoder = { CODEC_LONG_NAME("QOI (Quite OK Image format) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_QOI, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(qoi_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsv_internal.h b/arm/raspi/third_party/ffmpeg/libavcodec/qsv_internal.h index f6e739a6..5119ef4d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsv_internal.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsv_internal.h @@ -85,6 +85,12 @@ typedef struct QSVFrame { #if QSV_VERSION_ATLEAST(1, 34) mfxExtAV1FilmGrainParam av1_film_grain_param; #endif + +#if QSV_VERSION_ATLEAST(1, 35) + mfxExtMasteringDisplayColourVolume mdcv; + mfxExtContentLightLevelInfo clli; +#endif + mfxExtBuffer *ext_param[QSV_MAX_FRAME_EXT_PARAMS]; int num_ext_params; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvdec.c index 73405b57..6bc85116 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvdec.c @@ -41,6 +41,7 @@ #include "libavutil/time.h" #include "libavutil/imgutils.h" #include "libavutil/film_grain_params.h" +#include "libavutil/mastering_display_metadata.h" #include "avcodec.h" #include "codec_internal.h" @@ -127,7 +128,9 @@ static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, { int ret = 0; - ff_decode_frame_props(avctx, frame); + ret = ff_decode_frame_props(avctx, frame); + if (ret < 0) + return ret; frame->width = avctx->width; frame->height = avctx->height; @@ -492,6 +495,22 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) } #endif +#if QSV_VERSION_ATLEAST(1, 35) + if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == AV_CODEC_ID_HEVC) { + frame->mdcv.Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME; + frame->mdcv.Header.BufferSz = sizeof(frame->mdcv); + // The data in mdcv is valid when this flag is 1 + frame->mdcv.InsertPayloadToggle = 0; + ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->mdcv); + + frame->clli.Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO; + frame->clli.Header.BufferSz = sizeof(frame->clli); + // The data in clli is valid when this flag is 1 + frame->clli.InsertPayloadToggle = 0; + ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->clli); + } +#endif + frame->used = 1; return 0; @@ -628,6 +647,53 @@ static int qsv_export_film_grain(AVCodecContext *avctx, mfxExtAV1FilmGrainParam } #endif +#if QSV_VERSION_ATLEAST(1, 35) +static int qsv_export_hdr_side_data(AVCodecContext *avctx, mfxExtMasteringDisplayColourVolume *mdcv, + mfxExtContentLightLevelInfo *clli, AVFrame *frame) +{ + // The SDK re-uses this flag for HDR SEI parsing + if (mdcv->InsertPayloadToggle) { + AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame); + const int mapping[3] = {2, 0, 1}; + const int chroma_den = 50000; + const int luma_den = 10000; + int i; + + if (!mastering) + return AVERROR(ENOMEM); + + for (i = 0; i < 3; i++) { + const int j = mapping[i]; + mastering->display_primaries[i][0] = av_make_q(mdcv->DisplayPrimariesX[j], chroma_den); + mastering->display_primaries[i][1] = av_make_q(mdcv->DisplayPrimariesY[j], chroma_den); + } + + mastering->white_point[0] = av_make_q(mdcv->WhitePointX, chroma_den); + mastering->white_point[1] = av_make_q(mdcv->WhitePointY, chroma_den); + + mastering->max_luminance = av_make_q(mdcv->MaxDisplayMasteringLuminance, luma_den); + mastering->min_luminance = av_make_q(mdcv->MinDisplayMasteringLuminance, luma_den); + + mastering->has_luminance = 1; + mastering->has_primaries = 1; + } + + // The SDK re-uses this flag for HDR SEI parsing + if (clli->InsertPayloadToggle) { + AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame); + + if (!light) + return AVERROR(ENOMEM); + + light->MaxCLL = clli->MaxContentLightLevel; + light->MaxFALL = clli->MaxPicAverageLightLevel; + } + + return 0; +} + +#endif + static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *avpkt) @@ -749,6 +815,15 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, } #endif +#if QSV_VERSION_ATLEAST(1, 35) + if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == AV_CODEC_ID_HEVC) { + ret = qsv_export_hdr_side_data(avctx, &aframe.frame->mdcv, &aframe.frame->clli, frame); + + if (ret < 0) + return ret; + } +#endif + frame->repeat_pict = outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 : outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 : diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.c index d5e9f2d4..2f0e94a9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.c @@ -169,6 +169,8 @@ do { \ } \ } while (0) \ +#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) + static const char *print_ratecontrol(mfxU16 rc_mode) { int i; @@ -197,6 +199,10 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q, mfxExtCodingOption2 *co2 = NULL; mfxExtCodingOption3 *co3 = NULL; mfxExtHEVCTiles *exthevctiles = NULL; +#if QSV_HAVE_HE + mfxExtHyperModeParam *exthypermodeparam = NULL; +#endif + const char *tmp_str = NULL; if (q->co2_idx > 0) @@ -208,6 +214,11 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q, if (q->exthevctiles_idx > 0) exthevctiles = (mfxExtHEVCTiles *)coding_opts[q->exthevctiles_idx]; +#if QSV_HAVE_HE + if (q->exthypermodeparam_idx > 0) + exthypermodeparam = (mfxExtHyperModeParam *)coding_opts[q->exthypermodeparam_idx]; +#endif + av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n", print_profile(avctx->codec_id, info->CodecProfile), info->CodecLevel); @@ -373,6 +384,21 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q, av_log(avctx, AV_LOG_VERBOSE, "NumTileColumns: %"PRIu16"; NumTileRows: %"PRIu16"\n", exthevctiles->NumTileColumns, exthevctiles->NumTileRows); } + +#if QSV_HAVE_HE + if (exthypermodeparam) { + av_log(avctx, AV_LOG_VERBOSE, "HyperEncode: "); + + if (exthypermodeparam->Mode == MFX_HYPERMODE_OFF) + av_log(avctx, AV_LOG_VERBOSE, "OFF"); + if (exthypermodeparam->Mode == MFX_HYPERMODE_ON) + av_log(avctx, AV_LOG_VERBOSE, "ON"); + if (exthypermodeparam->Mode == MFX_HYPERMODE_ADAPTIVE) + av_log(avctx, AV_LOG_VERBOSE, "Adaptive"); + + av_log(avctx, AV_LOG_VERBOSE, "\n"); + } +#endif } static void dump_video_vp9_param(AVCodecContext *avctx, QSVEncContext *q, @@ -537,6 +563,8 @@ static void dump_video_av1_param(AVCodecContext *avctx, QSVEncContext *q, av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n", print_threestate(av1_bs_param->WriteIVFHeaders)); + av_log(avctx, AV_LOG_VERBOSE, "LowDelayBRC: %s\n", print_threestate(co3->LowDelayBRC)); + av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d;\n", co2->MaxFrameSize); } #endif @@ -644,6 +672,12 @@ static int check_enc_param(AVCodecContext *avctx, QSVEncContext *q) return 1; } +static int is_strict_gop(QSVEncContext *q) { + if (q->adaptive_b == 0 && q->adaptive_i == 0) + return 1; + return 0; +} + static int init_video_param_jpeg(AVCodecContext *avctx, QSVEncContext *q) { enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? @@ -755,7 +789,8 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->old_gop_size = avctx->gop_size; q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1; q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? - MFX_GOP_CLOSED : MFX_GOP_STRICT; + MFX_GOP_CLOSED : is_strict_gop(q) ? + MFX_GOP_STRICT : 0; q->param.mfx.IdrInterval = q->idr_interval; q->param.mfx.NumSlice = avctx->slices; q->param.mfx.NumRefFrame = FFMAX(0, avctx->refs); @@ -1026,6 +1061,8 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->adaptive_b >= 0) q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; + if (q->max_frame_size >= 0) + q->extco2.MaxFrameSize = q->max_frame_size; q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; q->extco2.Header.BufferSz = sizeof(q->extco2); @@ -1083,6 +1120,9 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->extco3.MaxFrameSizeP = q->max_frame_size_p; q->extco3.ScenarioInfo = q->scenario; + } else if (avctx->codec_id == AV_CODEC_ID_AV1) { + if (q->low_delay_brc >= 0) + q->extco3.LowDelayBRC = q->low_delay_brc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; } if (avctx->codec_id == AV_CODEC_ID_HEVC) { @@ -1154,6 +1194,54 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extvsi; } +#if QSV_HAVE_HE + if (q->dual_gfx) { + if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 4)) { + mfxIMPL impl; + MFXQueryIMPL(q->session, &impl); + + if (MFX_IMPL_VIA_MASK(impl) != MFX_IMPL_VIA_D3D11) { + av_log(avctx, AV_LOG_ERROR, "Dual GFX mode requires D3D11VA \n"); + return AVERROR_UNKNOWN; + } + if (q->param.mfx.LowPower != MFX_CODINGOPTION_ON) { + av_log(avctx, AV_LOG_ERROR, "Dual GFX mode supports only low-power encoding mode \n"); + return AVERROR_UNKNOWN; + } + if (q->param.mfx.CodecId != MFX_CODEC_AVC && q->param.mfx.CodecId != MFX_CODEC_HEVC) { + av_log(avctx, AV_LOG_ERROR, "Not supported encoder for dual GFX mode. " + "Supported: h264_qsv and hevc_qsv \n"); + return AVERROR_UNKNOWN; + } + if (q->param.mfx.RateControlMethod != MFX_RATECONTROL_VBR && + q->param.mfx.RateControlMethod != MFX_RATECONTROL_CQP && + q->param.mfx.RateControlMethod != MFX_RATECONTROL_ICQ) { + av_log(avctx, AV_LOG_WARNING, "Not supported BRC for dual GFX mode. " + "Supported: VBR, CQP and ICQ \n"); + } + if ((q->param.mfx.CodecId == MFX_CODEC_AVC && q->param.mfx.IdrInterval != 0) || + (q->param.mfx.CodecId == MFX_CODEC_HEVC && q->param.mfx.IdrInterval != 1)) { + av_log(avctx, AV_LOG_WARNING, "Dual GFX mode requires closed GOP for AVC and strict GOP for HEVC, -idr_interval 0 \n"); + } + if (q->param.mfx.GopPicSize < 30) { + av_log(avctx, AV_LOG_WARNING, "For better performance in dual GFX mode GopPicSize must be >= 30 \n"); + } + if (q->param.AsyncDepth < 30) { + av_log(avctx, AV_LOG_WARNING, "For better performance in dual GFX mode AsyncDepth must be >= 30 \n"); + } + + q->exthypermodeparam.Header.BufferId = MFX_EXTBUFF_HYPER_MODE_PARAM; + q->exthypermodeparam.Header.BufferSz = sizeof(q->exthypermodeparam); + q->exthypermodeparam.Mode = q->dual_gfx; + q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->exthypermodeparam; + } else { + av_log(avctx, AV_LOG_ERROR, + "This version of runtime doesn't support Hyper Encode\n"); + return AVERROR_UNKNOWN; + } + } +#endif + if (!check_enc_param(avctx,q)) { av_log(avctx, AV_LOG_ERROR, "some encoding parameters are not supported by the QSV " @@ -1328,12 +1416,19 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) .Header.BufferSz = sizeof(hevc_tile_buf), }; - mfxExtBuffer *ext_buffers[6]; +#if QSV_HAVE_HE + mfxExtHyperModeParam hyper_mode_param_buf = { + .Header.BufferId = MFX_EXTBUFF_HYPER_MODE_PARAM, + .Header.BufferSz = sizeof(hyper_mode_param_buf), + }; +#endif + + mfxExtBuffer *ext_buffers[6 + QSV_HAVE_HE]; int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO; int ret, ext_buf_num = 0, extradata_offset = 0; - q->co2_idx = q->co3_idx = q->exthevctiles_idx = -1; + q->co2_idx = q->co3_idx = q->exthevctiles_idx = q->exthypermodeparam_idx = -1; ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&extradata; ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co; @@ -1355,6 +1450,12 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) q->exthevctiles_idx = ext_buf_num; ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&hevc_tile_buf; } +#if QSV_HAVE_HE + if (q->dual_gfx && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 4)) { + q->exthypermodeparam_idx = ext_buf_num; + ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&hyper_mode_param_buf; + } +#endif q->param.ExtParam = ext_buffers; q->param.NumExtParam = ext_buf_num; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.h b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.h index a7bbb379..4a6fa2ca 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc.h @@ -45,10 +45,12 @@ #define QSV_HAVE_AVBR 1 #define QSV_HAVE_VCM 1 #define QSV_HAVE_MF 0 +#define QSV_HAVE_HE QSV_VERSION_ATLEAST(2, 4) #else #define QSV_HAVE_AVBR 0 #define QSV_HAVE_VCM 0 #define QSV_HAVE_MF !QSV_ONEVPL +#define QSV_HAVE_HE 0 #endif #define QSV_COMMON_OPTS \ @@ -64,6 +66,14 @@ { "forced_idr", "Forcing I frames as IDR frames", OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE }, \ { "low_power", "enable low power mode(experimental: many limitations by mfx version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, VE}, +#if QSV_HAVE_HE +#define QSV_HE_OPTIONS \ +{ "dual_gfx", "Prefer processing on both iGfx and dGfx simultaneously", OFFSET(qsv.dual_gfx), AV_OPT_TYPE_INT, { .i64 = MFX_HYPERMODE_OFF }, MFX_HYPERMODE_OFF, MFX_HYPERMODE_ADAPTIVE, VE, "dual_gfx" }, \ +{ "off", "Disable HyperEncode mode", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_OFF }, INT_MIN, INT_MAX, VE, "dual_gfx" }, \ +{ "on", "Enable HyperEncode mode and return error if incompatible parameters during initialization", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_ON }, INT_MIN, INT_MAX, VE, "dual_gfx" }, \ +{ "adaptive", "Enable HyperEncode mode or fallback to single GPU if incompatible parameters during initialization", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_HYPERMODE_ADAPTIVE }, INT_MIN, INT_MAX, VE, "dual_gfx" }, +#endif + #define QSV_OPTION_RDO \ { "rdo", "Enable rate distortion optimization", OFFSET(qsv.rdo), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, @@ -171,7 +181,9 @@ typedef struct QSVEncContext { mfxExtAV1TileParam extav1tileparam; mfxExtAV1BitstreamParam extav1bsparam; #endif - +#if QSV_HAVE_HE + mfxExtHyperModeParam exthypermodeparam; +#endif #if QSV_HAVE_OPAQUE mfxExtOpaqueSurfaceAlloc opaque_alloc; mfxFrameSurface1 **opaque_surfaces; @@ -180,7 +192,7 @@ typedef struct QSVEncContext { mfxExtVideoSignalInfo extvsi; - mfxExtBuffer *extparam_internal[5 + (QSV_HAVE_MF * 2) + QSV_HAVE_EXT_AV1_PARAM * 2]; + mfxExtBuffer *extparam_internal[5 + (QSV_HAVE_MF * 2) + (QSV_HAVE_EXT_AV1_PARAM * 2) + QSV_HAVE_HE]; int nb_extparam_internal; mfxExtBuffer **extparam; @@ -255,6 +267,7 @@ typedef struct QSVEncContext { int co2_idx; int co3_idx; int exthevctiles_idx; + int exthypermodeparam_idx; int vp9_idx; int max_qp_i; @@ -299,6 +312,8 @@ typedef struct QSVEncContext { // This is used for SEI Timing reset int old_pic_timing_sei; int skip_frame; + // This is used for Hyper Encode + int dual_gfx; } QSVEncContext; int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_av1.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_av1.c index bb9ad169..c697845d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_av1.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_av1.c @@ -110,6 +110,8 @@ static const AVOption options[] = { QSV_OPTION_ADAPTIVE_I QSV_OPTION_ADAPTIVE_B QSV_OPTION_EXTBRC + QSV_OPTION_LOW_DELAY_BRC + QSV_OPTION_MAX_FRAME_SIZE { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" }, { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" }, { "main" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AV1_MAIN }, INT_MIN, INT_MAX, VE, "profile" }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_h264.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_h264.c index 0ff73563..071a9a79 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_h264.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_h264.c @@ -117,6 +117,9 @@ static const AVOption options[] = { QSV_OPTION_SCENARIO QSV_OPTION_AVBR QSV_OPTION_SKIP_FRAME +#if QSV_HAVE_HE + QSV_HE_OPTIONS +#endif { "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, #if QSV_HAVE_VCM @@ -197,7 +200,6 @@ const FFCodec ff_h264_qsv_encoder = { .close = qsv_enc_close, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, - AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, .p.priv_class = &class, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_hevc.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_hevc.c index e042263b..5e23ca96 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_hevc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_hevc.c @@ -318,6 +318,9 @@ static const AVOption options[] = { QSV_OPTION_SCENARIO QSV_OPTION_AVBR QSV_OPTION_SKIP_FRAME +#if QSV_HAVE_HE + QSV_HE_OPTIONS +#endif { "idr_interval", "Distance (in I-frames) between IDR frames", OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, VE, "idr_interval" }, { "begin_only", "Output an IDR-frame only at the beginning of the stream", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "idr_interval" }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_jpeg.c b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_jpeg.c index 2469ef7c..2add12ad 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_jpeg.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qsvenc_jpeg.c @@ -89,6 +89,8 @@ const FFCodec ff_mjpeg_qsv_encoder = { .close = qsv_enc_close, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, + AV_PIX_FMT_YUYV422, + AV_PIX_FMT_BGRA, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, .p.priv_class = &class, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/qtrleenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/qtrleenc.c index 855494d3..3d51fcf8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/qtrleenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/qtrleenc.c @@ -404,7 +404,7 @@ const FFCodec ff_qtrle_encoder = { CODEC_LONG_NAME("QuickTime Animation (RLE) video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_QTRLE, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(QtrleEncContext), .init = qtrle_encode_init, FF_CODEC_ENCODE_CB(qtrle_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/r210enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/r210enc.c index d87f42ce..91e34528 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/r210enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/r210enc.c @@ -96,7 +96,7 @@ const FFCodec ff_r210_encoder = { CODEC_LONG_NAME("Uncompressed RGB 10-bit"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_R210, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = pix_fmt, @@ -108,7 +108,7 @@ const FFCodec ff_r10k_encoder = { CODEC_LONG_NAME("AJA Kona 10-bit RGB Codec"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_R10K, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = pix_fmt, @@ -120,7 +120,7 @@ const FFCodec ff_avrp_encoder = { CODEC_LONG_NAME("Avid 1:1 10-bit RGB Packer"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_AVRP, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), .p.pix_fmts = pix_fmt, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ratecontrol.h b/arm/raspi/third_party/ffmpeg/libavcodec/ratecontrol.h index 2a7aaec6..4de80fad 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ratecontrol.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ratecontrol.h @@ -80,9 +80,6 @@ typedef struct RateControlContext{ int frame_count[5]; int last_non_b_pict_type; - void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid) - float dry_run_qscale; ///< for xvid rc - int last_picture_number; ///< for xvid rc AVExpr * rc_eq_eval; }RateControlContext; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rawdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/rawdec.c index 72cdd139..c20c317f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rawdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rawdec.c @@ -233,9 +233,6 @@ static int raw_decode(AVCodecContext *avctx, AVFrame *frame, if (res < 0) return res; - frame->pkt_pos = avctx->internal->last_pkt_props->pos; - frame->duration = avctx->internal->last_pkt_props->duration; - if (context->tff >= 0) { frame->interlaced_frame = 1; frame->top_field_first = context->tff; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rawenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/rawenc.c index c2643e6d..8c577006 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rawenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rawenc.c @@ -86,7 +86,8 @@ const FFCodec ff_rawvideo_encoder = { CODEC_LONG_NAME("raw video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_RAWVIDEO, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = raw_encode_init, FF_CODEC_ENCODE_CB(raw_encode), }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/roqvideoenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/roqvideoenc.c index 273686a1..c25aa39b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/roqvideoenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/roqvideoenc.c @@ -1122,7 +1122,7 @@ const FFCodec ff_roq_encoder = { CODEC_LONG_NAME("id RoQ video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ROQ, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(RoqEncContext), .init = roq_encode_init, FF_CODEC_ENCODE_CB(roq_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rpzaenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/rpzaenc.c index 1ea579d2..da9500e4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rpzaenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rpzaenc.c @@ -873,7 +873,7 @@ const FFCodec ff_rpza_encoder = { CODEC_LONG_NAME("QuickTime video (RPZA)"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_RPZA, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(RpzaContext), .p.priv_class = &rpza_class, .init = rpza_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.c index d0704c5a..8a405b86 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.c @@ -31,7 +31,7 @@ #include "put_bits.h" #include "rv10enc.h" -int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_rv10_encode_picture_header(MpegEncContext *s) { int full_frame= 0; @@ -71,6 +71,7 @@ const FFCodec ff_rv10_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_RV10, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(MpegEncContext), .init = ff_mpv_encode_init, FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.h index 66672f80..fc3665e8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rv10enc.h @@ -23,7 +23,7 @@ #include "mpegvideo.h" -int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); -void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number); +int ff_rv10_encode_picture_header(MpegEncContext *s); +void ff_rv20_encode_picture_header(MpegEncContext *s); #endif /* AVCODEC_RV10ENC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/rv20enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/rv20enc.c index a6bacacb..dc26877d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/rv20enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/rv20enc.c @@ -34,12 +34,12 @@ #include "put_bits.h" #include "rv10enc.h" -void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number){ +void ff_rv20_encode_picture_header(MpegEncContext *s) { put_bits(&s->pb, 2, s->pict_type); //I 0 vs. 1 ? put_bits(&s->pb, 1, 0); /* unknown bit */ put_bits(&s->pb, 5, s->qscale); - put_sbits(&s->pb, 8, picture_number); //FIXME wrong, but correct is not known + put_sbits(&s->pb, 8, s->picture_number); //FIXME wrong, but correct is not known s->mb_x= s->mb_y= 0; ff_h263_encode_mba(s); @@ -68,6 +68,7 @@ const FFCodec ff_rv20_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_RV20, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(MpegEncContext), .init = ff_mpv_encode_init, FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/s302menc.c b/arm/raspi/third_party/ffmpeg/libavcodec/s302menc.c index 3bd657f9..4b8996f9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/s302menc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/s302menc.c @@ -176,7 +176,8 @@ const FFCodec ff_s302m_encoder = { .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_S302M, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | - AV_CODEC_CAP_VARIABLE_FRAME_SIZE, + AV_CODEC_CAP_VARIABLE_FRAME_SIZE | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(S302MEncContext), .init = s302m_encode_init, FF_CODEC_ENCODE_CB(s302m_encode2_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sbcenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/sbcenc.c index 721c97e1..fccb0e3e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sbcenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sbcenc.c @@ -348,7 +348,8 @@ const FFCodec ff_sbc_encoder = { CODEC_LONG_NAME("SBC (low-complexity subband codec)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_SBC, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SBCEncContext), .init = sbc_encode_init, FF_CODEC_ENCODE_CB(sbc_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/scpr.c b/arm/raspi/third_party/ffmpeg/libavcodec/scpr.c index 5abe157a..7630adb3 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/scpr.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/scpr.c @@ -458,6 +458,9 @@ static int decompress_p(AVCodecContext *avctx, int run, bx = x * 16 + sx1, by = y * 16 + sy1; uint32_t r, g, b, clr, ptype = 0; + if (bx >= avctx->width) + return AVERROR_INVALIDDATA; + for (; by < y * 16 + sy2 && by < avctx->height;) { ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); if (ret < 0) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/scpr3.c b/arm/raspi/third_party/ffmpeg/libavcodec/scpr3.c index d9ea6af1..5271717a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/scpr3.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/scpr3.c @@ -1167,6 +1167,9 @@ static int decompress_p3(AVCodecContext *avctx, int run, bx = x * 16 + sx1, by = y * 16 + sy1; uint32_t clr, ptype = 0, r, g, b; + if (bx >= avctx->width) + return AVERROR_INVALIDDATA; + for (; by < y * 16 + sy2 && by < avctx->height;) { ret = decode_value3(s, 5, &s->op_model3[ptype].cntsum, s->op_model3[ptype].freqs[0], diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sei.h b/arm/raspi/third_party/ffmpeg/libavcodec/sei.h index 5513590b..f96b7b64 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sei.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sei.h @@ -26,7 +26,7 @@ // The content of the payload data depends on the standard, though // many generic parts have the same interpretation everywhere (such as // mastering-display-colour-volume and user-data-unregistered). -enum { +enum SEIType { SEI_TYPE_BUFFERING_PERIOD = 0, SEI_TYPE_PIC_TIMING = 1, SEI_TYPE_PAN_SCAN_RECT = 2, @@ -137,4 +137,21 @@ enum { SEI_TYPE_SAMPLE_ASPECT_RATIO_INFO = 204, }; +/** + * frame_packing_arrangement types. H.265 and H.274 use only 3..5 + * with all the other values being reserved. H.264 uses a few more values + * that are prefixed with SEI_FPA_H264 in the enum below. + * + * The semantics of the common values are the same for all standards. + */ +typedef enum { + SEI_FPA_H264_TYPE_CHECKERBOARD = 0, + SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN = 1, + SEI_FPA_H264_TYPE_INTERLEAVE_ROW = 2, + SEI_FPA_TYPE_SIDE_BY_SIDE = 3, + SEI_FPA_TYPE_TOP_BOTTOM = 4, + SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, + SEI_FPA_H264_TYPE_2D = 6, +} SEIFpaType; + #endif /* AVCODEC_SEI_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sgidec.c b/arm/raspi/third_party/ffmpeg/libavcodec/sgidec.c index 6ff2ee97..92083f23 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sgidec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sgidec.c @@ -159,7 +159,7 @@ static int read_uncompressed_sgi(uint8_t *const out[4], const ptrdiff_t stride[4 unsigned rowsize = width * bytes_per_channel; /* Test buffer size. */ - if (rowsize * (int64_t)height > bytestream2_get_bytes_left(g)) + if (rowsize * (int64_t)height * nb_components > bytestream2_get_bytes_left(g)) return AVERROR_INVALIDDATA; for (unsigned z = 0; z < nb_components; z++) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sgienc.c b/arm/raspi/third_party/ffmpeg/libavcodec/sgienc.c index 901e0a74..5bbb72c0 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sgienc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sgienc.c @@ -275,7 +275,7 @@ const FFCodec ff_sgi_encoder = { CODEC_LONG_NAME("SGI image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SGI, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SgiContext), .p.priv_class = &sgi_class, .init = encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/smcenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/smcenc.c index a2d224bd..3e8b5afc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/smcenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/smcenc.c @@ -57,11 +57,13 @@ typedef struct SMCContext { { \ for (int block = 0; block < nb_blocks && pixel_ptr && row_ptr; block++) { \ pixel_ptr += 4; \ + cur_x += 4; \ if (pixel_ptr - row_ptr >= width) \ { \ row_ptr += stride * 4; \ pixel_ptr = row_ptr; \ cur_y += 4; \ + cur_x = 0; \ } \ } \ } @@ -114,14 +116,13 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, PutByteContext *pb) { const uint8_t *src_pixels = (const uint8_t *)frame->data[0]; - const int stride = frame->linesize[0]; + const ptrdiff_t stride = frame->linesize[0]; const uint8_t *prev_pixels = (const uint8_t *)s->prev_frame->data[0]; - const int prev_stride = s->prev_frame->linesize[0]; + const ptrdiff_t prev_stride = s->prev_frame->linesize[0]; uint8_t *distinct_values = s->distinct_values; const uint8_t *pixel_ptr, *row_ptr; const int height = frame->height; const int width = frame->width; - uint8_t block_values[16]; int block_counter = 0; int color_pair_index = 0; int color_quad_index = 0; @@ -129,10 +130,7 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, int color_table_index; /* indexes to color pair, quad, or octet tables */ int total_blocks; int cur_y = 0; - - memset(s->color_pairs, 0, sizeof(s->color_pairs)); - memset(s->color_quads, 0, sizeof(s->color_quads)); - memset(s->color_octets, 0, sizeof(s->color_octets)); + int cur_x = 0; /* Number of 4x4 blocks in frame. */ total_blocks = ((width + 3) / 4) * ((height + 3) / 4); @@ -150,16 +148,17 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, int distinct = 0; int blocks = 0; int frame_y = cur_y; + int frame_x = cur_x; while (prev_pixels && s->key_frame == 0 && block_counter + inter_skip_blocks < total_blocks) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); int compare = 0; for (int y = 0; y < y_size; y++) { - const ptrdiff_t offset = pixel_ptr - row_ptr; - const uint8_t *prev_pixel_ptr = prev_pixels + cur_y * prev_stride + offset; + const uint8_t *prev_pixel_ptr = prev_pixels + (y + cur_y) * prev_stride + cur_x; - compare |= memcmp(prev_pixel_ptr + y * prev_stride, pixel_ptr + y * stride, 4); + compare |= !!memcmp(prev_pixel_ptr, pixel_ptr + y * stride, x_size); if (compare) break; } @@ -167,9 +166,9 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, if (compare) break; + inter_skip_blocks++; if (inter_skip_blocks >= 256) break; - inter_skip_blocks++; ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) } @@ -177,19 +176,21 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, pixel_ptr = xpixel_ptr; row_ptr = xrow_ptr; cur_y = frame_y; + cur_x = frame_x; while (block_counter > 0 && block_counter + intra_skip_blocks < total_blocks) { const int y_size = FFMIN(4, height - cur_y); - const ptrdiff_t offset = pixel_ptr - src_pixels; + const int x_size = FFMIN(4, width - cur_x); + const ptrdiff_t offset = xpixel_ptr - src_pixels; const int sy = offset / stride; const int sx = offset % stride; const int ny = sx < 4 ? sy - 4 : sy; - const int nx = sx < 4 ? width - 4 : sx - 4; + const int nx = sx < 4 ? width - 4 + (width & 3) : sx - 4; const uint8_t *old_pixel_ptr = src_pixels + nx + ny * stride; int compare = 0; for (int y = 0; y < y_size; y++) { - compare |= memcmp(old_pixel_ptr + y * stride, pixel_ptr + y * stride, 4); + compare |= !!memcmp(old_pixel_ptr + y * stride, pixel_ptr + y * stride, x_size); if (compare) break; } @@ -197,23 +198,28 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, if (compare) break; + intra_skip_blocks++; if (intra_skip_blocks >= 256) break; - intra_skip_blocks++; + ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) } pixel_ptr = xpixel_ptr; row_ptr = xrow_ptr; cur_y = frame_y; + cur_x = frame_x; while (block_counter + coded_blocks < total_blocks && coded_blocks < 256) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); + const int nb_elements = x_size * y_size; + uint8_t block_values[16] = { 0 }; for (int y = 0; y < y_size; y++) - memcpy(block_values + y * 4, pixel_ptr + y * stride, 4); + memcpy(block_values + y * x_size, pixel_ptr + y * stride, x_size); - qsort(block_values, 16, sizeof(block_values[0]), smc_cmp_values); - s->next_nb_distinct = count_distinct_items(block_values, s->next_distinct_values, 16); + qsort(block_values, nb_elements, sizeof(block_values[0]), smc_cmp_values); + s->next_nb_distinct = count_distinct_items(block_values, s->next_distinct_values, nb_elements); if (coded_blocks == 0) { memcpy(distinct_values, s->next_distinct_values, sizeof(s->distinct_values)); s->nb_distinct = s->next_nb_distinct; @@ -226,43 +232,48 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, s->mono_value = block_values[0]; coded_distinct = s->nb_distinct; - ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) coded_blocks++; if (coded_distinct > 1 && coded_blocks >= 16) break; + + ADVANCE_BLOCK(pixel_ptr, row_ptr, 1) } pixel_ptr = xpixel_ptr; row_ptr = xrow_ptr; cur_y = frame_y; + cur_x = frame_x; - blocks = coded_blocks; + blocks = coded_distinct <= 8 ? coded_blocks : 0; distinct = coded_distinct; - if (intra_skip_blocks > 0 && intra_skip_blocks >= inter_skip_blocks && - intra_skip_blocks > 0) { + if (intra_skip_blocks >= blocks && intra_skip_blocks >= inter_skip_blocks) { distinct = 17; blocks = intra_skip_blocks; } if (intra_skip_blocks > 16 && intra_skip_blocks >= inter_skip_blocks && - intra_skip_blocks > 0) { + intra_skip_blocks >= blocks) { distinct = 18; blocks = intra_skip_blocks; } - if (inter_skip_blocks > 0 && inter_skip_blocks > intra_skip_blocks && - inter_skip_blocks > 0) { + if (inter_skip_blocks >= blocks && inter_skip_blocks > intra_skip_blocks) { distinct = 19; blocks = inter_skip_blocks; } if (inter_skip_blocks > 16 && inter_skip_blocks > intra_skip_blocks && - inter_skip_blocks > 0) { + inter_skip_blocks >= blocks) { distinct = 20; blocks = inter_skip_blocks; } + if (blocks == 0) { + blocks = coded_blocks; + distinct = coded_distinct; + } + switch (distinct) { case 1: if (blocks <= 16) { @@ -304,15 +315,17 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, for (int i = 0; i < blocks; i++) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); uint8_t value = s->color_pairs[color_table_index][1]; uint16_t flags = 0; int shift = 15; for (int y = 0; y < y_size; y++) { - for (int x = 0; x < 4; x++) { + for (int x = 0; x < x_size; x++) { flags |= (value == pixel_ptr[x + y * stride]) << shift; shift--; } + shift -= 4 - x_size; } bytestream2_put_be16(pb, flags); @@ -353,6 +366,7 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, for (int i = 0; i < blocks; i++) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); uint32_t flags = 0; uint8_t quad[4]; int shift = 30; @@ -361,7 +375,7 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, quad[k] = s->color_quads[color_table_index][k]; for (int y = 0; y < y_size; y++) { - for (int x = 0; x < 4; x++) { + for (int x = 0; x < x_size; x++) { int pixel = pixel_ptr[x + y * stride]; uint32_t idx = 0; @@ -375,6 +389,8 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, flags |= idx << shift; shift -= 2; } + + shift -= 2 * (4 - x_size); } bytestream2_put_be32(pb, flags); @@ -421,6 +437,7 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, for (int i = 0; i < blocks; i++) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); uint64_t flags = 0; uint8_t octet[8]; int shift = 45; @@ -429,7 +446,7 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, octet[k] = s->color_octets[color_table_index][k]; for (int y = 0; y < y_size; y++) { - for (int x = 0; x < 4; x++) { + for (int x = 0; x < x_size; x++) { int pixel = pixel_ptr[x + y * stride]; uint64_t idx = 0; @@ -443,6 +460,8 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, flags |= idx << shift; shift -= 3; } + + shift -= 3 * (4 - x_size); } bytestream2_put_be16(pb, ((flags >> 32) & 0xFFF0) | ((flags >> 8) & 0xF)); @@ -456,9 +475,12 @@ static void smc_encode_stream(SMCContext *s, const AVFrame *frame, bytestream2_put_byte(pb, 0xE0 | (blocks - 1)); for (int i = 0; i < blocks; i++) { const int y_size = FFMIN(4, height - cur_y); + const int x_size = FFMIN(4, width - cur_x); for (int y = 0; y < y_size; y++) { - for (int x = 0; x < 4; x++) + for (int x = 0; x < x_size; x++) bytestream2_put_byte(pb, pixel_ptr[x + y * stride]); + for (int x = x_size; x < 4; x++) + bytestream2_put_byte(pb, 0); } for (int y = y_size; y < 4; y++) { @@ -573,7 +595,7 @@ const FFCodec ff_smc_encoder = { CODEC_LONG_NAME("QuickTime Graphics (SMC)"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SMC, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SMCContext), .init = smc_encode_init, FF_CODEC_ENCODE_CB(smc_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/snowenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/snowenc.c index 7fad95b6..749c8067 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/snowenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/snowenc.c @@ -1935,7 +1935,7 @@ const FFCodec ff_snow_encoder = { CODEC_LONG_NAME("Snow"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SNOW, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SnowContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sonic.c b/arm/raspi/third_party/ffmpeg/libavcodec/sonic.c index 77bdb418..62e6193a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sonic.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sonic.c @@ -1096,7 +1096,8 @@ const FFCodec ff_sonic_encoder = { CODEC_LONG_NAME("Sonic"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_SONIC, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SonicContext), .init = sonic_encode_init, FF_CODEC_ENCODE_CB(sonic_encode_frame), @@ -1112,7 +1113,8 @@ const FFCodec ff_sonic_ls_encoder = { CODEC_LONG_NAME("Sonic lossless"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_SONIC_LS, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SonicContext), .init = sonic_encode_init, FF_CODEC_ENCODE_CB(sonic_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sp5xdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/sp5xdec.c index 394448c5..dfed7255 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sp5xdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sp5xdec.c @@ -32,21 +32,23 @@ #include "mjpegdec.h" #include "sp5x.h" -int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) + +static int sp5x_decode_frame(AVCodecContext *avctx, + AVFrame *frame, int *got_frame, + AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVBufferRef *buf_recoded; uint8_t *recoded; int i = 0, j = 0; + int ret; if (!avctx->width || !avctx->height) return -1; - buf_recoded = av_buffer_allocz(buf_size + 1024); - if (!buf_recoded) + recoded = av_mallocz(buf_size + 1024); + if (!recoded) return -1; - recoded = buf_recoded->data; /* SOI */ recoded[j++] = 0xFF; @@ -83,12 +85,12 @@ int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) recoded[j++] = 0xFF; recoded[j++] = 0xD9; - av_buffer_unref(&avpkt->buf); - avpkt->buf = buf_recoded; - avpkt->data = recoded; - avpkt->size = j; + ret = ff_mjpeg_decode_frame_from_buf(avctx, frame, got_frame, + avpkt, recoded, j); - return 0; + av_free(recoded); + + return ret < 0 ? ret : avpkt->size; } #if CONFIG_SP5X_DECODER @@ -100,11 +102,10 @@ const FFCodec ff_sp5x_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_DECODE_CB(sp5x_decode_frame), .p.capabilities = AV_CODEC_CAP_DR1, .p.max_lowres = 3, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_SETS_PKT_DTS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_AMV_DECODER @@ -116,10 +117,9 @@ const FFCodec ff_amv_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), + FF_CODEC_DECODE_CB(sp5x_decode_frame), .p.max_lowres = 3, .p.capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | - FF_CODEC_CAP_SETS_PKT_DTS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/speedhqenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/speedhqenc.c index 7269e345..5b4ff4c1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/speedhqenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/speedhqenc.c @@ -288,6 +288,7 @@ const FFCodec ff_speedhq_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SPEEDHQ, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SpeedHQEncContext), .init = ff_mpv_encode_init, FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sunrast.c b/arm/raspi/third_party/ffmpeg/libavcodec/sunrast.c index 45b29e4d..3668d2be 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sunrast.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sunrast.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" @@ -75,6 +76,12 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p, return AVERROR_PATCHWELCOME; } + if (maplength > 768) { + av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); + return AVERROR_INVALIDDATA; + } + + // This also checks depth to be valid switch (depth) { case 1: avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_MONOWHITE; @@ -96,15 +103,23 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p, return AVERROR_INVALIDDATA; } + // This checks w and h to be valid in the sense that bytes of a padded bitmap are addressable with 32bit int ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; + // ensured by ff_set_dimensions() + av_assert0(w <= (INT32_MAX - 7) / depth); + /* scanlines are aligned on 16 bit boundaries */ len = (depth * w + 7) >> 3; alen = len + (len & 1); - if (buf_end - buf < maplength + (len * h) * 3 / 256) + // ensured by ff_set_dimensions() + av_assert0(h <= INT32_MAX / (3 * len)); + + // maplength is limited to 768 and the right term is limited to INT32_MAX / 256 so the add needs no check + if (buf_end - buf < (uint64_t)maplength + (len * h) * 3 / 256) return AVERROR_INVALIDDATA; if ((ret = ff_get_buffer(avctx, p, 0)) < 0) @@ -118,7 +133,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p, } else if (maplength) { unsigned int len = maplength / 3; - if (maplength % 3 || maplength > 768) { + if (maplength % 3) { av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); return AVERROR_INVALIDDATA; } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/sunrastenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/sunrastenc.c index 9b82f992..b2d57f72 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/sunrastenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/sunrastenc.c @@ -213,7 +213,7 @@ const FFCodec ff_sunrast_encoder = { CODEC_LONG_NAME("Sun Rasterfile image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SUNRAST, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SUNRASTContext), .init = sunrast_encode_init, FF_CODEC_ENCODE_CB(sunrast_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/svq1enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/svq1enc.c index 8f09e634..e3ea0c1e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/svq1enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/svq1enc.c @@ -752,7 +752,7 @@ const FFCodec ff_svq1_encoder = { CODEC_LONG_NAME("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_SVQ1, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(SVQ1EncContext), .p.priv_class = &svq1enc_class, .init = svq1_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/targaenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/targaenc.c index bb3cb931..d9c500b9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/targaenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/targaenc.c @@ -207,7 +207,7 @@ const FFCodec ff_targa_encoder = { CODEC_LONG_NAME("Truevision Targa image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_TARGA, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(TargaContext), .p.priv_class = &targa_class, .init = targa_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tests/avcodec.c b/arm/raspi/third_party/ffmpeg/libavcodec/tests/avcodec.c index 3288a85f..4c173042 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/tests/avcodec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tests/avcodec.c @@ -158,6 +158,10 @@ int main(void){ if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS && codec->capabilities & AV_CODEC_CAP_DELAY) ERR("Frame-threaded encoder %s claims to have delay\n"); + + if (codec2->caps_internal & FF_CODEC_CAP_EOF_FLUSH && + !(codec->capabilities & AV_CODEC_CAP_DELAY)) + ERR("EOF_FLUSH encoder %s is not marked as having delay\n"); } else { if ((codec->type == AVMEDIA_TYPE_SUBTITLE) != (codec2->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB)) ERR("Subtitle decoder %s does not implement decode_sub callback\n"); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_be.c b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_be.c new file mode 100644 index 00000000..bc562ed3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_be.c @@ -0,0 +1,19 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "bitstream_template.c" diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_le.c b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_le.c new file mode 100644 index 00000000..ba9296c9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_le.c @@ -0,0 +1,20 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BITSTREAM_LE +#include "bitstream_template.c" diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_template.c b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_template.c new file mode 100644 index 00000000..ef598451 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tests/bitstream_template.c @@ -0,0 +1,200 @@ +/* + * cached bitstream reader test + * copyright (c) 2022 Anton Khirnov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define ASSERT_LEVEL 2 + +#include "libavutil/avassert.h" +#include "libavutil/lfg.h" +#include "libavutil/random_seed.h" + +#include "libavcodec/bitstream.h" +#include "libavcodec/defs.h" + +#ifdef BITSTREAM_LE +#define BITSTREAM_WRITER_LE +#endif +#include "libavcodec/put_bits.h" + +#define SIZE 157 + +enum Op { + OP_READ, + OP_READ_NZ, + OP_READ_BIT, + OP_READ_63, + OP_READ_64, + OP_READ_SIGNED, + OP_READ_SIGNED_NZ, + OP_APPLY_SIGN, + OP_ALIGN, + OP_NB, +}; + +int main(int argc, char **argv) +{ + BitstreamContext bc; + PutBitContext pb; + AVLFG lfg; + + uint8_t buf[SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; + uint8_t dst[SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; + + uint32_t random_seed; + uint64_t val, val1; + int32_t sval, sval1; + unsigned count; + + /* generate random input, using a given or random seed */ + if (argc > 1) + random_seed = strtoul(argv[1], NULL, 0); + else + random_seed = av_get_random_seed(); + + fprintf(stderr, "Testing with LFG seed: %"PRIu32"\n", random_seed); + av_lfg_init(&lfg, random_seed); + + for (unsigned i = 0; i < SIZE; i++) + buf[i] = av_lfg_get(&lfg); + + bits_init8 (&bc, buf, SIZE); + init_put_bits(&pb, dst, SIZE); + + /* use a random sequence of bitreading operations to transfer data + * from BitstreamContext to PutBitContext */ + while (bits_left(&bc) > 0) { + enum Op op = av_lfg_get(&lfg) % OP_NB; + + switch (op) { + case OP_READ: + count = av_lfg_get(&lfg) % FFMIN(33, bits_left(&bc) + 1); + val1 = bits_peek(&bc, count); + val = bits_read(&bc, count); + + fprintf(stderr, "%d read %u: %"PRIu64"\n", bits_tell(&bc) - count, count, val); + + av_assert0(val == val1); + + put_bits64(&pb, count, val); + break; + case OP_READ_NZ: + count = av_lfg_get(&lfg) % FFMIN(33, bits_left(&bc) + 1); + count = FFMAX(count, 1); + val1 = bits_peek_nz(&bc, count); + val = bits_read_nz(&bc, count); + + fprintf(stderr, "%d read_nz %u: %"PRIu64"\n", bits_tell(&bc) - count, count, val); + + av_assert0(val == val1); + + put_bits64(&pb, count, val); + break; + case OP_READ_BIT: + val = bits_read_bit(&bc); + + fprintf(stderr, "%d read_bit: %"PRIu64"\n", bits_tell(&bc) - 1, val); + + put_bits(&pb, 1, val); + break; + case OP_READ_63: + count = av_lfg_get(&lfg) % FFMIN(64, bits_left(&bc) + 1); + val = bits_read_63(&bc, count); + + fprintf(stderr, "%d read_63 %u: %"PRIu64"\n", bits_tell(&bc) - count, count, val); + + put_bits64(&pb, count, val); + break; + case OP_READ_64: + count = av_lfg_get(&lfg) % FFMIN(65, bits_left(&bc) + 1); + val = bits_read_64(&bc, count); + + fprintf(stderr, "%d read_64 %u: %"PRIu64"\n", bits_tell(&bc) - count, count, val); + + put_bits64(&pb, count, val); + break; + case OP_READ_SIGNED: + count = av_lfg_get(&lfg) % FFMIN(33, bits_left(&bc) + 1); + sval1 = bits_peek_signed(&bc, count); + sval = bits_read_signed(&bc, count); + + fprintf(stderr, "%d read_signed %u: %"PRId32"\n", bits_tell(&bc) - count, count, sval); + + av_assert0(sval == sval1); + + if (count == 32) put_bits32(&pb, sval); + else put_sbits(&pb, count, sval); + break; + case OP_READ_SIGNED_NZ: + count = av_lfg_get(&lfg) % FFMIN(33, bits_left(&bc) + 1); + count = FFMAX(count, 1); + sval1 = bits_peek_signed_nz(&bc, count); + sval = bits_read_signed_nz(&bc, count); + + fprintf(stderr, "%d read_signed_nz %u: %"PRId32"\n", bits_tell(&bc) - count, count, sval); + + av_assert0(sval == sval1); + + if (count == 32) put_bits32(&pb, sval); + else put_sbits(&pb, count, sval); + break; + case OP_ALIGN: + count = (bits_tell(&bc) + 7) / 8 * 8 - bits_tell(&bc); + + fprintf(stderr, "%d align %u\n", bits_tell(&bc), count); + + put_bits(&pb, count, bits_peek(&bc, count)); + bits_align(&bc); + break; + case OP_APPLY_SIGN: + if (bits_left(&bc) < 2) + continue; + + count = av_lfg_get(&lfg) % FFMIN(32, bits_left(&bc)); + count = FFMAX(count, 1); + + if (!bits_peek(&bc, count)) + continue; + + val = bits_read(&bc, count); + sval = bits_apply_sign(&bc, val); + + fprintf(stderr, "%d apply_sign %u %"PRId32"\n", + bits_tell(&bc) - count - 1, count, sval); + + put_bits64(&pb, count, FFABS(sval)); + put_bits(&pb, 1, sval < 0); + + break; + default: + av_assert0(0); + } + } + + flush_put_bits(&pb); + + for (unsigned i = 0; i < SIZE; i++) + if (buf[i] != dst[i]) { + fprintf(stderr, "Mismatch at byte %u: %hhu %hhu; seed %"PRIu32"\n", + i, buf[i], dst[i], random_seed); + return 1; + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tiff.c b/arm/raspi/third_party/ffmpeg/libavcodec/tiff.c index 5b568920..1a1879de 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/tiff.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tiff.c @@ -110,7 +110,6 @@ typedef struct TiffContext { int is_tiled; int tile_byte_counts_offset, tile_offsets_offset; int tile_width, tile_length; - int tile_count; int is_jpeg; @@ -327,7 +326,7 @@ static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int dst_stri scale_factor[i] = s->premultiply[s->pattern[i]] * 65535.f / (s->white_level - s->black_level[i]); } else { for (int i = 0; i < 4; i++) - scale_factor[i] = 65535.f * s->premultiply[i] / (s->white_level - s->black_level[i]); + scale_factor[i] = s->premultiply[ i ] * 65535.f / (s->white_level - s->black_level[i]); } if (is_single_comp) { @@ -994,7 +993,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, tile_count_y = (s->height + s->tile_length - 1) / s->tile_length; /* Iterate over the number of tiles */ - for (tile_idx = 0; tile_idx < s->tile_count; tile_idx++) { + for (tile_idx = 0; tile_idx < tile_count_x * tile_count_y; tile_idx++) { tile_x = tile_idx % tile_count_x; tile_y = tile_idx / tile_count_x; @@ -1430,7 +1429,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_TILE_OFFSETS: s->tile_offsets_offset = off; - s->tile_count = count; s->is_tiled = 1; break; case TIFF_TILE_BYTE_COUNTS: @@ -1896,6 +1894,8 @@ static void camera_xyz_coeff(TiffContext *s, for (i = 0; i < 3; i++) { for (num = j = 0; j < 3; j++) num += cam2rgb[i][j]; + if (!num) + num = 1; for (j = 0; j < 3; j++) cam2rgb[i][j] /= num; s->premultiply[i] = 1.f / num; @@ -2050,8 +2050,10 @@ again: } if (!s->use_color_matrix) { - for (i = 0; i < 3; i++) - s->premultiply[i] /= s->camera_calibration[i][i]; + for (i = 0; i < 3; i++) { + if (s->camera_calibration[i][i]) + s->premultiply[i] /= s->camera_calibration[i][i]; + } } else { for (int c = 0; c < 3; c++) { for (i = 0; i < 3; i++) { @@ -2094,7 +2096,7 @@ again: return AVERROR_INVALIDDATA; } - has_tile_bits = s->is_tiled || s->tile_byte_counts_offset || s->tile_offsets_offset || s->tile_width || s->tile_length || s->tile_count; + has_tile_bits = s->is_tiled || s->tile_byte_counts_offset || s->tile_offsets_offset || s->tile_width || s->tile_length; has_strip_bits = s->strippos || s->strips || s->stripoff || s->rps || s->sot || s->sstype || s->stripsize || s->stripsizesoff; if (has_tile_bits && has_strip_bits) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/tiffenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/tiffenc.c index 6dfbdaeb..06d7dcc9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/tiffenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/tiffenc.c @@ -574,7 +574,8 @@ const FFCodec ff_tiff_encoder = { CODEC_LONG_NAME("TIFF image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_TIFF, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(TiffEncoderContext), .init = encode_init, .close = encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/ttaenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/ttaenc.c index d41d2e6f..db79c38b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/ttaenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/ttaenc.c @@ -204,7 +204,8 @@ const FFCodec ff_tta_encoder = { CODEC_LONG_NAME("TTA (True Audio)"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_TTA, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(TTAEncContext), .init = tta_encode_init, .close = tta_encode_close, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/utils.c b/arm/raspi/third_party/ffmpeg/libavcodec/utils.c index 2b63a498..18a433b1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/utils.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/utils.c @@ -243,6 +243,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_GBRAP16BE: w_align = 16; //FIXME assume 16 pixel per macroblock h_align = 16 * 2; // interlaced needs 2 macroblocks height + if (s->codec_id == AV_CODEC_ID_BINKVIDEO) + w_align = 16*2; break; case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUVJ411P: @@ -514,7 +516,9 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_SGA: case AV_CODEC_ID_PCM_U8: case AV_CODEC_ID_SDX2_DPCM: + case AV_CODEC_ID_CBD2_DPCM: case AV_CODEC_ID_DERF_DPCM: + case AV_CODEC_ID_WADY_DPCM: return 8; case AV_CODEC_ID_PCM_S16BE: case AV_CODEC_ID_PCM_S16BE_PLANAR: @@ -765,6 +769,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, case AV_CODEC_ID_ADPCM_MTAF: tmp = blocks * (ba - 16LL) * 2 / ch; break; + case AV_CODEC_ID_ADPCM_XMD: + tmp = blocks * 32; + break; } if (tmp) { if (tmp != (int)tmp) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/utvideoenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/utvideoenc.c index d4388da8..6e87bbc2 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/utvideoenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/utvideoenc.c @@ -648,7 +648,8 @@ const FFCodec ff_utvideo_encoder = { CODEC_LONG_NAME("Ut Video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_UTVIDEO, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(UtvideoContext), .p.priv_class = &utvideo_class, .init = utvideo_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v210enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/v210enc.c index abbbf4ff..2a30ed77 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v210enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v210enc.c @@ -112,7 +112,8 @@ const FFCodec ff_v210_encoder = { CODEC_LONG_NAME("Uncompressed 4:2:2 10-bit"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_V210, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(V210EncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v308enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/v308enc.c index 78e33c0a..68f9c331 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v308enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v308enc.c @@ -75,7 +75,7 @@ const FFCodec ff_v308_encoder = { CODEC_LONG_NAME("Uncompressed packed 4:4:4"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_V308, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = v308_encode_init, FF_CODEC_ENCODE_CB(v308_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v408enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/v408enc.c index 514f41be..1faac7cc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v408enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v408enc.c @@ -94,7 +94,7 @@ const FFCodec ff_ayuv_encoder = { CODEC_LONG_NAME("Uncompressed packed MS 4:4:4:4"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_AYUV, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = v408_encode_init, FF_CODEC_ENCODE_CB(v408_encode_frame), .p.pix_fmts = pix_fmt, @@ -107,7 +107,7 @@ const FFCodec ff_v408_encoder = { CODEC_LONG_NAME("Uncompressed packed QT 4:4:4:4"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_V408, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = v408_encode_init, FF_CODEC_ENCODE_CB(v408_encode_frame), .p.pix_fmts = pix_fmt, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v410enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/v410enc.c index bad13c37..89ee3a72 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v410enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v410enc.c @@ -79,7 +79,7 @@ const FFCodec ff_v410_encoder = { CODEC_LONG_NAME("Uncompressed 4:4:4 10-bit"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_V410, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = v410_encode_init, FF_CODEC_ENCODE_CB(v410_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.c b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.c index 98493600..602efb7a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.c @@ -148,13 +148,15 @@ static int v4l2_configure_contexts(V4L2m2mContext *s) ofmt = s->output.format; cfmt = s->capture.format; - av_log(log_ctx, AV_LOG_INFO, "requesting formats: output=%s capture=%s\n", + av_log(log_ctx, AV_LOG_INFO, "requesting formats: output=%s/%s capture=%s/%s\n", av_fourcc2str(V4L2_TYPE_IS_MULTIPLANAR(ofmt.type) ? ofmt.fmt.pix_mp.pixelformat : ofmt.fmt.pix.pixelformat), + av_get_pix_fmt_name(s->output.av_pix_fmt) ?: "none", av_fourcc2str(V4L2_TYPE_IS_MULTIPLANAR(cfmt.type) ? cfmt.fmt.pix_mp.pixelformat : - cfmt.fmt.pix.pixelformat)); + cfmt.fmt.pix.pixelformat), + av_get_pix_fmt_name(s->capture.av_pix_fmt) ?: "none"); ret = ff_v4l2_context_set_format(&s->output); if (ret) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.h b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.h index b67b2163..04d86d7b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m.h @@ -38,7 +38,7 @@ #define V4L_M2M_DEFAULT_OPTS \ { "num_output_buffers", "Number of buffers in the output context",\ - OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 6, INT_MAX, FLAGS } + OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 2, INT_MAX, FLAGS } typedef struct V4L2m2mContext { char devname[PATH_MAX]; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m_dec.c b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m_dec.c index 53a57eae..4944d085 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m_dec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/v4l2_m2m_dec.c @@ -226,7 +226,7 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx) static const AVOption options[] = { V4L_M2M_DEFAULT_OPTS, { "num_capture_buffers", "Number of buffers in the capture context", - OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 20, INT_MAX, FLAGS }, + OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 2, INT_MAX, FLAGS }, { NULL}, }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.c index 9a58661b..bfca315a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.c @@ -695,6 +695,7 @@ static int vaapi_encode_output(AVCodecContext *avctx, pkt->flags |= AV_PKT_FLAG_KEY; pkt->pts = pic->pts; + pkt->duration = pic->duration; vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer); if (vas != VA_STATUS_SUCCESS) { @@ -704,6 +705,14 @@ static int vaapi_encode_output(AVCodecContext *avctx, goto fail; } + // for no-delay encoders this is handled in generic codec + if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY && + avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + pkt->opaque = pic->opaque; + pkt->opaque_ref = pic->opaque_ref; + pic->opaque_ref = NULL; + } + av_buffer_unref(&pic->output_buffer_ref); pic->output_buffer = VA_INVALID_ID; @@ -777,6 +786,8 @@ static int vaapi_encode_free(AVCodecContext *avctx, av_frame_free(&pic->input_image); av_frame_free(&pic->recon_image); + av_buffer_unref(&pic->opaque_ref); + av_freep(&pic->param_buffers); av_freep(&pic->slices); // Output buffer should already be destroyed. @@ -1144,6 +1155,15 @@ static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame) pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3]; pic->pts = frame->pts; + pic->duration = frame->duration; + + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref); + if (err < 0) + goto fail; + + pic->opaque = frame->opaque; + } av_frame_move_ref(pic->input_image, frame); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.h b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.h index 359f954f..a1e639f5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode.h @@ -75,8 +75,12 @@ typedef struct VAAPIEncodePicture { int64_t display_order; int64_t encode_order; int64_t pts; + int64_t duration; int force_idr; + void *opaque; + AVBufferRef *opaque_ref; + #if VA_CHECK_VERSION(1, 0, 0) // ROI regions. VAEncROI *roi; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h264.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h264.c index b1b503b2..645f6a97 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h264.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h264.c @@ -26,6 +26,7 @@ #include "libavutil/internal.h" #include "libavutil/opt.h" +#include "atsc_a53.h" #include "avcodec.h" #include "cbs.h" #include "cbs_h264.h" @@ -33,6 +34,7 @@ #include "h264.h" #include "h264_levels.h" #include "h264_sei.h" +#include "h2645data.h" #include "vaapi_encode.h" #include "version.h" @@ -40,6 +42,7 @@ enum { SEI_TIMING = 0x01, SEI_IDENTIFIER = 0x02, SEI_RECOVERY_POINT = 0x04, + SEI_A53_CC = 0x08, }; // Random (version 4) ISO 11578 UUID. @@ -98,6 +101,8 @@ typedef struct VAAPIEncodeH264Context { H264RawSEIRecoveryPoint sei_recovery_point; SEIRawUserDataUnregistered sei_identifier; char *sei_identifier_string; + SEIRawUserDataRegistered sei_a53cc; + void *sei_a53cc_data; int aud_needed; int sei_needed; @@ -248,6 +253,13 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, if (err < 0) goto fail; } + if (priv->sei_needed & SEI_A53_CC) { + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, + &priv->sei_a53cc, NULL); + if (err < 0) + goto fail; + } priv->sei_needed = 0; @@ -349,8 +361,10 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) sps->chroma_format_idc = 1; sps->log2_max_frame_num_minus4 = 4; - sps->pic_order_cnt_type = 0; - sps->log2_max_pic_order_cnt_lsb_minus4 = 4; + sps->pic_order_cnt_type = ctx->max_b_depth ? 0 : 2; + if (sps->pic_order_cnt_type == 0) { + sps->log2_max_pic_order_cnt_lsb_minus4 = 4; + } sps->max_num_ref_frames = priv->dpb_frames; @@ -378,24 +392,17 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) if (avctx->sample_aspect_ratio.num != 0 && avctx->sample_aspect_ratio.den != 0) { - static const AVRational sar_idc[] = { - { 0, 0 }, - { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, - { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, - { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, - { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, - }; int num, den, i; av_reduce(&num, &den, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 65535); - for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) { - if (num == sar_idc[i].num && - den == sar_idc[i].den) { + for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { + if (num == ff_h2645_pixel_aspect[i].num && + den == ff_h2645_pixel_aspect[i].den) { sps->vui.aspect_ratio_idc = i; break; } } - if (i >= FF_ARRAY_ELEMS(sar_idc)) { + if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { sps->vui.aspect_ratio_idc = 255; sps->vui.sar_width = num; sps->vui.sar_height = den; @@ -638,6 +645,10 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, } } hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame; + if (priv->raw_sps.pic_order_cnt_type == 2) { + hpic->pic_order_cnt *= 2; + } + hpic->dpb_delay = pic->display_order - pic->encode_order + ctx->max_b_depth; hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame; @@ -681,6 +692,22 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, priv->sei_needed |= SEI_RECOVERY_POINT; } + if (priv->sei & SEI_A53_CC) { + int err; + size_t sei_a53cc_len; + av_freep(&priv->sei_a53cc_data); + err = ff_alloc_a53_sei(pic->input_image, 0, &priv->sei_a53cc_data, &sei_a53cc_len); + if (err < 0) + return err; + if (priv->sei_a53cc_data != NULL) { + priv->sei_a53cc.itu_t_t35_country_code = 181; + priv->sei_a53cc.data = (uint8_t *)priv->sei_a53cc_data + 1; + priv->sei_a53cc.data_length = sei_a53cc_len - 1; + + priv->sei_needed |= SEI_A53_CC; + } + } + vpic->CurrPic = (VAPictureH264) { .picture_id = pic->recon_surface, .frame_idx = hpic->frame_num, @@ -1226,6 +1253,7 @@ static av_cold int vaapi_encode_h264_close(AVCodecContext *avctx) ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); av_freep(&priv->sei_identifier_string); + av_freep(&priv->sei_a53cc_data); return ff_vaapi_encode_close(avctx); } @@ -1252,7 +1280,7 @@ static const AVOption vaapi_encode_h264_options[] = { { "sei", "Set SEI to include", OFFSET(sei), AV_OPT_TYPE_FLAGS, - { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT }, + { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT | SEI_A53_CC }, 0, INT_MAX, FLAGS, "sei" }, { "identifier", "Include encoder version identifier", 0, AV_OPT_TYPE_CONST, { .i64 = SEI_IDENTIFIER }, @@ -1263,6 +1291,9 @@ static const AVOption vaapi_encode_h264_options[] = { { "recovery_point", "Include recovery points where appropriate", 0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT }, INT_MIN, INT_MAX, FLAGS, "sei" }, + { "a53_cc", "Include A/53 caption data", + 0, AV_OPT_TYPE_CONST, { .i64 = SEI_A53_CC }, + INT_MIN, INT_MAX, FLAGS, "sei" }, { "profile", "Set profile (profile_idc and constraint_set*_flag)", OFFSET(profile), AV_OPT_TYPE_INT, @@ -1336,7 +1367,7 @@ const FFCodec ff_h264_vaapi_encoder = { .close = &vaapi_encode_h264_close, .p.priv_class = &vaapi_encode_h264_class, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_DR1, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_h264_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h265.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h265.c index 94b56c65..aa7e532f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h265.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_h265.c @@ -27,10 +27,12 @@ #include "libavutil/opt.h" #include "libavutil/mastering_display_metadata.h" +#include "atsc_a53.h" #include "avcodec.h" #include "cbs.h" #include "cbs_h265.h" #include "codec_internal.h" +#include "h2645data.h" #include "h265_profile_level.h" #include "hevc.h" #include "hevc_sei.h" @@ -40,6 +42,7 @@ enum { SEI_MASTERING_DISPLAY = 0x08, SEI_CONTENT_LIGHT_LEVEL = 0x10, + SEI_A53_CC = 0x20, }; typedef struct VAAPIEncodeH265Picture { @@ -84,6 +87,8 @@ typedef struct VAAPIEncodeH265Context { SEIRawMasteringDisplayColourVolume sei_mastering_display; SEIRawContentLightLevelInfo sei_content_light_level; + SEIRawUserDataRegistered sei_a53cc; + void *sei_a53cc_data; CodedBitstreamContext *cbc; CodedBitstreamFragment current_access_unit; @@ -226,6 +231,13 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, if (err < 0) goto fail; } + if (priv->sei_needed & SEI_A53_CC) { + err = ff_cbs_sei_add_message(priv->cbc, au, 1, + SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, + &priv->sei_a53cc, NULL); + if (err < 0) + goto fail; + } priv->sei_needed = 0; @@ -496,24 +508,17 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) if (avctx->sample_aspect_ratio.num != 0 && avctx->sample_aspect_ratio.den != 0) { - static const AVRational sar_idc[] = { - { 0, 0 }, - { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, - { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, - { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, - { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, - }; int num, den, i; av_reduce(&num, &den, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 65535); - for (i = 0; i < FF_ARRAY_ELEMS(sar_idc); i++) { - if (num == sar_idc[i].num && - den == sar_idc[i].den) { + for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { + if (num == ff_h2645_pixel_aspect[i].num && + den == ff_h2645_pixel_aspect[i].den) { vui->aspect_ratio_idc = i; break; } } - if (i >= FF_ARRAY_ELEMS(sar_idc)) { + if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { vui->aspect_ratio_idc = 255; vui->sar_width = num; vui->sar_height = den; @@ -888,6 +893,22 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, } } + if (priv->sei & SEI_A53_CC) { + int err; + size_t sei_a53cc_len; + av_freep(&priv->sei_a53cc_data); + err = ff_alloc_a53_sei(pic->input_image, 0, &priv->sei_a53cc_data, &sei_a53cc_len); + if (err < 0) + return err; + if (priv->sei_a53cc_data != NULL) { + priv->sei_a53cc.itu_t_t35_country_code = 181; + priv->sei_a53cc.data = (uint8_t *)priv->sei_a53cc_data + 1; + priv->sei_a53cc.data_length = sei_a53cc_len - 1; + + priv->sei_needed |= SEI_A53_CC; + } + } + vpic->decoded_curr_pic = (VAPictureHEVC) { .picture_id = pic->recon_surface, .pic_order_cnt = hpic->pic_order_cnt, @@ -1355,6 +1376,7 @@ static av_cold int vaapi_encode_h265_close(AVCodecContext *avctx) ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); + av_freep(&priv->sei_a53cc_data); return ff_vaapi_encode_close(avctx); } @@ -1413,7 +1435,7 @@ static const AVOption vaapi_encode_h265_options[] = { { "sei", "Set SEI to include", OFFSET(sei), AV_OPT_TYPE_FLAGS, - { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, + { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL | SEI_A53_CC }, 0, INT_MAX, FLAGS, "sei" }, { "hdr", "Include HDR metadata for mastering display colour volume " @@ -1421,6 +1443,11 @@ static const AVOption vaapi_encode_h265_options[] = { 0, AV_OPT_TYPE_CONST, { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, INT_MIN, INT_MAX, FLAGS, "sei" }, + { "a53_cc", + "Include A/53 caption data", + 0, AV_OPT_TYPE_CONST, + { .i64 = SEI_A53_CC }, + INT_MIN, INT_MAX, FLAGS, "sei" }, { "tiles", "Tile columns x rows", OFFSET(common.tile_cols), AV_OPT_TYPE_IMAGE_SIZE, @@ -1460,7 +1487,7 @@ const FFCodec ff_hevc_vaapi_encoder = { .close = &vaapi_encode_h265_close, .p.priv_class = &vaapi_encode_h265_class, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_DR1, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_h265_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mjpeg.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mjpeg.c index 5ef93cd1..cb7588b9 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mjpeg.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mjpeg.c @@ -574,7 +574,8 @@ const FFCodec ff_mjpeg_vaapi_encoder = { FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), .close = &vaapi_encode_mjpeg_close, .p.priv_class = &vaapi_encode_mjpeg_class, - .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_mjpeg_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mpeg2.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mpeg2.c index 38e1d83f..9261d19a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mpeg2.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_mpeg2.c @@ -698,7 +698,7 @@ const FFCodec ff_mpeg2_vaapi_encoder = { .close = &vaapi_encode_mpeg2_close, .p.priv_class = &vaapi_encode_mpeg2_class, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_DR1, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_mpeg2_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp8.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp8.c index 93e543d7..ae6a8d31 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp8.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp8.c @@ -253,7 +253,7 @@ const FFCodec ff_vp8_vaapi_encoder = { .close = &ff_vaapi_encode_close, .p.priv_class = &vaapi_encode_vp8_class, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_DR1, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_vp8_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp9.c b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp9.c index b4c55887..af1353ce 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp9.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vaapi_encode_vp9.c @@ -308,7 +308,7 @@ const FFCodec ff_vp9_vaapi_encoder = { .close = &ff_vaapi_encode_close, .p.priv_class = &vaapi_encode_vp9_class, .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | - AV_CODEC_CAP_DR1, + AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .defaults = vaapi_encode_vp9_defaults, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vbnenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/vbnenc.c index 45101382..7ce91863 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vbnenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vbnenc.c @@ -153,7 +153,8 @@ const FFCodec ff_vbn_encoder = { CODEC_LONG_NAME("Vizrt Binary Image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_VBN, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.priv_class = &vbnenc_class, .init = vbn_init, FF_CODEC_ENCODE_CB(vbn_encode), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vc2enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/vc2enc.c index 82d11462..d978c67a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vc2enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vc2enc.c @@ -1228,7 +1228,8 @@ const FFCodec ff_vc2_encoder = { CODEC_LONG_NAME("SMPTE VC-2"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_DIRAC, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_data_size = sizeof(VC2EncContext), .init = vc2_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/version.h b/arm/raspi/third_party/ffmpeg/libavcodec/version.h index d149bc6c..499c6bb1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/version.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/version.h @@ -29,7 +29,7 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 54 +#define LIBAVCODEC_VERSION_MINOR 61 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/version_major.h b/arm/raspi/third_party/ffmpeg/libavcodec/version_major.h index 12f863de..2c0443c4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/version_major.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/version_major.h @@ -52,6 +52,7 @@ #define FF_API_SVTAV1_OPTS (LIBAVCODEC_VERSION_MAJOR < 60) #define FF_API_AYUV_CODECID (LIBAVCODEC_VERSION_MAJOR < 60) #define FF_API_VT_OUTPUT_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 60) +#define FF_API_VT_HWACCEL_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 60) #define FF_API_AVCODEC_CHROMA_POS (LIBAVCODEC_VERSION_MAJOR < 60) #endif /* AVCODEC_VERSION_MAJOR_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.c b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.c index 1b1be8dd..e42fea6f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.c @@ -1173,6 +1173,22 @@ static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx) return AV_PIX_FMT_NV12; } +static AVVideotoolboxContext *videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt, + bool full_range) +{ + AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret)); + + if (ret) { + OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range); + if (cv_pix_fmt_type == 0) { + cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + } + ret->cv_pix_fmt_type = cv_pix_fmt_type; + } + + return ret; +} + int ff_videotoolbox_common_init(AVCodecContext *avctx) { VTContext *vtctx = avctx->internal->hwaccel_priv_data; @@ -1181,9 +1197,9 @@ int ff_videotoolbox_common_init(AVCodecContext *avctx) vtctx->logctx = avctx; - // Old API - do nothing. - if (avctx->hwaccel_context) - return 0; + if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx && + avctx->hwaccel_context) + return videotoolbox_start(avctx); if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) { av_log(avctx, AV_LOG_ERROR, @@ -1191,7 +1207,7 @@ int ff_videotoolbox_common_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - vtctx->vt_ctx = av_videotoolbox_alloc_context(); + vtctx->vt_ctx = videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false); if (!vtctx->vt_ctx) { err = AVERROR(ENOMEM); goto fail; @@ -1371,25 +1387,12 @@ const AVHWAccel ff_prores_videotoolbox_hwaccel = { .priv_data_size = sizeof(VTContext), }; -static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt, - bool full_range) -{ - AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret)); - if (ret) { - OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range); - if (cv_pix_fmt_type == 0) { - cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; - } - ret->cv_pix_fmt_type = cv_pix_fmt_type; - } - - return ret; -} +#if FF_API_VT_HWACCEL_CONTEXT AVVideotoolboxContext *av_videotoolbox_alloc_context(void) { - return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false); + return videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false); } int av_videotoolbox_default_init(AVCodecContext *avctx) @@ -1401,10 +1404,10 @@ int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext * { enum AVPixelFormat pix_fmt = videotoolbox_best_pixel_format(avctx); bool full_range = avctx->color_range == AVCOL_RANGE_JPEG; - avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(pix_fmt, full_range); + avctx->hwaccel_context = vtctx ?: videotoolbox_alloc_context_with_pix_fmt(pix_fmt, full_range); if (!avctx->hwaccel_context) return AVERROR(ENOMEM); - return videotoolbox_start(avctx); + return 0; } void av_videotoolbox_default_free(AVCodecContext *avctx) @@ -1413,4 +1416,6 @@ void av_videotoolbox_default_free(AVCodecContext *avctx) videotoolbox_stop(avctx); av_freep(&avctx->hwaccel_context); } +#endif /* FF_API_VT_HWACCEL_CONTEXT */ + #endif /* CONFIG_VIDEOTOOLBOX */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.h b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.h index 25a747a4..ba5eddbf 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolbox.h @@ -57,7 +57,6 @@ typedef struct AVVideotoolboxContext { /** * Videotoolbox decompression session object. - * Created and freed the caller. */ VTDecompressionSessionRef session; @@ -79,17 +78,17 @@ typedef struct AVVideotoolboxContext { /** * CoreMedia Format Description that Videotoolbox will use to create the decompression session. - * Set by the caller. */ CMVideoFormatDescriptionRef cm_fmt_desc; /** * CoreMedia codec type that Videotoolbox will use to create the decompression session. - * Set by the caller. */ int cm_codec_type; } AVVideotoolboxContext; +#if FF_API_VT_HWACCEL_CONTEXT + /** * Allocate and initialize a Videotoolbox context. * @@ -102,7 +101,9 @@ typedef struct AVVideotoolboxContext { * object and free the Videotoolbox context using av_free(). * * @return the newly allocated context or NULL on failure + * @deprecated Use AVCodecContext.hw_frames_ctx or hw_device_ctx instead. */ +attribute_deprecated AVVideotoolboxContext *av_videotoolbox_alloc_context(void); /** @@ -112,7 +113,9 @@ AVVideotoolboxContext *av_videotoolbox_alloc_context(void); * @param avctx the corresponding codec context * * @return >= 0 on success, a negative AVERROR code on failure + * @deprecated Use AVCodecContext.hw_frames_ctx or hw_device_ctx instead. */ +attribute_deprecated int av_videotoolbox_default_init(AVCodecContext *avctx); /** @@ -123,7 +126,9 @@ int av_videotoolbox_default_init(AVCodecContext *avctx); * @param vtctx the Videotoolbox context to use * * @return >= 0 on success, a negative AVERROR code on failure + * @deprecated Use AVCodecContext.hw_frames_ctx or hw_device_ctx instead. */ +attribute_deprecated int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx); /** @@ -131,9 +136,13 @@ int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext * * av_videotoolbox_default_init(). * * @param avctx the corresponding codec context + * @deprecated Use AVCodecContext.hw_frames_ctx or hw_device_ctx instead. */ +attribute_deprecated void av_videotoolbox_default_free(AVCodecContext *avctx); +#endif /* FF_API_VT_HWACCEL_CONTEXT */ + /** * @} */ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolboxenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolboxenc.c index dc9e321d..56971471 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/videotoolboxenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/videotoolboxenc.c @@ -399,6 +399,10 @@ static int count_nalus(size_t length_code_size, length_code_size, size_buf); + if (status != kCMBlockBufferNoErr) { + return AVERROR_EXTERNAL; + } + for (i = 0; i < length_code_size; i++) { box_len <<= 8; box_len |= size_buf[i]; @@ -843,13 +847,22 @@ static int get_cv_pixel_format(AVCodecContext* avctx, int* av_pixel_format, int* range_guessed) { + const char *range_name; if (range_guessed) *range_guessed = range != AVCOL_RANGE_MPEG && range != AVCOL_RANGE_JPEG; //MPEG range is used when no range is set *av_pixel_format = av_map_videotoolbox_format_from_pixfmt2(fmt, range == AVCOL_RANGE_JPEG); + if (*av_pixel_format) + return 0; - return *av_pixel_format ? 0 : AVERROR(EINVAL); + range_name = av_color_range_name(range); + av_log(avctx, AV_LOG_ERROR, + "Could not get pixel format for color format '%s' range '%s'.\n", + av_get_pix_fmt_name(fmt), + range_name ? range_name : "Unknown"); + + return AVERROR(EINVAL); } static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict) { @@ -1637,7 +1650,6 @@ static int find_sei_end(AVCodecContext *avctx, { int nal_type; size_t sei_payload_size = 0; - int sei_payload_type = 0; *sei_end = NULL; uint8_t *nal_start = nal_data; @@ -1656,7 +1668,6 @@ static int find_sei_end(AVCodecContext *avctx, while (nal_size > 0 && *nal_data > 0) { do{ - sei_payload_type += *nal_data; nal_data++; nal_size--; } while (nal_size > 0 && *nal_data == 0xFF); @@ -2144,18 +2155,8 @@ static int get_cv_pixel_info( return AVERROR(EINVAL); status = get_cv_pixel_format(avctx, av_format, av_color_range, color, &range_guessed); - if (status) { - av_log(avctx, - AV_LOG_ERROR, - "Could not get pixel format for color format '%s' range '%s'.\n", - av_get_pix_fmt_name(av_format), - av_color_range > AVCOL_RANGE_UNSPECIFIED && - av_color_range < AVCOL_RANGE_NB ? - av_color_range_name(av_color_range) : - "Unknown"); - - return AVERROR(EINVAL); - } + if (status) + return status; if (range_guessed) { if (!vtctx->warned_color_range) { @@ -2337,7 +2338,7 @@ static int create_cv_pixel_buffer(AVCodecContext *avctx, status ); - return AVERROR_EXTERNAL; + return status; } pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session); @@ -2554,6 +2555,7 @@ static int vtenc_populate_extradata(AVCodecContext *avctx, pool = VTCompressionSessionGetPixelBufferPool(vtctx->session); if(!pool){ av_log(avctx, AV_LOG_ERROR, "Error getting pixel buffer pool.\n"); + status = AVERROR_EXTERNAL; goto pe_cleanup; } @@ -2563,6 +2565,7 @@ static int vtenc_populate_extradata(AVCodecContext *avctx, if(status != kCVReturnSuccess){ av_log(avctx, AV_LOG_ERROR, "Error creating frame from pool: %d\n", status); + status = AVERROR_EXTERNAL; goto pe_cleanup; } @@ -2580,7 +2583,7 @@ static int vtenc_populate_extradata(AVCodecContext *avctx, AV_LOG_ERROR, "Error sending frame for extradata: %d\n", status); - + status = AVERROR_EXTERNAL; goto pe_cleanup; } @@ -2588,8 +2591,10 @@ static int vtenc_populate_extradata(AVCodecContext *avctx, status = VTCompressionSessionCompleteFrames(vtctx->session, kCMTimeIndefinite); - if (status) + if (status) { + status = AVERROR_EXTERNAL; goto pe_cleanup; + } status = vtenc_q_pop(vtctx, 0, &buf, NULL); if (status) { diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/vqcdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/vqcdec.c index 18cd9946..c3bce879 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/vqcdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/vqcdec.c @@ -71,6 +71,9 @@ static av_cold int vqc_decode_init(AVCodecContext * avctx) static AVOnce init_static_once = AV_ONCE_INIT; VqcContext *s = avctx->priv_data; + if (avctx->width & 15) + return AVERROR_PATCHWELCOME; + s->vectors = av_malloc((avctx->width * avctx->height * 3) / 2); if (!s->vectors) return AVERROR(ENOMEM); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wavpack.c b/arm/raspi/third_party/ffmpeg/libavcodec/wavpack.c index 7aa1f65e..4346304f 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wavpack.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wavpack.c @@ -126,10 +126,10 @@ static av_always_inline unsigned get_tail(GetBitContext *gb, unsigned k) if (k < 1) return 0; p = av_log2(k); - e = (1 << (p + 1)) - k - 1; + e = (1LL << (p + 1)) - k - 1; res = get_bits_long(gb, p); if (res >= e) - res = (res << 1) - e + get_bits1(gb); + res = res * 2U - e + get_bits1(gb); return res; } @@ -495,6 +495,8 @@ static int wv_unpack_dsd_high(WavpackFrameContext *s, uint8_t *dst_left, uint8_t sp[0].fltr0 = 0; } + if (DSD_BYTE_READY(high, low) && !bytestream2_get_bytes_left(&s->gbyte)) + return AVERROR_INVALIDDATA; while (DSD_BYTE_READY(high, low) && bytestream2_get_bytes_left(&s->gbyte)) { value = (value << 8) | bytestream2_get_byte(&s->gbyte); high = (high << 8) | 0xff; @@ -530,6 +532,8 @@ static int wv_unpack_dsd_high(WavpackFrameContext *s, uint8_t *dst_left, uint8_t sp[1].fltr0 = 0; } + if (DSD_BYTE_READY(high, low) && !bytestream2_get_bytes_left(&s->gbyte)) + return AVERROR_INVALIDDATA; while (DSD_BYTE_READY(high, low) && bytestream2_get_bytes_left(&s->gbyte)) { value = (value << 8) | bytestream2_get_byte(&s->gbyte); high = (high << 8) | 0xff; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wavpackenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/wavpackenc.c index bdb53638..3d2d4536 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wavpackenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wavpackenc.c @@ -2963,7 +2963,8 @@ const FFCodec ff_wavpack_encoder = { CODEC_LONG_NAME("WavPack"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_WAVPACK, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(WavPackEncodeContext), .p.priv_class = &wavpack_encoder_class, .init = wavpack_encode_init, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wbmpdec.c b/arm/raspi/third_party/ffmpeg/libavcodec/wbmpdec.c index 9638b55b..8b105bc1 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wbmpdec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wbmpdec.c @@ -72,7 +72,7 @@ static int wbmp_decode_frame(AVCodecContext *avctx, AVFrame *p, if (p->linesize[0] == (width + 7) / 8) bytestream2_get_buffer(&gb, p->data[0], height * ((width + 7) / 8)); else - readbits(p->data[0], width, height, p->linesize[0], gb.buffer, gb.buffer_end - gb.buffer_start); + readbits(p->data[0], width, height, p->linesize[0], gb.buffer, gb.buffer_end - gb.buffer); p->key_frame = 1; p->pict_type = AV_PICTURE_TYPE_I; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wbmpenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/wbmpenc.c index 25fac746..abb66b4c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wbmpenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wbmpenc.c @@ -80,7 +80,8 @@ const FFCodec ff_wbmp_encoder = { CODEC_LONG_NAME("WBMP (Wireless Application Protocol Bitmap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_WBMP, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(wbmp_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOBLACK, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wmadec.c b/arm/raspi/third_party/ffmpeg/libavcodec/wmadec.c index 15d6fb42..bc18d182 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wmadec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wmadec.c @@ -845,6 +845,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, AVFrame *frame, if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; + frame->pts = AV_NOPTS_VALUE; for (i = 0; i < s->avctx->ch_layout.nb_channels; i++) memcpy(frame->extended_data[i], &s->frame_out[i][0], frame->nb_samples * sizeof(s->frame_out[i][0])); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wmaenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/wmaenc.c index 2c647af1..80ff696b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wmaenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wmaenc.c @@ -440,7 +440,7 @@ const FFCodec ff_wmav1_encoder = { CODEC_LONG_NAME("Windows Media Audio 1"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_WMAV1, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(WMACodecContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_superframe), @@ -456,7 +456,7 @@ const FFCodec ff_wmav2_encoder = { CODEC_LONG_NAME("Windows Media Audio 2"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_WMAV2, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(WMACodecContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_superframe), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wmaprodec.c b/arm/raspi/third_party/ffmpeg/libavcodec/wmaprodec.c index fbfe75ee..7f735783 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wmaprodec.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wmaprodec.c @@ -2110,6 +2110,7 @@ const FFCodec ff_xma1_decoder = { .init = xma_decode_init, .close = xma_decode_end, FF_CODEC_DECODE_CB(xma_decode_packet), + .flush = xma_flush, .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.c index 05f99352..8eb56444 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.c @@ -93,7 +93,7 @@ static av_cold int wmv2_encode_init(AVCodecContext *avctx) return 0; } -int ff_wmv2_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_wmv2_encode_picture_header(MpegEncContext *s) { WMV2EncContext *const w = (WMV2EncContext *) s; @@ -242,6 +242,7 @@ const FFCodec ff_wmv2_encoder = { .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_WMV2, .p.priv_class = &ff_mpv_enc_class, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(WMV2EncContext), .init = wmv2_encode_init, FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.h b/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.h index 3f7f5104..263265ac 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.h +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wmv2enc.h @@ -23,7 +23,7 @@ #include "mpegvideo.h" -int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number); +int ff_wmv2_encode_picture_header(MpegEncContext * s); void ff_wmv2_encode_mb(MpegEncContext * s, int16_t block[6][64], int motion_x, int motion_y); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/wrapped_avframe.c b/arm/raspi/third_party/ffmpeg/libavcodec/wrapped_avframe.c index c9579848..0278ea42 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/wrapped_avframe.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/wrapped_avframe.c @@ -109,6 +109,7 @@ const FFCodec ff_wrapped_avframe_encoder = { CODEC_LONG_NAME("AVFrame to AVPacket passthrough"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_WRAPPED_AVFRAME, + .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(wrapped_avframe_encode), }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/Makefile b/arm/raspi/third_party/ffmpeg/libavcodec/x86/Makefile index 6f628780..118daca3 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/Makefile +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/Makefile @@ -138,8 +138,11 @@ X86ASM-OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp.o \ X86ASM-OBJS-$(CONFIG_RV34DSP) += x86/rv34dsp.o X86ASM-OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_loopfilter.o \ x86/vc1dsp_mc.o -X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct10.o \ - x86/simple_idct.o +ifdef ARCH_X86_64 +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct10.o +else +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct.o +endif X86ASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o X86ASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o X86ASM-OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp.o \ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/aacpsdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/aacpsdsp.asm index 105e1af5..cc496d4d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/aacpsdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/aacpsdsp.asm @@ -49,7 +49,7 @@ align 16 add dstq, mmsize add nq, mmsize*2 jl .loop - REP_RET + RET %endmacro INIT_XMM sse @@ -83,7 +83,7 @@ align 16 add src2q, mmsize add nq, mmsize*2 jl .loop - REP_RET + RET ;*********************************************************************** ;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], @@ -116,7 +116,7 @@ align 16 movhps [rq+nq], m2 add nq, 8 jl .loop - REP_RET + RET ;*************************************************************************** ;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], @@ -164,7 +164,7 @@ align 16 movhps [rq+nq], m2 add nq, 8 jl .loop - REP_RET + RET ;********************************************************** ;void ps_hybrid_analysis_ileave_sse(float out[2][38][64], @@ -484,7 +484,7 @@ align 16 add outq, strideq add nq, 64 jl .loop - REP_RET + RET %endmacro INIT_XMM sse diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/ac3dsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/ac3dsp.asm index c11a94ca..a95d359d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/ac3dsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/ac3dsp.asm @@ -60,7 +60,7 @@ cglobal ac3_exponent_min, 3, 4, 2, exp, reuse_blks, expn, offset sub expnq, mmsize jg .nextexp .end: - REP_RET + RET %endmacro %define LOOP_ALIGN ALIGN 16 @@ -126,7 +126,7 @@ cglobal float_to_fixed24, 3, 3, 9, dst, src, len sub lenq, 16 %endif ja .loop - REP_RET + RET ;------------------------------------------------------------------------------ ; int ff_ac3_compute_mantissa_size(uint16_t mant_cnt[6][16]) @@ -220,7 +220,7 @@ cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len add lenq, 4 jl .loop - REP_RET + RET %endmacro %if HAVE_SSE2_EXTERNAL diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/alacdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/alacdsp.asm index bb2069f7..1cfd302d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/alacdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/alacdsp.asm @@ -100,7 +100,7 @@ align 16 add lenq, mmsize*2 jl .loop - REP_RET + RET %if ARCH_X86_64 cglobal alac_append_extra_bits_mono, 2, 5, 3, buf, exbuf, exbits, ch, len @@ -130,4 +130,4 @@ align 16 add lenq, mmsize*2 jl .loop - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/audiodsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/audiodsp.asm index f64077cb..cf5baa94 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/audiodsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/audiodsp.asm @@ -123,7 +123,7 @@ cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len add dstq, mmsize*4*(%2+%3) sub lend, mmsize*(%2+%3) jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/dirac_dwt.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/dirac_dwt.asm index 6c8b3c0d..1f3b238a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/dirac_dwt.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/dirac_dwt.asm @@ -75,7 +75,7 @@ cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width COMPOSE_53iL0 m0, m1, [b2q+2*widthq], m2 mova [b1q+2*widthq], m0 jg .loop - REP_RET + RET ; void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, ; int width) @@ -93,7 +93,7 @@ cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width paddw m0, [b1q+2*widthq] mova [b1q+2*widthq], m0 jg .loop - REP_RET + RET ; void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, ; IDWTELEM *b3, IDWTELEM *b4, int width) @@ -110,7 +110,7 @@ cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width COMPOSE_DD97iH0 [b2q+2*widthq], [b3q+2*widthq], [b4q+2*widthq] mova [b2q+2*widthq], m1 jg .loop - REP_RET + RET ; void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, ; IDWTELEM *b3, IDWTELEM *b4, int width) @@ -139,7 +139,7 @@ cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width psubw m5, m1 mova [b2q+2*widthq], m5 jg .loop - REP_RET + RET ; void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width) cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width @@ -159,7 +159,7 @@ cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width paddw m2, m0 mova [b1q+2*widthq], m2 jg .loop - REP_RET + RET %endmacro ; extend the left and right edges of the tmp array by %1 and %2 respectively @@ -225,7 +225,7 @@ cglobal horizontal_compose_haar%2i_%1, 3,6,4, b, tmp, w, x, w2, b_w2 cmp xq, w2q jl .highpass_loop .end: - REP_RET + RET %endmacro @@ -290,7 +290,7 @@ cglobal horizontal_compose_dd97i_ssse3, 3,6,8, b, tmp, w, x, w2, b_w2 cmp xd, w2d jl .highpass_loop .end: - REP_RET + RET INIT_XMM diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/fft.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/fft.asm index a44596e5..34c3fc9a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/fft.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/fft.asm @@ -475,7 +475,7 @@ cglobal fft_calc, 2,5,8 mov r0, r1 mov r1, r3 FFT_DISPATCH _interleave %+ SUFFIX, r1 - REP_RET + RET %endif @@ -510,7 +510,7 @@ cglobal fft_calc, 2,5,8 add r2, mmsize*2 jl .loop .end: - REP_RET + RET cglobal fft_permute, 2,7,1 mov r4, [r0 + FFTContext.revtab] @@ -543,7 +543,7 @@ cglobal fft_permute, 2,7,1 movaps [r1 + r2 + 16], xmm1 add r2, 32 jl .loopcopy - REP_RET + RET INIT_XMM sse cglobal imdct_calc, 3,5,3 @@ -583,7 +583,7 @@ cglobal imdct_calc, 3,5,3 sub r3, mmsize add r2, mmsize jl .loop - REP_RET + RET %ifdef PIC %define SECTION_REL - $$ diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/flacdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/flacdsp.asm index 6d755f49..44416e4d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/flacdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/flacdsp.asm @@ -79,7 +79,7 @@ ALIGN 16 movd [decodedq+4], m1 jg .loop_sample .ret: - REP_RET + RET %endmacro %if HAVE_XOP_EXTERNAL @@ -133,7 +133,7 @@ align 16 mova [outq + lenq], m%2 add lenq, 16 jl .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -177,7 +177,7 @@ align 16 add outq, mmsize*2 sub lend, mmsize/4 jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -302,7 +302,7 @@ align 16 add outq, mmsize*REPCOUNT sub lend, mmsize/4 jg .loop - REP_RET + RET %endmacro INIT_XMM ssse3 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc.asm index a5c53034..e70bc492 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc.asm @@ -112,7 +112,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7 + extra_regs, 0 jne .at_least_one_non_zero ; mx == 0 AND my == 0 - no filter needed mv0_pixels_mc8 - REP_RET + RET .at_least_one_non_zero: %ifidn %2, rv40 @@ -192,7 +192,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7 + extra_regs, 0 add r1, r2 dec r3d jne .next1drow - REP_RET + RET .both_non_zero: ; general case, bilinear movd m4, r4d ; x @@ -365,7 +365,7 @@ cglobal %1_%2_chroma_mc4, 6, 6 + extra_regs, 0 add r0, r2 sub r3d, 2 jnz .next2rows - REP_RET + RET %endmacro %macro chroma_mc2_mmx_func 2 @@ -407,7 +407,7 @@ cglobal %1_%2_chroma_mc2, 6, 7, 0 add r0, r2 sub r3d, 1 jnz .nextrow - REP_RET + RET %endmacro %define rnd_1d_h264 pw_4 @@ -453,7 +453,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7, 8 jne .at_least_one_non_zero ; mx == 0 AND my == 0 - no filter needed mv0_pixels_mc8 - REP_RET + RET .at_least_one_non_zero: test r5d, r5d @@ -514,7 +514,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7, 8 sub r3d, 2 lea r0, [r0+r2*2] jg .next2rows - REP_RET + RET .my_is_zero: mov r5d, r4d @@ -551,7 +551,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7, 8 lea r0, [r0+r2*2] lea r1, [r1+r2*2] jg .next2xrows - REP_RET + RET .mx_is_zero: mov r4d, r5d @@ -588,7 +588,7 @@ cglobal %1_%2_chroma_mc8%3, 6, 7, 8 sub r3d, 2 lea r0, [r0+r2*2] jg .next2yrows - REP_RET + RET %endmacro %macro chroma_mc4_ssse3_func 2 @@ -638,7 +638,7 @@ cglobal %1_%2_chroma_mc4, 6, 7, 0 sub r3d, 2 lea r0, [r0+r2*2] jg .next2rows - REP_RET + RET %endmacro %define CHROMAMC_AVG NOTHING diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm index fdc4f407..d4f92c90 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_chromamc_10bit.asm @@ -67,7 +67,7 @@ cglobal %1_h264_chroma_mc8_10, 6,7,8 jne .at_least_one_non_zero ; mx == 0 AND my == 0 - no filter needed MV0_PIXELS_MC8 - REP_RET + RET .at_least_one_non_zero: mov r6d, 2 @@ -102,7 +102,7 @@ cglobal %1_h264_chroma_mc8_10, 6,7,8 add r1, r2 dec r3d jne .next1drow - REP_RET + RET .xy_interpolation: ; general case, bilinear movd m4, r4m ; x @@ -144,7 +144,7 @@ cglobal %1_h264_chroma_mc8_10, 6,7,8 add r0, r2 dec r3d jne .next2drow - REP_RET + RET %endmacro ;----------------------------------------------------------------------------- @@ -194,7 +194,7 @@ cglobal %1_h264_chroma_mc4_10, 6,6,7 MC4_OP m6, m0 sub r3d, 2 jnz .next2rows - REP_RET + RET %endmacro ;----------------------------------------------------------------------------- @@ -234,7 +234,7 @@ cglobal %1_h264_chroma_mc2_10, 6,7 add r0, r2 dec r3d jnz .nextrow - REP_RET + RET %endmacro %macro NOTHING 2-3 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm index 23971b5c..033f2f4d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_deblock_10bit.asm @@ -372,7 +372,7 @@ cglobal deblock_v_luma_10, 5,5,15 add r4, 2 dec r3 jg .loop - REP_RET + RET cglobal deblock_h_luma_10, 5,7,15 shl r2d, 2 @@ -411,7 +411,7 @@ cglobal deblock_h_luma_10, 5,7,15 lea r5, [r5+r1*8] dec r6 jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -648,7 +648,7 @@ cglobal deblock_v_luma_intra_10, 4,7,16 add r4, mmsize dec r6 jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_deblock_h_luma_intra_10(uint16_t *pix, int stride, int alpha, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct.asm index 9b5920d3..1f86e51d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct.asm @@ -354,7 +354,7 @@ INIT_MMX cpuname add r2, 128 cmp r5, 16 jl .nextblock - REP_RET + RET .no_dc: INIT_XMM cpuname mov dst2d, dword [r1+r5*4] @@ -368,7 +368,7 @@ INIT_XMM cpuname add r2, 128 cmp r5, 16 jl .nextblock - REP_RET + RET INIT_MMX mmx h264_idct_add8_mmx_plane: @@ -508,7 +508,7 @@ cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8 add16_sse2_cycle 5, 0x24 add16_sse2_cycle 6, 0x1e add16_sse2_cycle 7, 0x26 -REP_RET +RET %macro add16intra_sse2_cycle 2 movzx r0, word [r4+%2] @@ -555,7 +555,7 @@ cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8 add16intra_sse2_cycle 5, 0x24 add16intra_sse2_cycle 6, 0x1e add16intra_sse2_cycle 7, 0x26 -REP_RET +RET %macro add8_sse2_cycle 2 movzx r0, word [r4+%2] @@ -610,7 +610,7 @@ cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8 %endif add8_sse2_cycle 2, 0x5c add8_sse2_cycle 3, 0x64 -REP_RET +RET ;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct_10bit.asm index 9fd05abb..b990db71 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_idct_10bit.asm @@ -155,7 +155,7 @@ cglobal h264_idct_add16_10, 5,6 ADD16_OP 13, 7+3*8 ADD16_OP 14, 6+4*8 ADD16_OP 15, 7+4*8 - REP_RET + RET %endmacro INIT_XMM sse2 @@ -292,7 +292,7 @@ cglobal h264_idct_add16intra_10,5,7,8 ADD16_OP_INTRA 10, 4+4*8 ADD16_OP_INTRA 12, 6+3*8 ADD16_OP_INTRA 14, 6+4*8 - REP_RET + RET AC 8 AC 10 AC 12 @@ -335,7 +335,7 @@ cglobal h264_idct_add8_10,5,8,7 %endif ADD16_OP_INTRA 32, 4+11*8 ADD16_OP_INTRA 34, 4+12*8 - REP_RET + RET AC 16 AC 18 AC 32 @@ -384,7 +384,7 @@ cglobal h264_idct_add8_422_10, 5, 8, 7 ADD16_OP_INTRA 34, 4+12*8 ADD16_OP_INTRA 40, 4+13*8 ; i+4 ADD16_OP_INTRA 42, 4+14*8 ; i+4 -REP_RET +RET AC 16 AC 18 AC 24 ; i+4 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred.asm index 31840a14..8a38ba2b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred.asm @@ -62,7 +62,7 @@ cglobal pred16x16_vertical_8, 2,3 lea r0, [r0+r1*2] dec r2 jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_horizontal_8(uint8_t *src, ptrdiff_t stride) @@ -95,7 +95,7 @@ cglobal pred16x16_horizontal_8, 2,3 lea r0, [r0+r1*2] dec r2 jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -146,7 +146,7 @@ cglobal pred16x16_dc_8, 2,7 lea r4, [r4+r1*2] dec r3d jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -192,7 +192,7 @@ cglobal pred16x16_tm_vp8_8, 2,6,6 lea r0, [r0+r1*2] dec r5d jg .loop - REP_RET + RET %if HAVE_AVX2_EXTERNAL INIT_YMM avx2 @@ -228,7 +228,7 @@ cglobal pred16x16_tm_vp8_8, 2, 4, 5, dst, stride, stride3, iteration lea dstq, [dstq+strideq*4] dec iterationd jg .loop - REP_RET + RET %endif ;----------------------------------------------------------------------------- @@ -427,7 +427,7 @@ cglobal pred16x16_plane_%1_8, 2,9,7 lea r0, [r0+r2*2] dec r4 jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -556,7 +556,7 @@ ALIGN 16 lea r0, [r0+r2*2] dec r4 jg .loop - REP_RET + RET %endmacro INIT_XMM sse2 @@ -599,7 +599,7 @@ cglobal pred8x8_horizontal_8, 2,3 lea r0, [r0+r1*2] dec r2 jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -737,7 +737,7 @@ cglobal pred8x8_dc_rv40_8, 2,7 lea r4, [r4+r1*2] dec r3d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred8x8_tm_vp8_8(uint8_t *src, ptrdiff_t stride) @@ -770,7 +770,7 @@ cglobal pred8x8_tm_vp8_8, 2,6,4 lea r0, [r0+r1*2] dec r5d jg .loop - REP_RET + RET INIT_XMM ssse3 cglobal pred8x8_tm_vp8_8, 2,3,6 @@ -797,7 +797,7 @@ cglobal pred8x8_tm_vp8_8, 2,3,6 lea r0, [r0+r1*2] dec r2d jg .loop - REP_RET + RET ; dest, left, right, src, tmp ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2 @@ -1802,7 +1802,7 @@ cglobal pred4x4_tm_vp8_8, 3,6 lea r0, [r0+r2*2] dec r5d jg .loop - REP_RET + RET INIT_XMM ssse3 cglobal pred4x4_tm_vp8_8, 3,3 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm index c4645d43..2f308073 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_intrapred_10bit.asm @@ -327,7 +327,7 @@ cglobal pred8x8_horizontal_10, 2, 3 lea r0, [r0+r1*2] dec r2d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_predict_8x8_dc_10(pixel *src, ptrdiff_t stride) @@ -481,7 +481,7 @@ cglobal pred8x8_plane_10, 2, 7, 7 add r0, r1 dec r2d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- @@ -994,7 +994,7 @@ cglobal pred16x16_vertical_10, 2, 3 lea r0, [r0+r1*2] dec r2d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_horizontal_10(pixel *src, ptrdiff_t stride) @@ -1012,7 +1012,7 @@ cglobal pred16x16_horizontal_10, 2, 3 lea r0, [r0+r1*2] dec r2d jg .vloop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_dc_10(pixel *src, ptrdiff_t stride) @@ -1048,7 +1048,7 @@ cglobal pred16x16_dc_10, 2, 6 lea r5, [r5+r1*2] dec r3d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_top_dc_10(pixel *src, ptrdiff_t stride) @@ -1070,7 +1070,7 @@ cglobal pred16x16_top_dc_10, 2, 3 lea r0, [r0+r1*2] dec r2d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_left_dc_10(pixel *src, ptrdiff_t stride) @@ -1101,7 +1101,7 @@ cglobal pred16x16_left_dc_10, 2, 6 lea r5, [r5+r1*2] dec r3d jg .loop - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_pred16x16_128_dc_10(pixel *src, ptrdiff_t stride) @@ -1116,4 +1116,4 @@ cglobal pred16x16_128_dc_10, 2,3 lea r0, [r0+r1*2] dec r2d jg .loop - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm index c862cb22..80483b15 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_10bit.asm @@ -211,7 +211,7 @@ cglobal %1_h264_qpel16_mc00_10, 3,4 lea r1, [r1+r2*2] dec r3d jg .loop - REP_RET + RET %endmacro %define OP_MOV mova diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_8bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_8bit.asm index 6269b3cf..4e643299 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_8bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_qpel_8bit.asm @@ -89,7 +89,7 @@ cglobal %1_h264_qpel4_h_lowpass, 4,5 ; dst, src, dstStride, srcStride add r1, r3 dec r4d jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -149,7 +149,7 @@ cglobal %1_h264_qpel8_h_lowpass, 4,5 ; dst, src, dstStride, srcStride add r1, r3 dec r4d jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -192,7 +192,7 @@ cglobal %1_h264_qpel8_h_lowpass, 4,5,8 ; dst, src, dstStride, srcStride add r0, r2 dec r4d jne .loop - REP_RET + RET %endmacro INIT_XMM ssse3 @@ -239,7 +239,7 @@ cglobal %1_h264_qpel4_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride add r2, r4 dec r5d jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -303,7 +303,7 @@ cglobal %1_h264_qpel8_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride add r2, r4 dec r5d jg .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -350,7 +350,7 @@ cglobal %1_h264_qpel8_h_lowpass_l2, 5,6,8 ; dst, src, src2, dstStride, src2Strid add r2, r4 dec r5d jg .loop - REP_RET + RET %endmacro INIT_XMM ssse3 @@ -458,7 +458,7 @@ cglobal %1_h264_qpel8or16_v_lowpass_op, 5,5,8 ; dst, src, dstStride, srcStride, FILT_V %1 FILT_V %1 .end: - REP_RET + RET %endmacro INIT_XMM sse2 @@ -531,7 +531,7 @@ cglobal %1_h264_qpel4_hv_lowpass_h, 3,4 ; tmp, dst, dstStride add r1, r2 dec r3d jnz .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -574,7 +574,7 @@ cglobal %1_h264_qpel8or16_hv1_lowpass_op, 4,4,8 ; src, tmp, srcStride, size FILT_HV 14*48 FILT_HV 15*48 .end: - REP_RET + RET %endmacro INIT_XMM sse2 @@ -619,7 +619,7 @@ cglobal %1_h264_qpel8or16_hv2_lowpass_op, 5,5 ; dst, tmp, dstStride, unused, h add r0, r2 dec r4d jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -710,7 +710,7 @@ cglobal %1_h264_qpel8or16_hv2_lowpass, 5,5,8 ; dst, tmp, dstStride, tmpStride, s dec r4d jne .op16 .done: - REP_RET + RET %endmacro INIT_XMM ssse3 @@ -776,7 +776,7 @@ cglobal %1_pixels8_l2_shift5, 6, 6 ; dst, src16, src8, dstStride, src8Stride, h lea r0, [r0+2*r3] sub r5d, 2 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -845,7 +845,7 @@ cglobal %1_h264_qpel16_h_lowpass_l2, 5, 6, 16 ; dst, src, src2, dstStride, src2S add r2, r4 dec r5d jg .loop - REP_RET + RET %endmacro INIT_XMM ssse3 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight.asm index 6076e64a..66353d1a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight.asm @@ -79,7 +79,7 @@ cglobal h264_weight_%1, 6, 6, %2 add r0, r1 dec r2d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -102,7 +102,7 @@ cglobal h264_weight_%1, 6, 6, %2 add r0, r3 dec r2d jnz .nextrow - REP_RET + RET %endmacro INIT_MMX mmxext @@ -196,7 +196,7 @@ cglobal h264_biweight_%1, 7, 8, %2 add r1, r2 dec r3d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -223,7 +223,7 @@ cglobal h264_biweight_%1, 7, 8, %2 add r1, r4 dec r3d jnz .nextrow - REP_RET + RET %endmacro INIT_MMX mmxext @@ -258,7 +258,7 @@ cglobal h264_biweight_16, 7, 8, 8 add r1, r2 dec r3d jnz .nextrow - REP_RET + RET INIT_XMM ssse3 cglobal h264_biweight_8, 7, 8, 8 @@ -281,4 +281,4 @@ cglobal h264_biweight_8, 7, 8, 8 add r1, r4 dec r3d jnz .nextrow - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight_10bit.asm index f924e558..356871bc 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/h264_weight_10bit.asm @@ -101,7 +101,7 @@ cglobal h264_weight_16_10 add r0, r1 dec r2d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -120,7 +120,7 @@ cglobal h264_weight_8_10 add r0, r1 dec r2d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -142,7 +142,7 @@ cglobal h264_weight_4_10 add r0, r3 dec r2d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -234,7 +234,7 @@ cglobal h264_biweight_16_10 add r1, r2 dec r3d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -253,7 +253,7 @@ cglobal h264_biweight_8_10 add r1, r2 dec r3d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -275,7 +275,7 @@ cglobal h264_biweight_4_10 add r1, r4 dec r3d jnz .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao.asm index 2eb8924d..8abb1615 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao.asm @@ -166,7 +166,7 @@ INIT_YMM cpuname add srcq, srcstrideq ; src += srcstride dec heightd ; cmp height jnz .loop ; height loop - REP_RET + RET %endmacro diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao_10bit.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao_10bit.asm index 38005740..0daa9c64 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao_10bit.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hevc_sao_10bit.asm @@ -145,7 +145,7 @@ align 16 add srcq, srcstrideq dec heightd jg .loop - REP_RET + RET %endmacro %macro HEVC_SAO_BAND_FILTER_FUNCS 0 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp.asm index b3a270a1..7a2b7135 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp.asm @@ -78,7 +78,7 @@ cglobal put_pixels8_x2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -120,7 +120,7 @@ cglobal put_pixels16_x2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -162,7 +162,7 @@ cglobal put_no_rnd_pixels8_x2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET ; void ff_put_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @@ -194,7 +194,7 @@ cglobal put_pixels8_y2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -232,7 +232,7 @@ cglobal put_no_rnd_pixels8_y2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET ; void ff_avg_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @@ -280,7 +280,7 @@ cglobal avg_pixels8_x2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -323,7 +323,7 @@ cglobal avg_pixels8_y2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -370,7 +370,7 @@ cglobal avg_approx_pixels8_xy2, 4,5 add r0, r4 sub r3d, 4 jne .loop - REP_RET + RET ; void ff_avg_pixels16_xy2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @@ -448,7 +448,7 @@ cglobal %1_pixels8_xy2, 4,5 add r4, r2 sub r3d, 2 jnz .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -514,7 +514,7 @@ cglobal %1_pixels8_xy2, 4,5 add r4, r2 sub r3d, 2 jnz .loop - REP_RET + RET %endmacro INIT_MMX ssse3 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp_vp3.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp_vp3.asm index 88ca8e8e..e580133e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp_vp3.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/hpeldsp_vp3.asm @@ -60,7 +60,7 @@ cglobal put_no_rnd_pixels8_x2_exact, 4,5 lea r0, [r0+r2*4] sub r3d, 4 jg .loop - REP_RET + RET ; void ff_put_no_rnd_pixels8_y2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) @@ -96,4 +96,4 @@ cglobal put_no_rnd_pixels8_y2_exact, 4,5 lea r0, [r0+r2*4] sub r3d, 4 jg .loop - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/huffyuvdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/huffyuvdsp.asm index c5c40e99..c1b375f4 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/huffyuvdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/huffyuvdsp.asm @@ -74,7 +74,7 @@ cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left jl .loop movd m0, [dstq-4] movd [leftq], m0 - REP_RET + RET ; void add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int mask, int w, int *left, int *left_top) diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/jpeg2000dsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/jpeg2000dsp.asm index 61dfdd4f..c61cc707 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/jpeg2000dsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/jpeg2000dsp.asm @@ -113,7 +113,7 @@ align 16 movaps [src1q+csizeq], m5 add csizeq, mmsize jl .loop - REP_RET + RET %endmacro INIT_XMM sse @@ -153,7 +153,7 @@ align 16 mova [src0q+csizeq], m2 add csizeq, mmsize jl .loop - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videodsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videodsp.asm index eb1b8050..7159aafe 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videodsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videodsp.asm @@ -229,7 +229,7 @@ cglobal add_bytes, 3,4,2, dst, src, w, size inc wq jl .3 .end: - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videoencdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videoencdsp.asm index c579891d..8ccaea91 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videoencdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/lossless_videoencdsp.asm @@ -110,7 +110,7 @@ cglobal diff_bytes, 4,5,2, dst, src1, src2, w inc wq jl .loop_gpr_%1%2 .end_%1%2: - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/me_cmp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/me_cmp.asm index eb036ee4..923eb807 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/me_cmp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/me_cmp.asm @@ -458,7 +458,7 @@ cglobal hf_noise%1, 3,3,0, pix1, lsize, h psrlq m6, 32 paddd m0, m6 movd eax, m0 ; eax = result of hf_noise8; - REP_RET ; return eax; + RET ; return eax; %endmacro INIT_MMX mmx diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/pngdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/pngdsp.asm index 7bc43c79..efaf652c 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/pngdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/pngdsp.asm @@ -75,7 +75,7 @@ cglobal add_bytes_l2, 4, 6, 2, dst, src1, src2, wa, w, i .end_s: cmp iq, wq jl .loop_s - REP_RET + RET %macro ADD_PAETH_PRED_FN 1 cglobal add_png_paeth_prediction, 5, 7, %1, dst, src, top, w, bpp, end, cntr diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpel.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpel.asm index 4e72d508..48125131 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpel.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpel.asm @@ -81,7 +81,7 @@ cglobal %1_pixels4_l2, 6,6 add r2, 16 sub r5d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -125,7 +125,7 @@ cglobal %1_pixels8_l2, 6,6 add r2, 32 sub r5d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -171,7 +171,7 @@ cglobal %1_pixels16_l2, 6,6 add r2, 32 sub r5d, 2 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpeldsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpeldsp.asm index 3a6a6506..30d26a5a 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpeldsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/qpeldsp.asm @@ -92,7 +92,7 @@ cglobal put_no_rnd_pixels8_l2, 6,6 add r2, 32 sub r5d, 4 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -161,7 +161,7 @@ cglobal put_no_rnd_pixels16_l2, 6,6 add r2, 32 sub r5d, 2 jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -274,7 +274,7 @@ cglobal %1_mpeg4_qpel16_h_lowpass, 5, 5, 0, 16 add r0, r2 dec r4d jne .loop - REP_RET + RET %endmacro %macro PUT_OP 2-3 @@ -357,7 +357,7 @@ cglobal %1_mpeg4_qpel8_h_lowpass, 5, 5, 0, 8 add r0, r2 dec r4d jne .loop - REP_RET + RET %endmacro INIT_MMX mmxext @@ -466,7 +466,7 @@ cglobal %1_mpeg4_qpel16_v_lowpass, 4, 6, 0, 544 add r0, r1 dec r4d jne .loopv - REP_RET + RET %endmacro %macro PUT_OPH 2-3 @@ -543,7 +543,7 @@ cglobal %1_mpeg4_qpel8_v_lowpass, 4, 6, 0, 288 add r0, r1 dec r4d jne .loopv - REP_RET + RET %endmacro INIT_MMX mmxext diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv34dsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv34dsp.asm index 0a3d99c5..f29bfd71 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv34dsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv34dsp.asm @@ -54,7 +54,7 @@ cglobal rv34_idct_dc_noround, 1, 2, 0 movq [r0+ 8], m0 movq [r0+16], m0 movq [r0+24], m0 - REP_RET + RET ; Load coeffs and perform row transform ; Output: coeffs in mm[0467], rounder in mm5 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv40dsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv40dsp.asm index f2ce236d..e02ad2c6 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv40dsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/rv40dsp.asm @@ -170,7 +170,7 @@ cglobal %1_rv40_qpel_v, 6,6+npicregs,12, dst, dststride, src, srcstride, height, add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %endmacro %macro FILTER_H 1 @@ -227,7 +227,7 @@ cglobal %1_rv40_qpel_h, 6, 6+npicregs, 12, dst, dststride, src, srcstride, heigh add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -280,7 +280,7 @@ cglobal %1_rv40_qpel_v, 6,6+npicregs,8, dst, dststride, src, srcstride, height, add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET cglobal %1_rv40_qpel_h, 6,6+npicregs,8, dst, dststride, src, srcstride, height, mx, picreg %ifdef PIC @@ -313,7 +313,7 @@ cglobal %1_rv40_qpel_h, 6,6+npicregs,8, dst, dststride, src, srcstride, height, add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %endmacro INIT_XMM ssse3 @@ -464,7 +464,7 @@ cglobal rv40_weight_func_%1_%2, 6, 7, 8 .loop: MAIN_LOOP %2, RND jnz .loop - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/sbrdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/sbrdsp.asm index 87dcdc43..d02f70d7 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/sbrdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/sbrdsp.asm @@ -208,7 +208,7 @@ cglobal sbr_sum64x5, 1,2,4,z add zq, 32 cmp zq, r1q jne .loop - REP_RET + RET INIT_XMM sse cglobal sbr_qmf_post_shuffle, 2,3,4,W,z @@ -227,7 +227,7 @@ cglobal sbr_qmf_post_shuffle, 2,3,4,W,z add zq, 16 cmp zq, r2q jl .loop - REP_RET + RET INIT_XMM sse cglobal sbr_neg_odd_64, 1,2,4,z @@ -248,7 +248,7 @@ cglobal sbr_neg_odd_64, 1,2,4,z add zq, 64 cmp zq, r1q jne .loop - REP_RET + RET ; void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1) INIT_XMM sse2 @@ -276,7 +276,7 @@ cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c add vrevq, 2*mmsize sub cq, 2*mmsize jge .loop - REP_RET + RET INIT_XMM sse2 cglobal sbr_qmf_pre_shuffle, 1,4,6,z @@ -306,7 +306,7 @@ cglobal sbr_qmf_pre_shuffle, 1,4,6,z jge .loop movq m2, [zq] movq [r2q], m2 - REP_RET + RET %ifdef PIC %define NREGS 1 @@ -432,7 +432,7 @@ cglobal sbr_qmf_deint_neg, 2,4,4,v,src,vrev,c sub vq, mmsize add cq, mmsize jl .loop - REP_RET + RET %macro SBR_AUTOCORRELATE 0 cglobal sbr_autocorrelate, 2,3,8,32, x, phi, cnt diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/takdsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/takdsp.asm index 5f3ded3e..be8e1ab5 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/takdsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/takdsp.asm @@ -43,7 +43,7 @@ cglobal tak_decorrelate_ls, 3, 3, 2, p1, p2, length mova [p2q+lengthq+mmsize*1], m1 add lengthq, mmsize*2 jl .loop - REP_RET + RET cglobal tak_decorrelate_sr, 3, 3, 2, p1, p2, length shl lengthd, 2 @@ -60,7 +60,7 @@ cglobal tak_decorrelate_sr, 3, 3, 2, p1, p2, length mova [p1q+lengthq+mmsize*1], m1 add lengthq, mmsize*2 jl .loop - REP_RET + RET cglobal tak_decorrelate_sm, 3, 3, 6, p1, p2, length shl lengthd, 2 @@ -87,7 +87,7 @@ cglobal tak_decorrelate_sm, 3, 3, 6, p1, p2, length mova [p2q+lengthq+mmsize], m4 add lengthq, mmsize*2 jl .loop - REP_RET + RET INIT_XMM sse4 cglobal tak_decorrelate_sf, 3, 3, 5, p1, p2, length, dshift, dfactor @@ -113,4 +113,4 @@ cglobal tak_decorrelate_sf, 3, 3, 5, p1, p2, length, dshift, dfactor mova [p1q+lengthq], m1 add lengthq, mmsize jl .loop - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/utvideodsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/utvideodsp.asm index b799c44b..9d54deeb 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/utvideodsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/utvideodsp.asm @@ -69,7 +69,7 @@ DEFINE_ARGS src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, x add src_bq, linesize_bq sub hd, 1 jg .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 @@ -125,7 +125,7 @@ DEFINE_ARGS src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, x add src_bq, linesize_bq sub hd, 1 jg .nextrow - REP_RET + RET %endmacro INIT_XMM sse2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210-init.c b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210-init.c index 5db1fef9..8b3677b8 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210-init.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210-init.c @@ -17,7 +17,7 @@ */ #include "libavutil/attributes.h" -#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" #include "libavcodec/v210dec.h" extern void ff_v210_planar_unpack_unaligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); @@ -28,6 +28,8 @@ extern void ff_v210_planar_unpack_aligned_ssse3(const uint32_t *src, uint16_t *y extern void ff_v210_planar_unpack_aligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); extern void ff_v210_planar_unpack_aligned_avx2(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_avx512icl(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + av_cold void ff_v210_x86_init(V210DecContext *s) { #if HAVE_X86ASM @@ -42,6 +44,9 @@ av_cold void ff_v210_x86_init(V210DecContext *s) if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) s->unpack_frame = ff_v210_planar_unpack_aligned_avx2; + + if (EXTERNAL_AVX512ICL(cpu_flags)) + s->unpack_frame = ff_v210_planar_unpack_avx512icl; } else { if (cpu_flags & AV_CPU_FLAG_SSSE3) @@ -52,6 +57,9 @@ av_cold void ff_v210_x86_init(V210DecContext *s) if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) s->unpack_frame = ff_v210_planar_unpack_unaligned_avx2; + + if (EXTERNAL_AVX512ICL(cpu_flags)) + s->unpack_frame = ff_v210_planar_unpack_avx512icl; } #endif } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210.asm index 3b9e0761..8ae59220 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210.asm @@ -22,7 +22,21 @@ %include "libavutil/x86/x86util.asm" -SECTION_RODATA 32 +SECTION_RODATA 64 + +perm_y: + db 0,1, 4,5, 6,7, 8,9, 12,13, 14,15, 16,17, 20,21 + db 22,23, 24,25, 28,29, 30,31, 32,33, 36,37, 38,39, 40,41 + db 44,45, 46,47, 48,49, 52,53, 54,55, 56,57, 60,61, 62,63 +times 16 db 0xff ; align to 64 + +perm_uv: + db 0,1, 4,5, 10,11, 16,17, 20,21, 26,27, 32,33, 36,37 + db 42,43, 48,49, 52,53, 58,59 +times 8 db 0xff ; align to 32 + db 2,3, 8,9, 12,13, 18,19, 24,25, 28,29, 34,35, 40,41 + db 44,45, 50,51, 56,57, 60,61 +times 8 db 0xff ; align to 32 ; for AVX2 version only v210_luma_permute: dd 0,1,2,4,5,6,7,7 ; 32-byte alignment required @@ -34,6 +48,9 @@ v210_mult: dw 64,4,64,4,64,4,64,4 v210_luma_shuf: db 8,9,0,1,2,3,12,13,4,5,6,7,-1,-1,-1,-1 v210_chroma_shuf: db 0,1,8,9,6,7,-1,-1,2,3,4,5,12,13,-1,-1 +shift: times 4 dw 6, 2 +kmask: dw 0x5555, 0xaaaa + SECTION .text %macro v210_planar_unpack 1 @@ -65,18 +82,18 @@ cglobal v210_planar_unpack_%1, 5, 5, 6 + 2 * cpuflag(avx2), src, y, u, v, w mova m0, [srcq] %endif - pmullw m1, m0, m3 - pslld m0, 12 - psrlw m1, 6 ; yB yA u5 v4 y8 y7 v3 u3 y5 y4 u2 v1 y2 y1 v0 u0 - psrld m0, 22 ; 00 v5 00 y9 00 u4 00 y6 00 v2 00 y3 00 u1 00 y0 + pmullw m1, m0, m3 ; shifts the 1st and 3rd sample of each dword into the high 10 bits of each word + pslld m0, 12 ; shifts the 2nd sample of each dword into the high 10 bits of each dword + psrlw m1, 6 ; shifts the 1st and 3rd samples back into the low 10 bits + psrld m0, 22 ; shifts the 2nd sample back into the low 10 bits of each dword %if cpuflag(avx2) - vpblendd m2, m1, m0, 0x55 ; yB yA 00 y9 y8 y7 00 y6 y5 y4 00 y3 y2 y1 00 y0 + vpblendd m2, m1, m0, 0x55 ; merge the odd dwords from m0 and even from m1 ; yB yA 00 y9 y8 y7 00 y6 y5 y4 00 y3 y2 y1 00 y0 pshufb m2, m4 ; 00 00 yB yA y9 y8 y7 y6 00 00 y5 y4 y3 y2 y1 y0 vpermd m2, m6, m2 ; 00 00 00 00 yB yA y9 y8 y7 y6 y5 y4 y3 y2 y1 y0 movu [yq+2*wq], m2 - vpblendd m1, m1, m0, 0xaa ; 00 v5 u5 v4 00 u4 v3 u3 00 v2 u2 v1 00 u1 v0 u0 + vpblendd m1, m1, m0, 0xaa ; merge the even dwords from m0 and odd from m1 ; 00 v5 u5 v4 00 u4 v3 u3 00 v2 u2 v1 00 u1 v0 u0 pshufb m1, m5 ; 00 v5 v4 v3 00 u5 u4 u3 00 v2 v1 v0 00 u2 u1 u0 vpermq m1, m1, 0xd8 ; 00 v5 v4 v3 00 v2 v1 v0 00 u5 u4 u3 00 u2 u1 u0 pshufb m1, m7 ; 00 00 v5 v4 v3 v2 v1 v0 00 00 u5 u4 u3 u2 u1 u0 @@ -99,7 +116,7 @@ cglobal v210_planar_unpack_%1, 5, 5, 6 + 2 * cpuflag(avx2), src, y, u, v, w add wq, (mmsize*3)/8 jl .loop - REP_RET + RET %endmacro INIT_XMM ssse3 @@ -127,3 +144,44 @@ v210_planar_unpack aligned INIT_YMM avx2 v210_planar_unpack aligned %endif + +%if HAVE_AVX512ICL_EXTERNAL + +INIT_ZMM avx512icl + +cglobal v210_planar_unpack, 5, 5, 6, src, y, u, v, w + movsxdifnidn wq, wd + lea yq, [yq+2*wq] + add uq, wq + add vq, wq + neg wq + + kmovw k1, [kmask] ; odd dword mask + kmovw k2, [kmask+2] ; even dword mask + + VBROADCASTI128 m0, [shift] + mova m1, [perm_y] + mova m2, [perm_uv] + + .loop: + movu m3, [srcq] + vpsllvw m4, m3, m0 + pslld m5, m3, 12 + psrlw m4, 6 + psrld m5, 22 + + vpblendmd m3{k1}, m4, m5 + vpermb m3, m1, m3 ; could use vpcompressw + movu [yq+2*wq], m3 + + vpblendmd m5{k2}, m4, m5 + vpermb m5, m2, m5 + movu [uq+wq], ym5 + vextracti32x8 [vq+wq], zm5, 1 + + add srcq, mmsize + add wq, (mmsize*3)/8 + jl .loop +RET + +%endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc.asm index afac238e..bbad1589 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc.asm @@ -56,13 +56,43 @@ v210enc_8_permd: dd 0,1,4,5, 1,2,5,6 v210enc_8_mult: db 4, 0, 64, 0 v210enc_8_mask: dd 255<<12 +icl_perm_y: ; vpermb does not set bytes to zero when the high bit is set unlike pshufb +%assign i 0 +%rep 8 + db -1,i+0,i+1,-1 , i+2,i+3,i+4,i+5 + %assign i i+6 +%endrep + +icl_perm_uv: ; vpermb does not set bytes to zero when the high bit is set unlike pshufb +%assign i 0 +%rep 4 + db i+0,i+1,i+32,i+33 , -1,i+2,i+3,-1 , i+34,i+35,i+4,i+5 , -1,i+36,i+37,-1 + %assign i i+6 +%endrep + +icl_perm_y_kmask: times 8 db 1111_0110b +icl_perm_uv_kmask: times 8 db 0110_1111b + +icl_shift_y: times 10 dw 2,0,4 + times 4 db 0 ; padding to 64 bytes +icl_shift_uv: times 5 dw 0,2,4 + times 2 db 0 ; padding to 32 bytes + times 5 dw 4,0,2 + times 2 db 0 ; padding to 32 bytes + +v210enc_10_permd_y: dd 0,1,2,-1 , 3,4,5,-1 +v210enc_10_shufb_y: db -1,0,1,-1 , 2,3,4,5 , -1,6,7,-1 , 8,9,10,11 +v210enc_10_permd_uv: dd 0,1,4,5 , 1,2,5,6 +v210enc_10_shufb_uv: db 0,1, 8, 9 , -1,2,3,-1 , 10,11,4,5 , -1,12,13,-1 + db 2,3,10,11 , -1,4,5,-1 , 12,13,6,7 , -1,14,15,-1 + SECTION .text %macro v210_planar_pack_10 0 ; v210_planar_pack_10(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width) cglobal v210_planar_pack_10, 5, 5, 4+cpuflag(avx2), y, u, v, dst, width - lea r0, [yq+2*widthq] + lea yq, [yq+2*widthq] add uq, widthq add vq, widthq neg widthq @@ -113,6 +143,75 @@ INIT_YMM avx2 v210_planar_pack_10 %endif +%macro v210_planar_pack_10_new 0 + +cglobal v210_planar_pack_10, 5, 5, 8+2*notcpuflag(avx512icl), y, u, v, dst, width + lea yq, [yq+2*widthq] + add uq, widthq + add vq, widthq + neg widthq + + %if cpuflag(avx512icl) + movu m6, [icl_perm_y] + movu m7, [icl_perm_uv] + kmovq k1, [icl_perm_y_kmask] + kmovq k2, [icl_perm_uv_kmask] + %else + movu m6, [v210enc_10_permd_y] + VBROADCASTI128 m7, [v210enc_10_shufb_y] + movu m8, [v210enc_10_permd_uv] + movu m9, [v210enc_10_shufb_uv] + %endif + movu m2, [icl_shift_y] + movu m3, [icl_shift_uv] + VBROADCASTI128 m4, [v210_enc_min_10] ; only ymm sized + VBROADCASTI128 m5, [v210_enc_max_10] ; only ymm sized + + .loop: + movu m0, [yq + widthq*2] + %if cpuflag(avx512icl) + movu ym1, [uq + widthq*1] + vinserti32x8 zm1, [vq + widthq*1], 1 + %else + movu xm1, [uq + widthq*1] + vinserti128 ym1, [vq + widthq*1], 1 + %endif + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + + vpsllvw m0, m2 + vpsllvw m1, m3 + %if cpuflag(avx512icl) + vpermb m0{k1}{z}, m6, m0 ; make space for uv where the k-mask sets to zero + vpermb m1{k2}{z}, m7, m1 ; interleave uv and make space for y where the k-mask sets to zero + %else + vpermd m0, m6, m0 + pshufb m0, m7 + vpermd m1, m8, m1 + pshufb m1, m9 + %endif + por m0, m1 + + movu [dstq], m0 + add dstq, mmsize + add widthq, (mmsize*3)/8 + jl .loop +RET + +%endmacro + +%if ARCH_X86_64 +%if HAVE_AVX512_EXTERNAL +INIT_YMM avx512 +v210_planar_pack_10_new +%endif +%endif + +%if HAVE_AVX512ICL_EXTERNAL +INIT_ZMM avx512icl +v210_planar_pack_10_new +%endif + %macro v210_planar_pack_8 0 ; v210_planar_pack_8(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width) @@ -215,7 +314,7 @@ cglobal v210_planar_pack_8, 5, 5, 7+notcpuflag(avx512icl), y, u, v, dst, width movu ym1, [yq + 2*widthq] vinserti32x4 m1, [uq + 1*widthq], 2 vinserti32x4 m1, [vq + 1*widthq], 3 - vpermb m1, m2, m1 ; uyv0 yuy0 vyu0 yvy0 + vpermb m1, m2, m1 ; uyvx yuyx vyux yvyx %else movq xm0, [uq + 1*widthq] ; uuuu uuxx movq xm1, [vq + 1*widthq] ; vvvv vvxx @@ -226,13 +325,12 @@ cglobal v210_planar_pack_8, 5, 5, 7+notcpuflag(avx512icl), y, u, v, dst, width %endif CLIPUB m1, m4, m5 - pmaddubsw m0, m1, m3 - pslld m1, 4 + pmaddubsw m0, m1, m3 ; shift high and low samples of each dword and mask out other bits + pslld m1, 4 ; shift center sample of each dword %if cpuflag(avx512) - vpternlogd m0, m1, m6, 0xd8 ; C?B:A + vpternlogd m0, m1, m6, 0xd8 ; C?B:A ; merge and mask out bad bits from B %else pand m1, m6, m1 - pandn m0, m6, m0 por m0, m0, m1 %endif diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc_init.c b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc_init.c index 6e9f8c6e..44f22ca7 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc_init.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/v210enc_init.c @@ -37,6 +37,12 @@ void ff_v210_planar_pack_10_ssse3(const uint16_t *y, const uint16_t *u, void ff_v210_planar_pack_10_avx2(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width); +void ff_v210_planar_pack_10_avx512(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); +void ff_v210_planar_pack_10_avx512icl(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); av_cold void ff_v210enc_init_x86(V210EncContext *s) { @@ -60,10 +66,16 @@ av_cold void ff_v210enc_init_x86(V210EncContext *s) if (EXTERNAL_AVX512(cpu_flags)) { s->sample_factor_8 = 2; s->pack_line_8 = ff_v210_planar_pack_8_avx512; +#if ARCH_X86_64 + s->sample_factor_10 = 2; + s->pack_line_10 = ff_v210_planar_pack_10_avx512; +#endif } if (EXTERNAL_AVX512ICL(cpu_flags)) { s->sample_factor_8 = 4; s->pack_line_8 = ff_v210_planar_pack_8_avx512icl; + s->sample_factor_10 = 4; + s->pack_line_10 = ff_v210_planar_pack_10_avx512icl; } } diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/vc1dsp_mc.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/vc1dsp_mc.asm index 0e6d87dd..c1b3ed1b 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/vc1dsp_mc.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/vc1dsp_mc.asm @@ -139,7 +139,7 @@ cglobal vc1_put_ver_16b_shift2, 4,7,0, dst, src, stride add dstq, 8 dec i jnz .loop - REP_RET + RET %undef rnd %undef shift %undef stride_neg2 diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/videodsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/videodsp.asm index b19a8300..3cc07878 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/videodsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/videodsp.asm @@ -433,4 +433,4 @@ cglobal prefetch, 3, 3, 0, buf, stride, h add bufq, strideq dec hd jg .loop - REP_RET + RET diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/x86/vp8dsp.asm b/arm/raspi/third_party/ffmpeg/libavcodec/x86/vp8dsp.asm index 33d488bf..6ac5a772 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/x86/vp8dsp.asm +++ b/arm/raspi/third_party/ffmpeg/libavcodec/x86/vp8dsp.asm @@ -200,7 +200,7 @@ cglobal put_vp8_epel%1_h6, 6, 6 + npicregs, 8, dst, dststride, src, srcstride, h add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET cglobal put_vp8_epel%1_h4, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg shl mxd, 4 @@ -230,7 +230,7 @@ cglobal put_vp8_epel%1_h4, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, h add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my shl myd, 4 @@ -268,7 +268,7 @@ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picr add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my lea myd, [myq*3] @@ -314,7 +314,7 @@ cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picr add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %endmacro INIT_MMX ssse3 @@ -368,7 +368,7 @@ cglobal put_vp8_epel4_h4, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, he add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET ; 4x4 block, H-only 6-tap filter INIT_MMX mmxext @@ -426,7 +426,7 @@ cglobal put_vp8_epel4_h6, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, he add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET INIT_XMM sse2 cglobal put_vp8_epel8_h4, 6, 6 + npicregs, 10, dst, dststride, src, srcstride, height, mx, picreg @@ -474,7 +474,7 @@ cglobal put_vp8_epel8_h4, 6, 6 + npicregs, 10, dst, dststride, src, srcstride, h add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET INIT_XMM sse2 cglobal put_vp8_epel8_h6, 6, 6 + npicregs, 14, dst, dststride, src, srcstride, height, mx, picreg @@ -537,7 +537,7 @@ cglobal put_vp8_epel8_h6, 6, 6 + npicregs, 14, dst, dststride, src, srcstride, h add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %macro FILTER_V 1 ; 4x4 block, V-only 4-tap filter @@ -590,7 +590,7 @@ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picr add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET ; 4x4 block, V-only 6-tap filter @@ -655,7 +655,7 @@ cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picr add srcq, srcstrideq dec heightd ; next row jg .nextrow - REP_RET + RET %endmacro INIT_MMX mmxext @@ -738,7 +738,7 @@ cglobal put_vp8_bilinear%1_v, 7, 7, 7, dst, dststride, src, srcstride, height, p lea srcq, [srcq+srcstrideq*2] sub heightd, 2 jg .nextrow - REP_RET + RET %if cpuflag(ssse3) cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride, height, mx, picreg @@ -815,7 +815,7 @@ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride lea srcq, [srcq+srcstrideq*2] sub heightd, 2 jg .nextrow - REP_RET + RET %endmacro INIT_MMX mmxext @@ -838,7 +838,7 @@ cglobal put_vp8_pixels8, 5, 5, 0, dst, dststride, src, srcstride, height lea dstq, [dstq+dststrideq*2] sub heightd, 2 jg .nextrow - REP_RET + RET INIT_XMM sse cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height @@ -851,7 +851,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height lea dstq, [dstq+dststrideq*2] sub heightd, 2 jg .nextrow - REP_RET + RET ;----------------------------------------------------------------------------- ; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/xbmenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/xbmenc.c index 664c6599..cd8b73af 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/xbmenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/xbmenc.c @@ -82,7 +82,7 @@ const FFCodec ff_xbm_encoder = { CODEC_LONG_NAME("XBM (X BitMap) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_XBM, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(xbm_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/xfaceenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/xfaceenc.c index 7125f1f0..4998d42e 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/xfaceenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/xfaceenc.c @@ -216,7 +216,7 @@ const FFCodec ff_xface_encoder = { CODEC_LONG_NAME("X-face image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_XFACE, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, .priv_data_size = sizeof(XFaceContext), FF_CODEC_ENCODE_CB(xface_encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/xwdenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/xwdenc.c index 6c588f3a..08554d86 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/xwdenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/xwdenc.c @@ -216,7 +216,7 @@ const FFCodec ff_xwd_encoder = { CODEC_LONG_NAME("XWD (X Window Dump) image"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_XWD, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, FF_CODEC_ENCODE_CB(xwd_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA, AV_PIX_FMT_RGBA, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/y41penc.c b/arm/raspi/third_party/ffmpeg/libavcodec/y41penc.c index d3ef88c2..e86769da 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/y41penc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/y41penc.c @@ -82,7 +82,7 @@ const FFCodec ff_y41p_encoder = { CODEC_LONG_NAME("Uncompressed YUV 4:1:1 12-bit"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_Y41P, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .init = y41p_encode_init, FF_CODEC_ENCODE_CB(y41p_encode_frame), .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/yuv4enc.c b/arm/raspi/third_party/ffmpeg/libavcodec/yuv4enc.c index 27e786dd..8123260d 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/yuv4enc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/yuv4enc.c @@ -64,7 +64,7 @@ const FFCodec ff_yuv4_encoder = { CODEC_LONG_NAME("Uncompressed packed 4:2:0"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_YUV4, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, FF_CODEC_ENCODE_CB(yuv4_encode_frame), }; diff --git a/arm/raspi/third_party/ffmpeg/libavcodec/zmbvenc.c b/arm/raspi/third_party/ffmpeg/libavcodec/zmbvenc.c index c12f783d..d2033056 100644 --- a/arm/raspi/third_party/ffmpeg/libavcodec/zmbvenc.c +++ b/arm/raspi/third_party/ffmpeg/libavcodec/zmbvenc.c @@ -416,7 +416,7 @@ const FFCodec ff_zmbv_encoder = { CODEC_LONG_NAME("Zip Motion Blocks Video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_ZMBV, - .p.capabilities = AV_CODEC_CAP_DR1, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(ZmbvEncContext), .init = encode_init, FF_CODEC_ENCODE_CB(encode_frame), diff --git a/arm/raspi/third_party/ffmpeg/libavutil/.gitignore b/arm/raspi/third_party/ffmpeg/libavutil/.gitignore new file mode 100644 index 00000000..4dc74667 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/.gitignore @@ -0,0 +1,2 @@ +/avconfig.h +/ffversion.h diff --git a/arm/raspi/third_party/ffmpeg/libavutil/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/Makefile new file mode 100644 index 00000000..29b06665 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/Makefile @@ -0,0 +1,282 @@ +NAME = avutil +DESC = FFmpeg utility library + +HEADERS = adler32.h \ + aes.h \ + aes_ctr.h \ + ambient_viewing_environment.h \ + attributes.h \ + audio_fifo.h \ + avassert.h \ + avstring.h \ + avutil.h \ + base64.h \ + blowfish.h \ + bprint.h \ + bswap.h \ + buffer.h \ + cast5.h \ + camellia.h \ + channel_layout.h \ + common.h \ + cpu.h \ + crc.h \ + csp.h \ + des.h \ + detection_bbox.h \ + dict.h \ + display.h \ + dovi_meta.h \ + downmix_info.h \ + encryption_info.h \ + error.h \ + eval.h \ + fifo.h \ + file.h \ + frame.h \ + hash.h \ + hdr_dynamic_metadata.h \ + hdr_dynamic_vivid_metadata.h \ + hmac.h \ + hwcontext.h \ + hwcontext_cuda.h \ + hwcontext_d3d11va.h \ + hwcontext_drm.h \ + hwcontext_dxva2.h \ + hwcontext_qsv.h \ + hwcontext_mediacodec.h \ + hwcontext_opencl.h \ + hwcontext_vaapi.h \ + hwcontext_videotoolbox.h \ + hwcontext_vdpau.h \ + hwcontext_vulkan.h \ + imgutils.h \ + intfloat.h \ + intreadwrite.h \ + lfg.h \ + log.h \ + lzo.h \ + macros.h \ + mathematics.h \ + mastering_display_metadata.h \ + md5.h \ + mem.h \ + motion_vector.h \ + murmur3.h \ + opt.h \ + parseutils.h \ + pixdesc.h \ + pixelutils.h \ + pixfmt.h \ + random_seed.h \ + rc4.h \ + rational.h \ + replaygain.h \ + ripemd.h \ + samplefmt.h \ + sha.h \ + sha512.h \ + spherical.h \ + stereo3d.h \ + threadmessage.h \ + time.h \ + timecode.h \ + timestamp.h \ + tree.h \ + twofish.h \ + uuid.h \ + version.h \ + video_enc_params.h \ + xtea.h \ + tea.h \ + tx.h \ + film_grain_params.h \ + +ARCH_HEADERS = bswap.h \ + intmath.h \ + intreadwrite.h \ + timer.h \ + +BUILT_HEADERS = avconfig.h \ + ffversion.h + +OBJS = adler32.o \ + aes.o \ + aes_ctr.o \ + ambient_viewing_environment.o \ + audio_fifo.o \ + avstring.o \ + avsscanf.o \ + base64.o \ + blowfish.o \ + bprint.o \ + buffer.o \ + cast5.o \ + camellia.o \ + channel_layout.o \ + color_utils.o \ + cpu.o \ + crc.o \ + csp.o \ + des.o \ + detection_bbox.o \ + dict.o \ + display.o \ + dovi_meta.o \ + downmix_info.o \ + encryption_info.o \ + error.o \ + eval.o \ + fifo.o \ + file.o \ + file_open.o \ + float_dsp.o \ + fixed_dsp.o \ + frame.o \ + hash.o \ + hdr_dynamic_metadata.o \ + hdr_dynamic_vivid_metadata.o \ + hmac.o \ + hwcontext.o \ + imgutils.o \ + integer.o \ + intmath.o \ + lfg.o \ + lls.o \ + log.o \ + log2_tab.o \ + lzo.o \ + mathematics.o \ + mastering_display_metadata.o \ + md5.o \ + mem.o \ + murmur3.o \ + opt.o \ + parseutils.o \ + pixdesc.o \ + pixelutils.o \ + random_seed.o \ + rational.o \ + reverse.o \ + rc4.o \ + ripemd.o \ + samplefmt.o \ + sha.o \ + sha512.o \ + slicethread.o \ + spherical.o \ + stereo3d.o \ + threadmessage.o \ + time.o \ + timecode.o \ + tree.o \ + twofish.o \ + utils.o \ + xga_font_data.o \ + xtea.o \ + tea.o \ + tx.o \ + tx_float.o \ + tx_double.o \ + tx_int32.o \ + uuid.o \ + version.o \ + video_enc_params.o \ + film_grain_params.o \ + + +OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o +OBJS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.o +OBJS-$(CONFIG_DXVA2) += hwcontext_dxva2.o +OBJS-$(CONFIG_LIBDRM) += hwcontext_drm.o +OBJS-$(CONFIG_MACOS_KPERF) += macos_kperf.o +OBJS-$(CONFIG_MEDIACODEC) += hwcontext_mediacodec.o +OBJS-$(CONFIG_OPENCL) += hwcontext_opencl.o +OBJS-$(CONFIG_QSV) += hwcontext_qsv.o +OBJS-$(CONFIG_VAAPI) += hwcontext_vaapi.o +OBJS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.o +OBJS-$(CONFIG_VDPAU) += hwcontext_vdpau.o +OBJS-$(CONFIG_VULKAN) += hwcontext_vulkan.o + +OBJS-$(!CONFIG_VULKAN) += hwcontext_stub.o + +OBJS += $(COMPAT_OBJS:%=../compat/%) + +# Windows resource file +SHLIBOBJS-$(HAVE_GNU_WINDRES) += avutilres.o + +SKIPHEADERS += objc.h +SKIPHEADERS-$(HAVE_CUDA_H) += hwcontext_cuda.h +SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda_internal.h \ + cuda_check.h +SKIPHEADERS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.h +SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h +SKIPHEADERS-$(CONFIG_QSV) += hwcontext_qsv.h +SKIPHEADERS-$(CONFIG_OPENCL) += hwcontext_opencl.h +SKIPHEADERS-$(CONFIG_VAAPI) += hwcontext_vaapi.h +SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.h +SKIPHEADERS-$(CONFIG_VDPAU) += hwcontext_vdpau.h +SKIPHEADERS-$(CONFIG_VULKAN) += hwcontext_vulkan.h vulkan.h \ + vulkan_functions.h \ + vulkan_loader.h + +TESTPROGS = adler32 \ + aes \ + aes_ctr \ + audio_fifo \ + avstring \ + base64 \ + blowfish \ + bprint \ + cast5 \ + camellia \ + channel_layout \ + color_utils \ + cpu \ + crc \ + des \ + dict \ + display \ + encryption_info \ + error \ + eval \ + file \ + fifo \ + hash \ + hmac \ + hwdevice \ + integer \ + imgutils \ + lfg \ + lls \ + log \ + md5 \ + murmur3 \ + opt \ + pca \ + parseutils \ + pixdesc \ + pixelutils \ + pixfmt_best \ + random_seed \ + rational \ + ripemd \ + sha \ + sha512 \ + softfloat \ + tree \ + twofish \ + utf8 \ + uuid \ + xtea \ + tea \ + +TESTPROGS-$(HAVE_THREADS) += cpu_init +TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo + +TOOLS = crypto_bench ffhash ffeval ffescape + +tools/crypto_bench$(EXESUF): ELIBS += $(if $(VERSUS),$(subst +, -l,+$(VERSUS)),) +tools/crypto_bench.o: CFLAGS += -DUSE_EXT_LIBS=0$(if $(VERSUS),$(subst +,+USE_,+$(VERSUS)),) + +$(SUBDIR)tests/lzo$(EXESUF): ELIBS = -llzo2 diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/Makefile new file mode 100644 index 00000000..eba01513 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/Makefile @@ -0,0 +1,6 @@ +OBJS += aarch64/cpu.o \ + aarch64/float_dsp_init.o \ + aarch64/tx_float_init.o \ + +NEON-OBJS += aarch64/float_dsp_neon.o \ + aarch64/tx_float_neon.o \ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/asm.S b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/asm.S new file mode 100644 index 00000000..d8f78640 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/asm.S @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#ifdef __ELF__ +# define ELF +#else +# define ELF # +#endif + +#ifdef __MACH__ +# define MACH +#else +# define MACH # +#endif + +#if HAVE_AS_FUNC +# define FUNC +#else +# define FUNC # +#endif + +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + + +/* Support macros for + * - Armv8.3-A Pointer Authentication and + * - Armv8.5-A Branch Target Identification + * features which require emitting a .note.gnu.property section with the + * appropriate architecture-dependent feature bits set. + * + * |AARCH64_SIGN_LINK_REGISTER| and |AARCH64_VALIDATE_LINK_REGISTER| expand to + * PACIxSP and AUTIxSP, respectively. |AARCH64_SIGN_LINK_REGISTER| should be + * used immediately before saving the LR register (x30) to the stack. + * |AARCH64_VALIDATE_LINK_REGISTER| should be used immediately after restoring + * it. Note |AARCH64_SIGN_LINK_REGISTER|'s modifications to LR must be undone + * with |AARCH64_VALIDATE_LINK_REGISTER| before RET. The SP register must also + * have the same value at the two points. For example: + * + * .global f + * f: + * AARCH64_SIGN_LINK_REGISTER + * stp x29, x30, [sp, #-96]! + * mov x29, sp + * ... + * ldp x29, x30, [sp], #96 + * AARCH64_VALIDATE_LINK_REGISTER + * ret + * + * |AARCH64_VALID_CALL_TARGET| expands to BTI 'c'. Either it, or + * |AARCH64_SIGN_LINK_REGISTER|, must be used at every point that may be an + * indirect call target. In particular, all symbols exported from a file must + * begin with one of these macros. For example, a leaf function that does not + * save LR can instead use |AARCH64_VALID_CALL_TARGET|: + * + * .globl return_zero + * return_zero: + * AARCH64_VALID_CALL_TARGET + * mov x0, #0 + * ret + * + * A non-leaf function which does not immediately save LR may need both macros + * because |AARCH64_SIGN_LINK_REGISTER| appears late. For example, the function + * may jump to an alternate implementation before setting up the stack: + * + * .globl with_early_jump + * with_early_jump: + * AARCH64_VALID_CALL_TARGET + * cmp x0, #128 + * b.lt .Lwith_early_jump_128 + * AARCH64_SIGN_LINK_REGISTER + * stp x29, x30, [sp, #-96]! + * mov x29, sp + * ... + * ldp x29, x30, [sp], #96 + * AARCH64_VALIDATE_LINK_REGISTER + * ret + * + * .Lwith_early_jump_128: + * ... + * ret + * + * These annotations are only required with indirect calls. Private symbols that + * are only the target of direct calls do not require annotations. Also note + * that |AARCH64_VALID_CALL_TARGET| is only valid for indirect calls (BLR), not + * indirect jumps (BR). Indirect jumps in assembly are supported through + * |AARCH64_VALID_JUMP_TARGET|. Landing Pads which shall serve for jumps and + * calls can be created using |AARCH64_VALID_JUMP_CALL_TARGET|. + * + * Although not necessary, it is safe to use these macros in 32-bit ARM + * assembly. This may be used to simplify dual 32-bit and 64-bit files. + * + * References: + * - "ELF for the Arm® 64-bit Architecture" + * https: *github.com/ARM-software/abi-aa/blob/master/aaelf64/aaelf64.rst + * - "Providing protection for complex software" + * https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software + */ +#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) +# define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has BTI +# define AARCH64_VALID_CALL_TARGET hint #34 // BTI 'c' +# define AARCH64_VALID_JUMP_TARGET hint #38 // BTI 'j' +#else +# define GNU_PROPERTY_AARCH64_BTI 0 // No BTI +# define AARCH64_VALID_CALL_TARGET +# define AARCH64_VALID_JUMP_TARGET +#endif + +#if defined(__ARM_FEATURE_PAC_DEFAULT) +# if ((__ARM_FEATURE_PAC_DEFAULT & (1 << 0)) != 0) // authentication using key A +# define AARCH64_SIGN_LINK_REGISTER paciasp +# define AARCH64_VALIDATE_LINK_REGISTER autiasp +# elif ((__ARM_FEATURE_PAC_DEFAULT & (1 << 1)) != 0) // authentication using key B +# define AARCH64_SIGN_LINK_REGISTER pacibsp +# define AARCH64_VALIDATE_LINK_REGISTER autibsp +# else +# error Pointer authentication defines no valid key! +# endif +# if ((__ARM_FEATURE_PAC_DEFAULT & (1 << 2)) != 0) +# error Authentication of leaf functions is enabled but not supported in FFmpeg! +# endif +# define GNU_PROPERTY_AARCH64_PAC (1 << 1) +#else +# define GNU_PROPERTY_AARCH64_PAC 0 +# define AARCH64_SIGN_LINK_REGISTER +# define AARCH64_VALIDATE_LINK_REGISTER +#endif + + +#if (GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_PAC != 0) && defined(__ELF__) + .pushsection .note.gnu.property, "a" + .balign 8 + .long 4 + .long 0x10 + .long 0x5 + .asciz "GNU" + .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ + .long 4 + .long (GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_PAC) + .long 0 + .popsection +#endif + +.macro function name, export=0, align=2 + .macro endfunc +ELF .size \name, . - \name +FUNC .endfunc + .purgem endfunc + .endm + .text + .align \align + .if \export + .global EXTERN_ASM\name +ELF .type EXTERN_ASM\name, %function +// Chromium patch to ensure symbols are correctly hidden. +ELF .hidden EXTERN_ASM\name +MACH .private_extern EXTERN_ASM\name +FUNC .func EXTERN_ASM\name +EXTERN_ASM\name: + AARCH64_VALID_CALL_TARGET + .else +ELF .type \name, %function +FUNC .func \name +\name: + .endif +.endm + +.macro const name, align=2, relocate=0 + .macro endconst +ELF .size \name, . - \name + .purgem endconst + .endm +#if HAVE_SECTION_DATA_REL_RO +.if \relocate + .section .data.rel.ro +.else + .section .rodata +.endif +#elif defined(_WIN32) + .section .rdata +#elif !defined(__MACH__) + .section .rodata +#else + .const_data +#endif + .align \align +\name: +.endm + +.macro movrel rd, val, offset=0 +#if CONFIG_PIC && defined(__APPLE__) + .if \offset < 0 + adrp \rd, \val@PAGE + add \rd, \rd, \val@PAGEOFF + sub \rd, \rd, -(\offset) + .else + adrp \rd, \val+(\offset)@PAGE + add \rd, \rd, \val+(\offset)@PAGEOFF + .endif +#elif CONFIG_PIC && defined(_WIN32) + .if \offset < 0 + adrp \rd, \val + add \rd, \rd, :lo12:\val + sub \rd, \rd, -(\offset) + .else + adrp \rd, \val+(\offset) + add \rd, \rd, :lo12:\val+(\offset) + .endif +#elif CONFIG_PIC +# if __has_feature(hwaddress_sanitizer) + adrp \rd, :pg_hi21_nc:\val+(\offset) +# else + adrp \rd, \val+(\offset) +# endif + add \rd, \rd, :lo12:\val+(\offset) +#else + ldr \rd, =\val+\offset +#endif +.endm + +#define GLUE(a, b) a ## b +#define JOIN(a, b) GLUE(a, b) +#define X(s) JOIN(EXTERN_ASM, s) + +#define x18 do_not_use_x18 +#define w18 do_not_use_w18 diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/autorename_libavutil_aarch64_float_dsp_neon.S b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/autorename_libavutil_aarch64_float_dsp_neon.S new file mode 100644 index 00000000..9edc48b8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/autorename_libavutil_aarch64_float_dsp_neon.S @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "float_dsp_neon.S" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/bswap.h new file mode 100644 index 00000000..7abca657 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/bswap.h @@ -0,0 +1,56 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_BSWAP_H +#define AVUTIL_AARCH64_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_INLINE_ASM + +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + unsigned y; + + __asm__("rev16 %w0, %w1" : "=r"(y) : "r"(x)); + return y; +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + uint32_t y; + + __asm__("rev %w0, %w1" : "=r"(y) : "r"(x)); + return y; +} + +#define av_bswap64 av_bswap64 +static av_always_inline av_const uint64_t av_bswap64(uint64_t x) +{ + uint64_t y; + + __asm__("rev %0, %1" : "=r"(y) : "r"(x)); + return y; +} + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVUTIL_AARCH64_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.c new file mode 100644 index 00000000..cc641da5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.c @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "config.h" + +int ff_get_cpu_flags_aarch64(void) +{ + return AV_CPU_FLAG_ARMV8 * HAVE_ARMV8 | + AV_CPU_FLAG_NEON * HAVE_NEON | + AV_CPU_FLAG_VFP * HAVE_VFP; +} + +size_t ff_get_cpu_max_align_aarch64(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.h new file mode 100644 index 00000000..2ee3f932 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/cpu.h @@ -0,0 +1,29 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_CPU_H +#define AVUTIL_AARCH64_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_armv8(flags) CPUEXT(flags, ARMV8) +#define have_neon(flags) CPUEXT(flags, NEON) +#define have_vfp(flags) CPUEXT(flags, VFP) + +#endif /* AVUTIL_AARCH64_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_init.c new file mode 100644 index 00000000..43250718 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_init.c @@ -0,0 +1,69 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" + +void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_dmul_scalar_neon(double *dst, const double *src, double mul, + int len); + +void ff_vector_fmul_window_neon(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_neon(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_neon(float *v1, float *v2, int len); + +float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); + +av_cold void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + fdsp->butterflies_float = ff_butterflies_float_neon; + fdsp->scalarproduct_float = ff_scalarproduct_float_neon; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_neon; + fdsp->vector_fmul = ff_vector_fmul_neon; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; + fdsp->vector_fmul_add = ff_vector_fmul_add_neon; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; + fdsp->vector_fmul_window = ff_vector_fmul_window_neon; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_neon.S b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_neon.S new file mode 100644 index 00000000..02d790c0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/float_dsp_neon.S @@ -0,0 +1,202 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * Copyright (c) 2014 Janne Grunau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "asm.S" + +function ff_vector_fmul_neon, export=1 +1: subs w3, w3, #16 + ld1 {v0.4S, v1.4S}, [x1], #32 + ld1 {v2.4S, v3.4S}, [x1], #32 + ld1 {v4.4S, v5.4S}, [x2], #32 + ld1 {v6.4S, v7.4S}, [x2], #32 + fmul v16.4S, v0.4S, v4.4S + fmul v17.4S, v1.4S, v5.4S + fmul v18.4S, v2.4S, v6.4S + fmul v19.4S, v3.4S, v7.4S + st1 {v16.4S, v17.4S}, [x0], #32 + st1 {v18.4S, v19.4S}, [x0], #32 + b.ne 1b + ret +endfunc + +function ff_vector_fmac_scalar_neon, export=1 + mov x3, #-32 +1: subs w2, w2, #16 + ld1 {v16.4S, v17.4S}, [x0], #32 + ld1 {v18.4S, v19.4S}, [x0], x3 + ld1 {v4.4S, v5.4S}, [x1], #32 + ld1 {v6.4S, v7.4S}, [x1], #32 + fmla v16.4S, v4.4S, v0.S[0] + fmla v17.4S, v5.4S, v0.S[0] + fmla v18.4S, v6.4S, v0.S[0] + fmla v19.4S, v7.4S, v0.S[0] + st1 {v16.4S, v17.4S}, [x0], #32 + st1 {v18.4S, v19.4S}, [x0], #32 + b.ne 1b + ret +endfunc + +function ff_vector_fmul_scalar_neon, export=1 + mov w4, #15 + bics w3, w2, w4 + dup v16.4S, v0.S[0] + b.eq 3f + ld1 {v0.4S, v1.4S}, [x1], #32 +1: subs w3, w3, #16 + fmul v0.4S, v0.4S, v16.4S + ld1 {v2.4S, v3.4S}, [x1], #32 + fmul v1.4S, v1.4S, v16.4S + fmul v2.4S, v2.4S, v16.4S + st1 {v0.4S, v1.4S}, [x0], #32 + fmul v3.4S, v3.4S, v16.4S + b.eq 2f + ld1 {v0.4S, v1.4S}, [x1], #32 + st1 {v2.4S, v3.4S}, [x0], #32 + b 1b +2: ands w2, w2, #15 + st1 {v2.4S, v3.4S}, [x0], #32 + b.eq 4f +3: ld1 {v0.4S}, [x1], #16 + fmul v0.4S, v0.4S, v16.4S + st1 {v0.4S}, [x0], #16 + subs w2, w2, #4 + b.gt 3b +4: ret +endfunc + +function ff_vector_dmul_scalar_neon, export=1 + dup v16.2D, v0.D[0] + ld1 {v0.2D, v1.2D}, [x1], #32 +1: subs w2, w2, #8 + fmul v0.2D, v0.2D, v16.2D + ld1 {v2.2D, v3.2D}, [x1], #32 + fmul v1.2D, v1.2D, v16.2D + fmul v2.2D, v2.2D, v16.2D + st1 {v0.2D, v1.2D}, [x0], #32 + fmul v3.2D, v3.2D, v16.2D + ld1 {v0.2D, v1.2D}, [x1], #32 + st1 {v2.2D, v3.2D}, [x0], #32 + b.gt 1b + ret +endfunc + +function ff_vector_fmul_window_neon, export=1 + sxtw x4, w4 // len + sub x2, x2, #8 + sub x5, x4, #2 + add x2, x2, x5, lsl #2 // src1 + 4 * (len - 4) + add x6, x3, x5, lsl #3 // win + 8 * (len - 2) + add x5, x0, x5, lsl #3 // dst + 8 * (len - 2) + mov x7, #-16 + ld1 {v0.4S}, [x1], #16 // s0 + ld1 {v2.4S}, [x3], #16 // wi + ld1 {v1.4S}, [x2], x7 // s1 +1: ld1 {v3.4S}, [x6], x7 // wj + subs x4, x4, #4 + fmul v17.4S, v0.4S, v2.4S // s0 * wi + rev64 v4.4S, v1.4S + rev64 v5.4S, v3.4S + rev64 v17.4S, v17.4S + ext v4.16B, v4.16B, v4.16B, #8 // s1_r + ext v5.16B, v5.16B, v5.16B, #8 // wj_r + ext v17.16B, v17.16B, v17.16B, #8 // (s0 * wi)_rev + fmul v16.4S, v0.4S, v5.4S // s0 * wj_r + fmla v17.4S, v1.4S, v3.4S // (s0 * wi)_rev + s1 * wj + b.eq 2f + ld1 {v0.4S}, [x1], #16 + fmls v16.4S, v4.4S, v2.4S // s0 * wj_r - s1_r * wi + st1 {v17.4S}, [x5], x7 + ld1 {v2.4S}, [x3], #16 + ld1 {v1.4S}, [x2], x7 + st1 {v16.4S}, [x0], #16 + b 1b +2: + fmls v16.4S, v4.4S, v2.4S // s0 * wj_r - s1_r * wi + st1 {v17.4S}, [x5], x7 + st1 {v16.4S}, [x0], #16 + ret +endfunc + +function ff_vector_fmul_add_neon, export=1 + ld1 {v0.4S, v1.4S}, [x1], #32 + ld1 {v2.4S, v3.4S}, [x2], #32 + ld1 {v4.4S, v5.4S}, [x3], #32 +1: subs w4, w4, #8 + fmla v4.4S, v0.4S, v2.4S + fmla v5.4S, v1.4S, v3.4S + b.eq 2f + ld1 {v0.4S, v1.4S}, [x1], #32 + ld1 {v2.4S, v3.4S}, [x2], #32 + st1 {v4.4S, v5.4S}, [x0], #32 + ld1 {v4.4S, v5.4S}, [x3], #32 + b 1b +2: st1 {v4.4S, v5.4S}, [x0], #32 + ret +endfunc + +function ff_vector_fmul_reverse_neon, export=1 + sxtw x3, w3 + add x2, x2, x3, lsl #2 + sub x2, x2, #32 + mov x4, #-32 + ld1 {v2.4S, v3.4S}, [x2], x4 + ld1 {v0.4S, v1.4S}, [x1], #32 +1: subs x3, x3, #8 + rev64 v3.4S, v3.4S + rev64 v2.4S, v2.4S + ext v3.16B, v3.16B, v3.16B, #8 + ext v2.16B, v2.16B, v2.16B, #8 + fmul v16.4S, v0.4S, v3.4S + fmul v17.4S, v1.4S, v2.4S + b.eq 2f + ld1 {v2.4S, v3.4S}, [x2], x4 + ld1 {v0.4S, v1.4S}, [x1], #32 + st1 {v16.4S, v17.4S}, [x0], #32 + b 1b +2: st1 {v16.4S, v17.4S}, [x0], #32 + ret +endfunc + +function ff_butterflies_float_neon, export=1 +1: ld1 {v0.4S}, [x0] + ld1 {v1.4S}, [x1] + subs w2, w2, #4 + fsub v2.4S, v0.4S, v1.4S + fadd v3.4S, v0.4S, v1.4S + st1 {v2.4S}, [x1], #16 + st1 {v3.4S}, [x0], #16 + b.gt 1b + ret +endfunc + +function ff_scalarproduct_float_neon, export=1 + movi v2.4S, #0 +1: ld1 {v0.4S}, [x0], #16 + ld1 {v1.4S}, [x1], #16 + subs w2, w2, #4 + fmla v2.4S, v0.4S, v1.4S + b.gt 1b + faddp v0.4S, v2.4S, v2.4S + faddp s0, v0.2S + ret +endfunc diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/neontest.h b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/neontest.h new file mode 100644 index 00000000..2d0fc199 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/neontest.h @@ -0,0 +1,70 @@ +/* + * check NEON registers for clobbering + * Copyright (c) 2008 Ramiro Polla + * Copyright (c) 2013 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_NEONTEST_H +#define AVUTIL_AARCH64_NEONTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storeneonregs(mem) \ + __asm__ volatile( \ + "stp d8, d9, [%0]\n\t" \ + "stp d10, d11, [%0, #16]\n\t" \ + "stp d12, d13, [%0, #32]\n\t" \ + "stp d14, d15, [%0, #48]\n\t" \ + :: "r"(mem) : "memory") + +#define testneonclobbers(func, ctx, ...) \ + uint64_t neon[2][8]; \ + int ret; \ + storeneonregs(neon[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storeneonregs(neon[1]); \ + if (memcmp(neon[0], neon[1], sizeof(neon[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "NEON REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 8; i ++) \ + if (neon[0][i] != neon[1][i]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "d%-2d = %016"PRIx64"\n", \ + 8 + i, av_bswap64(neon[0][i])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"\n", \ + av_bswap64(neon[1][i])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_AARCH64_NEONTEST_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/timer.h new file mode 100644 index 00000000..8b28fd35 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/timer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015 Janne Grunau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_TIMER_H +#define AVUTIL_AARCH64_TIMER_H + +#include +#include "config.h" + +#if defined(__APPLE__) + +#include + +#define AV_READ_TIME mach_absolute_time + +#elif HAVE_INLINE_ASM + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint64_t cycle_counter; + __asm__ volatile( + "isb \t\n" + "mrs %0, pmccntr_el0 " + : "=r"(cycle_counter) :: "memory" ); + + return cycle_counter; +} + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_AARCH64_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_init.c b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_init.c new file mode 100644 index 00000000..8300472c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_init.c @@ -0,0 +1,64 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TX_FLOAT +#include "libavutil/tx_priv.h" +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" + +TX_DECL_FN(fft2, neon) +TX_DECL_FN(fft4_fwd, neon) +TX_DECL_FN(fft4_inv, neon) +TX_DECL_FN(fft8, neon) +TX_DECL_FN(fft8_ns, neon) +TX_DECL_FN(fft16, neon) +TX_DECL_FN(fft16_ns, neon) +TX_DECL_FN(fft32, neon) +TX_DECL_FN(fft32_ns, neon) +TX_DECL_FN(fft_sr, neon) +TX_DECL_FN(fft_sr_ns, neon) + +static av_cold int neon_init(AVTXContext *s, const FFTXCodelet *cd, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale) +{ + ff_tx_init_tabs_float(len); + if (cd->max_len == 2) + return ff_tx_gen_ptwo_revtab(s, opts); + else + return ff_tx_gen_split_radix_parity_revtab(s, len, inv, opts, 8, 0); +} + +const FFTXCodelet * const ff_tx_codelet_list_float_aarch64[] = { + TX_DEF(fft2, FFT, 2, 2, 2, 0, 128, NULL, neon, NEON, AV_TX_INPLACE, 0), + TX_DEF(fft2, FFT, 2, 2, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 128, NULL, neon, NEON, AV_TX_INPLACE | FF_TX_FORWARD_ONLY, 0), + TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft4_inv, FFT, 4, 4, 2, 0, 128, NULL, neon, NEON, AV_TX_INPLACE | FF_TX_INVERSE_ONLY, 0), + TX_DEF(fft8, FFT, 8, 8, 2, 0, 128, neon_init, neon, NEON, AV_TX_INPLACE, 0), + TX_DEF(fft8_ns, FFT, 8, 8, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft16, FFT, 16, 16, 2, 0, 128, neon_init, neon, NEON, AV_TX_INPLACE, 0), + TX_DEF(fft16_ns, FFT, 16, 16, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft32, FFT, 32, 32, 2, 0, 128, neon_init, neon, NEON, AV_TX_INPLACE, 0), + TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + + TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 128, neon_init, neon, NEON, 0, 0), + TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 192, neon_init, neon, NEON, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + + NULL, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_neon.S b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_neon.S new file mode 100644 index 00000000..e5531dcc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aarch64/tx_float_neon.S @@ -0,0 +1,1294 @@ +/* + * Copyright (c) Lynne + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/aarch64/asm.S" + +/* Open `doc/transforms.md` to see the code upon which the transforms here were + * based upon. + * + * File conventions: + * GPRs: x0-x3 - arguments, untouched + * x4 - Lookup table base pointer + * x5-x6 - macro ld1 temps/function scratch + * x7-x9 - FFT table state + * x10-x17 - lookup table/macro scratch + * w19-w20 - current/target length when needed + * x21-x22 - len*2, len*6 + * + * Vectors: v0-v7 - coefficients + * v8-v15 - coefficients when needed, otherwise untouched + * v16-v30 - used as needed + * v31 - -1.0, +1.0, -1.0, +1.0. Never touched after loading. + * + * Stack: backup for v8-v15 and x19-x22 when needed, and transform lengths + */ + +#define M_SQRT1_2 0.707106781186547524401 +#define COS16_1 0.92387950420379638671875 +#define COS16_3 0.3826834261417388916015625 + +/* We only ever load this once at the start, and then live with losing an + * entire register as we need to lug this all the time everywhere. + * Clearly should be integrated into an fsadd and fmlsa, but "muh RISC!". */ +const subadd, align=4 + .float -1.0, 1.0, -1.0, 1.0 +endconst + +.macro LOAD_SUBADD + movrel x5, subadd + ld1 { v31.4s }, [x5] +.endm + +.macro SETUP_LUT no_lut=0 +.if \no_lut == 0 + ldr x4, [x0, #8] +.endif +.endm + +.macro LOAD_INPUT dst1, dst2, dst3, dst4, src, no_lut=0, discont=0 +.if \no_lut == 1 +.if \discont == 1 + ldp q\dst1\(), q\dst2\(), [\src\()] + ldp q\dst3\(), q\dst4\(), [\src\(), #32] + add \src\(), \src\(), #64 +.else + ld1 { v\dst1\().4s, v\dst2\().4s, v\dst3\().4s, v\dst4\().4s }, [\src], #64 +.endif +.else + ldp w10, w11, [x4, #0 ] + ldp w12, w13, [x4, #8 ] + ldp w14, w15, [x4, #16] + ldp w16, w17, [x4, #24] + + add x4, x4, #32 + + ldr d\dst1, [\src, x10, lsl #3] + add x11, \src, x11, lsl #3 + ldr d\dst2, [\src, x12, lsl #3] + add x13, \src, x13, lsl #3 + ldr d\dst3, [\src, x14, lsl #3] + add x15, \src, x15, lsl #3 + ldr d\dst4, [\src, x16, lsl #3] + add x17, \src, x17, lsl #3 + + ld1 { v\dst1\().d }[1], [x11] + ld1 { v\dst2\().d }[1], [x13] + ld1 { v\dst3\().d }[1], [x15] + ld1 { v\dst4\().d }[1], [x17] +.endif +.endm + +.macro FFT4 e0, o0, standalone + fadd v16.4s, \e0\().4s, \o0\().4s // r1..4 + fsub \e0\().4s, \e0\().4s, \o0\().4s // t1..4 + + rev64 v18.4s, \e0\().4s + + zip2 \o0\().2d, v16.2d, \e0\().2d + zip1 v17.2d, v16.2d, \e0\().2d + + mov \o0\().d[1], v18.d[1] + + fadd \e0\().4s, v17.4s, \o0\().4s // a1,2 b1,4 + fsub v16.4s, v17.4s, \o0\().4s // a3,4 b3,2 + + mov \o0\().16b, v16.16b // Swap once again... + mov \o0\().s[3], \e0\().s[3] + mov \e0\().s[3], v16.s[3] + +.if \standalone == 0 + uzp2 \o0\().2d, \e0\().2d, \o0\().2d + uzp1 \e0\().2d, \e0\().2d, v16.2d +.endif +.endm + +const shuf_4pt_x2, align=4 + .byte 24, 25, 26, 27 // reg2, 3 + .byte 12, 13, 14, 15 // reg1, 4 + .byte 8, 9, 10, 11 // reg1, 3 + .byte 28, 29, 30, 31 // reg2, 4 +endconst + +// Identical to FFT4, but does 2 transforms in parallel, with no deinterleaving +.macro FFT4_X2 e0, o0, e1, o1, \ + t0=v16, t1=v17, t2=v18, t3=v19, t4=v20, t5=v21, t6=v22 + + fadd \t0\().4s, \e0\().4s, \o0\().4s // r1234 + fadd \t2\().4s, \e1\().4s, \o1\().4s // r1234 + fsub \e0\().4s, \e0\().4s, \o0\().4s // t1234 + fsub \e1\().4s, \e1\().4s, \o1\().4s // t1234 + + movrel x5, shuf_4pt_x2 + + rev64 \t4\().4s, \e0\().4s + rev64 \t5\().4s, \e1\().4s + + zip2 \o0\().2d, \t0\().2d, \e0\().2d // t3,4 r3,4 + zip2 \o1\().2d, \t2\().2d, \e1\().2d // t3,4 r3,4 + + ld1 { \t6\().16b }, [x5] + + mov \o0\().d[1], \t4\().d[1] + mov \o1\().d[1], \t5\().d[1] + + zip1 \t1\().2d, \t0\().2d, \e0\().2d // t1,2 r1,2 + zip1 \t3\().2d, \t2\().2d, \e1\().2d // t1,2 r1,2 + + fsub \t4\().4s, \t1\().4s, \o0\().4s // a34 b32 + fadd \t5\().4s, \t1\().4s, \o0\().4s // a12 b14 + fsub \t2\().4s, \t3\().4s, \o1\().4s // a34 b32 + fadd \t3\().4s, \t3\().4s, \o1\().4s // a12 b14 + + // TODO: experiment with movs instead of tables here + tbl \o0\().16b, { \t4\().16b, \t5\().16b }, \t6\().16b // b1234 + tbl \o1\().16b, { \t2\().16b, \t3\().16b }, \t6\().16b // b1234 + + zip1 \e0\().2d, \t5\().2d, \t4\().2d // a1234 +// zip2 \o0\().2d, \t5\().2d, \t4\().2d // b1432 + zip1 \e1\().2d, \t3\().2d, \t2\().2d // a1234 +// zip2 \o1\().2d, \t3\().2d, \t2\().2d // b1432 +// rev64 \o0\().4s, \o0\().4s // b4123 +// rev64 \o1\().4s, \o1\().4s // b4123 +// ext \o0\().16b, \o0\().16b, \o0\().16b, #4 // b1234 +// ext \o1\().16b, \o1\().16b, \o1\().16b, #4 // b1234 +.endm + +const tab_8pt, align=4 + .float M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2 +endconst + +.macro FFT8 e0, e1, o0, o1, \ + t0=v16, t1=v17, t2=v18, t3=v19, t4=v20, t5=v21, t6=v22 + + movrel x5, tab_8pt + + fsub \t1\().4s, \e1\().4s, \o1\().4s // j1234 + fadd \o1\().4s, \e1\().4s, \o1\().4s // k1234 + fsub \t0\().4s, \e0\().4s, \o0\().4s // r1234 + fadd \o0\().4s, \e0\().4s, \o0\().4s // q1234 + + ld1 { \t5\().4s }, [x5] + + ext \t4\().16b, \o1\().16b, \o1\().16b, #12 + rev64 \t4\().4s, \t4\().4s + + ext \t2\().16b, \o0\().16b, \t4\().16b, #8 // o0[0,1], o1[3,2] + mov \o0\().d[1], \t4\().d[1] // o0[3, 4]; o1[1, 4] + + fsub \e1\().4s, \o0\().4s, \t2\().4s // s34, g43 + fadd \t2\().4s, \o0\().4s, \t2\().4s // s12, g12 + + rev64 \t6\().4s, v31.4s // 1, -1, 1, -1 + dup \o0\().2d, \t0\().d[0] // r1212 + dup \o1\().2d, \t0\().d[1] // r3434 + + rev64 \t4\().4s, \e1\().4s // xxg34 + rev64 \o1\().4s, \o1\().4s // r4343 + + ext \t6\().16b, v31.16b, \t6\().16b, #8 // -1, 1, 1, -1 + zip1 \t3\().2d, \t2\().2d, \e1\().2d // s1234 + zip2 \t2\().2d, \t2\().2d, \t4\().2d // g1234 + + fadd \e0\().4s, \t3\().4s, \t2\().4s // out_e1 + fsub \e1\().4s, \t3\().4s, \t2\().4s // out_e2 + + fmul \t1\().4s, \t1\().4s, \t5\().4s // j * +--+M_SQRT1_2 + fmls \o0\().4s, \o1\().4s, \t6\().4s // z1234 + + rev64 \t4\().4s, \t1\().4s // j2143 + fmla \t1\().4s, \t4\().4s, v31.4s // l2143 + + rev64 \t4\().4s, \t1\().4s // l1234 + ext \t4\().16b, \t4\().16b, \t4\().16b, #8 // l3412 + + fmla \t4\().4s, \t1\().4s, v31.4s // t1234 + + fadd \o1\().4s, \o0\().4s, \t4\().4s // out_o2 + fsub \o0\().4s, \o0\().4s, \t4\().4s // out_o1 +.endm + +// Identical as FFT8, but does 2 transforms in parallel +.macro FFT8_X2 e0, e1, o0, o1, e2, e3, o2, o3 + + movrel x5, tab_8pt + + fadd v19.4s, \e3\().4s, \o3\().4s // k1234 + fadd v17.4s, \e1\().4s, \o1\().4s // k1234 + fadd v18.4s, \e2\().4s, \o2\().4s // q1234 + fadd v16.4s, \e0\().4s, \o0\().4s // q1234 + + ld1 { v23.4s }, [x5] + + ext v22.16b, v19.16b, v19.16b, #12 + ext v21.16b, v17.16b, v17.16b, #12 + + rev64 v22.4s, v22.4s + rev64 v21.4s, v21.4s + + ext v19.16b, v18.16b, v22.16b, #8 + ext v17.16b, v16.16b, v21.16b, #8 + + mov v18.d[1], v22.d[1] + mov v21.d[0], v16.d[0] + + fadd v22.4s, v18.4s, v19.4s // s12, g12 + fsub v19.4s, v18.4s, v19.4s // s34, g43 + fsub v18.4s, v21.4s, v17.4s // s34, g43 + fadd v16.4s, v21.4s, v17.4s // s12, g12 + + fsub \e0\().4s, \e0\().4s, \o0\().4s // r1234 + fsub v20.4s, \e1\().4s, \o1\().4s // j1234 + fsub \e2\().4s, \e2\().4s, \o2\().4s // r1234 + fsub v21.4s, \e3\().4s, \o3\().4s // j1234 + + rev64 v24.4s, v31.4s // 1, -1, 1, -1 + zip1 v17.2d, v16.2d, v18.2d // s1234 + zip1 \e1\().2d, v22.2d, v19.2d // s1234 + + rev64 v18.4s, v18.4s // xxg34 + rev64 v19.4s, v19.4s // xxg34 + + zip2 v16.2d, v16.2d, v18.2d // g1234 + zip2 \e3\().2d, v22.2d, v19.2d // g1234 + + dup \o0\().2d, \e0\().d[0] // r1212 + dup \o1\().2d, \e0\().d[1] // r3434 + dup \o2\().2d, \e2\().d[0] // r1212 + dup \o3\().2d, \e2\().d[1] // r3434 + + fadd \e2\().4s, \e1\().4s, \e3\().4s // out_e1 + fsub \e3\().4s, \e1\().4s, \e3\().4s // out_e2 + fadd \e0\().4s, v17.4s, v16.4s // out_e1 + fsub \e1\().4s, v17.4s, v16.4s // out_e2 + + ext v24.16b, v31.16b, v24.16b, #8 // -1, 1, 1, -1 + rev64 \o1\().4s, \o1\().4s // r4343 + rev64 \o3\().4s, \o3\().4s // r4343 + + fmul v19.4s, v20.4s, v23.4s // j * +--+M_SQRT1_2 + fmul v21.4s, v21.4s, v23.4s // j * +--+M_SQRT1_2 + + rev64 v20.4s, v19.4s // j2143 + rev64 v18.4s, v21.4s // j2143 + + fmls \o0\().4s, \o1\().4s, v24.4s // z1234 + fmls \o2\().4s, \o3\().4s, v24.4s // z1234 + + fmla v19.4s, v20.4s, v31.4s // l2143 + fmla v21.4s, v18.4s, v31.4s // l2143 + + rev64 v20.4s, v19.4s // l1234 + rev64 v18.4s, v21.4s // l1234 + ext v20.16b, v20.16b, v20.16b, #8 // l3412 + ext v18.16b, v18.16b, v18.16b, #8 // l3412 + + fmla v20.4s, v19.4s, v31.4s // t1234 + fmla v18.4s, v21.4s, v31.4s // t1234 + + fadd \o1\().4s, \o0\().4s, v20.4s // out_o2 + fadd \o3\().4s, \o2\().4s, v18.4s // out_o2 + fsub \o0\().4s, \o0\().4s, v20.4s // out_o1 + fsub \o2\().4s, \o2\().4s, v18.4s // out_o1 +.endm + +const tab_16pt, align=4 + .float -COS16_1, COS16_1, -COS16_3, COS16_3 // Could be +-+- too + .float COS16_3, COS16_3, COS16_1, COS16_1 + .float 1.0, 1.0, M_SQRT1_2, M_SQRT1_2 +endconst + +// 16-point FFT +// t3, t4, t5, t6 must be sequential +.macro FFT16 e0, e1, e2, e3, o0, o1, o2, o3, \ + t0=v16, t1=v17, t2=v18, t3=v19, t4=v20, t5=v21, t6=v22 + + FFT8 \e0, \e1, \e2, \e3, \t0, \t1, \t2, \t3, \t4, \t5, \t6 + FFT4_X2 \o0, \o1, \o2, \o3, \t0, \t1, \t2, \t3, \t4, \t5, \t6 + + movrel x5, tab_16pt + + rev64 \t0\().4s, \o0\().4s // z[ 8, 9].imre + rev64 \t1\().4s, \o2\().4s // z[10,11].imre + + ins \t0\().d[0], xzr + ins \t1\().d[0], xzr + + ld1 { \t4\().4s, \t5\().4s, \t6\().4s }, [x5] + // TODO: We could derive \t4\() or \t5\() from either, but it seems cheaper to load + + fmla \o2\().4s, \t1\().4s, v31.4s // s[4567] + fmls \o0\().4s, \t0\().4s, v31.4s // s[0123] + + fmul \t2\().4s, \o1\().4s, \t4\().4s + fmul \t3\().4s, \o3\().4s, \t4\().4s + + rev64 \o3\().4s, \o3\().4s + rev64 \o1\().4s, \o1\().4s + + fmla \t3\().4s, \o3\().4s, \t5\().4s // s[12, 13, 14, 15] + fmls \t2\().4s, \o1\().4s, \t5\().4s // s[ 8, 9, 10, 11] + + fmul \t1\().4s, \o2\().4s, \t6\().4s // s[4567] * mult + fmul \t0\().4s, \o0\().4s, \t6\().4s // s[0123] * mult + + mov \o1\().16b, \t3\().16b + mov \o2\().16b, \t1\().16b + + fsub \t3\().4s, \t3\().4s, \t2\().4s // y34, u34 + fsub \t1\().4s, \t1\().4s, \t0\().4s // w34, x34 + + fadd \t2\().4s, \t2\().4s, \o1\().4s // y56, u56 + rev64 \t3\().4s, \t3\().4s + fadd \t0\().4s, \t0\().4s, \o2\().4s // w56, x56 + rev64 \t1\().4s, \t1\().4s + + fmul \t2\().4s, \t2\().4s, v31.4s + fmul \t1\().4s, \t1\().4s, v31.4s + + fadd \o3\().4s, \e3\().4s, \t3\().4s + fsub \o2\().4s, \e3\().4s, \t3\().4s + fsub \o1\().4s, \e2\().4s, \t2\().4s + fadd \o0\().4s, \e2\().4s, \t2\().4s + + fsub \e2\().4s, \e0\().4s, \t0\().4s + fadd \e0\().4s, \e0\().4s, \t0\().4s + fsub \e3\().4s, \e1\().4s, \t1\().4s + fadd \e1\().4s, \e1\().4s, \t1\().4s +.endm + +function ff_tx_fft2_float_neon, export=1 + ld2r { v0.2d, v1.2d }, [x2] + + fneg v2.2s, v1.2s + mov v2.d[1], v1.d[0] + + fsub v2.4s, v0.4s, v2.4s + + st1 { v2.4s }, [x1] + ret +endfunc + +.macro FFT4_FN name, inv +function ff_tx_fft4_\name\()_float_neon, export=1 + ld1 {v0.4s, v1.4s}, [x2] + +.if \inv == 1 + mov v2.d[0], v0.d[1] + mov v0.d[1], v1.d[1] + mov v1.d[1], v2.d[0] +.endif + + FFT4 v0, v1, 1 + + st1 { v0.4s, v1.4s }, [x1] + ret +endfunc +.endm + +FFT4_FN fwd, 0 +FFT4_FN inv, 1 + +.macro FFT8_FN name, no_perm +function ff_tx_fft8_\name\()_neon, export=1 + SETUP_LUT \no_perm + LOAD_INPUT 0, 1, 2, 3, x2, \no_perm + + LOAD_SUBADD + FFT8 v0, v1, v2, v3 + + zip1 v16.2d, v0.2d, v2.2d + zip2 v17.2d, v0.2d, v2.2d + zip1 v18.2d, v1.2d, v3.2d + zip2 v19.2d, v1.2d, v3.2d + st1 { v16.4s, v17.4s, v18.4s, v19.4s }, [x1] + + ret +endfunc +.endm + +FFT8_FN float, 0 +FFT8_FN ns_float, 1 + +.macro FFT16_FN name, no_perm +function ff_tx_fft16_\name\()_neon, export=1 + SETUP_LUT \no_perm + LOAD_INPUT 0, 1, 2, 3, x2, \no_perm + LOAD_INPUT 4, 5, 6, 7, x2, \no_perm + + LOAD_SUBADD + FFT16 v0, v1, v2, v3, v4, v5, v6, v7 + + zip1 v20.2d, v0.2d, v4.2d + zip2 v21.2d, v0.2d, v4.2d + zip1 v22.2d, v1.2d, v6.2d + zip2 v23.2d, v1.2d, v6.2d + st1 { v20.4s, v21.4s, v22.4s, v23.4s }, [x1], #64 + + zip1 v24.2d, v2.2d, v5.2d + zip2 v25.2d, v2.2d, v5.2d + zip1 v26.2d, v3.2d, v7.2d + zip2 v27.2d, v3.2d, v7.2d + st1 { v24.4s, v25.4s, v26.4s, v27.4s }, [x1] + + ret +endfunc +.endm + +FFT16_FN float, 0 +FFT16_FN ns_float, 1 + +.macro SETUP_SR_RECOMB len, re, im, dec + ldr w5, =(\len - 4*7) + movrel \re, X(ff_tx_tab_\len\()_float) + add \im, \re, x5 + mov \dec, #-32 + +.if \len > 32 + mov x21, #2*\len + add x22, x21, x21, lsl #1 +.endif +.endm + +.macro SR_COMBINE e0, e1, e2, e3, e4, e5, e6, e7, \ + o0, o1, o2, o3, o4, o5, o6, o7, \ + re, im, dec, swap_im, \ + t0=v16, t1=v17, t2=v18, t3=v19, t4=v20, t5=v21, \ + t6=v22, t7=v23, t8=v24, t9=v25, ta=v26, tb=v27 + + ld1 { \t8\().4s, \t9\().4s }, [\im], \dec + ld1 { \t0\().4s, \t1\().4s }, [\re], #32 + +.if \swap_im == 1 + ext \t2\().16b, \t9\().16b, \t9\().16b, #8 + ext \t3\().16b, \t8\().16b, \t8\().16b, #8 +.else + ext \t2\().16b, \t8\().16b, \t8\().16b, #8 + ext \t3\().16b, \t9\().16b, \t9\().16b, #8 +.endif + + trn1 \t4\().4s, \t0\().4s, \t0\().4s // cos0022 + trn2 \t0\().4s, \t0\().4s, \t0\().4s // cos4466 + trn1 \t5\().4s, \t1\().4s, \t1\().4s // cos1133 + trn2 \t1\().4s, \t1\().4s, \t1\().4s // cos5577 + + rev64 \t6\().4s, \o0\().4s // E m2[0,1].imre + rev64 \t7\().4s, \o2\().4s // O m2[0,1].imre + rev64 \t8\().4s, \o4\().4s // E m2[2,3].imre + rev64 \t9\().4s, \o6\().4s // O m2[2,3].imre + + fmul \t6\().4s, \t6\().4s, \t4\().4s // E m2[0,1].imre*t1[0,2] + fmul \t7\().4s, \t7\().4s, \t0\().4s // O m2[0,1].imre*t1[0,2] + fmul \t8\().4s, \t8\().4s, \t4\().4s // E m2[2,3].imre*t1[0,2] + fmul \t9\().4s, \t9\().4s, \t0\().4s // O m2[2,3].imre*t1[0,2] + + rev64 \ta\().4s, \o1\().4s // E m3[0,1].imre + rev64 \tb\().4s, \o3\().4s // O m3[0,1].imre + rev64 \t4\().4s, \o5\().4s // E m3[2,3].imre + rev64 \t0\().4s, \o7\().4s // O m3[2,3].imre + + fmul \ta\().4s, \ta\().4s, \t5\().4s // E m3[0,1].imre*t1[4,6] + fmul \tb\().4s, \tb\().4s, \t1\().4s // O m3[0,1].imre*t1[4,6] + fmul \t4\().4s, \t4\().4s, \t5\().4s // E m3[2,3].imre*t1[4,6] + fmul \t0\().4s, \t0\().4s, \t1\().4s // O m3[2,3].imre*t1[4,6] + + trn1 \t5\().4s, \t3\().4s, \t3\().4s // wim2200 + trn2 \t3\().4s, \t3\().4s, \t3\().4s // wim3311 + trn1 \t1\().4s, \t2\().4s, \t2\().4s // wim6644 + trn2 \t2\().4s, \t2\().4s, \t2\().4s // wim7755 + + fmul \t5\().4s, \t5\().4s, v31.4s + fmul \t3\().4s, \t3\().4s, v31.4s + fmul \t1\().4s, \t1\().4s, v31.4s + fmul \t2\().4s, \t2\().4s, v31.4s + + fmla \t7\().4s, \o2\().4s, \t5\().4s // O w0123 + fmls \t9\().4s, \o6\().4s, \t5\().4s // O j0123 + fmla \t6\().4s, \o0\().4s, \t3\().4s // E w0123 + fmls \t8\().4s, \o4\().4s, \t3\().4s // E j0123 + + fmla \ta\().4s, \o1\().4s, \t2\().4s // E w4567 + fmla \tb\().4s, \o3\().4s, \t1\().4s // O w4567 + fmls \t4\().4s, \o5\().4s, \t2\().4s // E j4567 + fmls \t0\().4s, \o7\().4s, \t1\().4s // O j4567 + + fsub \t2\().4s, \t7\().4s, \t9\().4s + fsub \t1\().4s, \t8\().4s, \t6\().4s + fsub \t3\().4s, \t4\().4s, \ta\().4s + fsub \t5\().4s, \t0\().4s, \tb\().4s + + fadd \t6\().4s, \t8\().4s, \t6\().4s + fadd \t7\().4s, \t9\().4s, \t7\().4s + fadd \t8\().4s, \t4\().4s, \ta\().4s + fadd \t9\().4s, \t0\().4s, \tb\().4s + + fmul \t1\().4s, \t1\().4s, v31.4s + fmul \t2\().4s, \t2\().4s, v31.4s + fmul \t3\().4s, \t3\().4s, v31.4s + fmul \t5\().4s, \t5\().4s, v31.4s + + rev64 \t6\().4s, \t6\().4s + rev64 \t8\().4s, \t8\().4s + rev64 \t7\().4s, \t7\().4s + rev64 \t9\().4s, \t9\().4s + + fsub \o0\().4s, \e0\().4s, \t6\().4s + fsub \o1\().4s, \e1\().4s, \t8\().4s + fsub \o2\().4s, \e2\().4s, \t1\().4s + fsub \o3\().4s, \e3\().4s, \t3\().4s + + fsub \o4\().4s, \e4\().4s, \t7\().4s + fsub \o5\().4s, \e6\().4s, \t9\().4s + fadd \o6\().4s, \e5\().4s, \t2\().4s + fsub \o7\().4s, \e7\().4s, \t5\().4s + + fadd \e0\().4s, \e0\().4s, \t6\().4s + fadd \e1\().4s, \e1\().4s, \t8\().4s + fadd \e2\().4s, \e2\().4s, \t1\().4s + fadd \e3\().4s, \e3\().4s, \t3\().4s + + fadd \e4\().4s, \e4\().4s, \t7\().4s + fsub \e5\().4s, \e5\().4s, \t2\().4s // swapped + fadd \e6\().4s, \e6\().4s, \t9\().4s // swapped + fadd \e7\().4s, \e7\().4s, \t5\().4s +.endm + +.macro SR_COMBINE_HALF e0, e1, e2, e3, \ + o0, o1, o2, o3, \ + c0, c1, c2, c3, \ + t0, t1, t2, t3, t4, t5, part + +.if \part == 0 + trn1 \t4\().4s, \c0\().4s, \c0\().4s // cos0022 + trn1 \c1\().4s, \c1\().4s, \c1\().4s // cos1133 +.else + trn2 \t4\().4s, \c0\().4s, \c0\().4s // cos0022 + trn2 \c1\().4s, \c1\().4s, \c1\().4s // cos1133 +.endif +.if \part == 0 + trn2 \t5\().4s, \c2\().4s, \c2\().4s // wim7755 + trn2 \c3\().4s, \c3\().4s, \c3\().4s // wim3311 +.else + trn1 \t5\().4s, \c2\().4s, \c2\().4s // wim7755 + trn1 \c3\().4s, \c3\().4s, \c3\().4s // wim3311 +.endif + + fmul \t5\().4s, \t5\().4s, v31.4s + fmul \c3\().4s, \c3\().4s, v31.4s + + rev64 \t0\().4s, \o0\().4s // E m2[0,1].imre + rev64 \t1\().4s, \o2\().4s // E m2[2,3].imre + rev64 \t2\().4s, \o1\().4s // E m3[0,1].imre + rev64 \t3\().4s, \o3\().4s // E m3[2,3].imre + + fmul \o0\().4s, \o0\().4s, \c3\().4s // E m2[0,1].imre*t1[0,2] + fmul \o1\().4s, \o1\().4s, \t5\().4s // E m3[0,1].imre*t1[4,6] + fmla \o0\().4s, \t0\().4s, \t4\().4s // E w0123 + fmla \o1\().4s, \t2\().4s, \c1\().4s // E w4567 + + fmul \t1\().4s, \t1\().4s, \t4\().4s // E m2[2,3].imre*t1[0,2] + fmul \t3\().4s, \t3\().4s, \c1\().4s // E m3[2,3].imre*t1[4,6] + fmls \t1\().4s, \o2\().4s, \c3\().4s // E j0123 + fmls \t3\().4s, \o3\().4s, \t5\().4s // E j4567 + + fsub \t0\().4s, \t1\().4s, \o0\().4s + fadd \t1\().4s, \t1\().4s, \o0\().4s + fadd \t2\().4s, \t3\().4s, \o1\().4s + fsub \t3\().4s, \t3\().4s, \o1\().4s + + fmul \t0\().4s, \t0\().4s, v31.4s + fmul \t3\().4s, \t3\().4s, v31.4s + + rev64 \t1\().4s, \t1\().4s + rev64 \t2\().4s, \t2\().4s + +.if \part == 0 + fsub \o0\().4s, \e0\().4s, \t1\().4s + fsub \o1\().4s, \e1\().4s, \t2\().4s + fsub \o2\().4s, \e2\().4s, \t0\().4s + fsub \o3\().4s, \e3\().4s, \t3\().4s +.else + fsub \o0\().4s, \e0\().4s, \t1\().4s + fadd \o2\().4s, \e1\().4s, \t2\().4s + fsub \o1\().4s, \e2\().4s, \t0\().4s + fadd \o3\().4s, \e3\().4s, \t3\().4s +.endif + +.if \part == 0 + fadd \e0\().4s, \e0\().4s, \t1\().4s + fadd \e1\().4s, \e1\().4s, \t2\().4s + fadd \e2\().4s, \e2\().4s, \t0\().4s + fadd \e3\().4s, \e3\().4s, \t3\().4s +.else + fadd \e0\().4s, \e0\().4s, \t1\().4s + fsub \e1\().4s, \e1\().4s, \t2\().4s // swapped + fadd \e2\().4s, \e2\().4s, \t0\().4s // swapped + fsub \e3\().4s, \e3\().4s, \t3\().4s +.endif +.endm + +/* Same as SR_COMBINE_HALF, but heroically tries to use 3 temporary registers + * without touching the tables. */ +.macro SR_COMBINE_LITE e0, e1, e2, e3, \ + o0, o1, o2, o3, \ + c0, c1, c2, c3, \ + t0, t1, t2, part + + rev64 \t0\().4s, \o0\().4s // E m2[0,1].imre + rev64 \t1\().4s, \o2\().4s // E m2[2,3].imre +.if \part == 0 + trn2 \t2\().4s, \c3\().4s, \c3\().4s // wim3311 +.else + trn1 \t2\().4s, \c3\().4s, \c3\().4s // wim3311 +.endif + fmul \t2\().4s, \t2\().4s, v31.4s + fmul \o2\().4s, \o2\().4s, \t2\().4s + fmul \o0\().4s, \o0\().4s, \t2\().4s // E m2[0,1].imre*t1[0,2] +.if \part == 0 + trn1 \t2\().4s, \c0\().4s, \c0\().4s // cos0022 +.else + trn2 \t2\().4s, \c0\().4s, \c0\().4s // cos0022 +.endif + fmul \t1\().4s, \t1\().4s, \t2\().4s // E m2[2,3].imre*t1[0,2] + fmla \o0\().4s, \t0\().4s, \t2\().4s // E w0123 + fsub \t1\().4s, \t1\().4s, \o2\().4s // E j0123 + + rev64 \t2\().4s, \o1\().4s // E m3[0,1].imre + rev64 \o2\().4s, \o3\().4s // E m3[2,3].imre + +.if \part == 0 + trn2 \t0\().4s, \c2\().4s, \c2\().4s // wim7755 +.else + trn1 \t0\().4s, \c2\().4s, \c2\().4s // wim7755 +.endif + fmul \t0\().4s, \t0\().4s, v31.4s + + fmul \o1\().4s, \o1\().4s, \t0\().4s // E m3[0,1].imre*t1[4,6] + fmul \o3\().4s, \o3\().4s, \t0\().4s + +.if \part == 0 + trn1 \t0\().4s, \c1\().4s, \c1\().4s // cos1133 +.else + trn2 \t0\().4s, \c1\().4s, \c1\().4s // cos1133 +.endif + fmul \o2\().4s, \o2\().4s, \t0\().4s // E m3[2,3].imre*t1[4,6] + fmla \o1\().4s, \t2\().4s, \t0\().4s // E w4567 + fsub \o2\().4s, \o2\().4s, \o3\().4s // E j4567 + + fsub \t0\().4s, \t1\().4s, \o0\().4s + fadd \o0\().4s, \t1\().4s, \o0\().4s + fadd \t2\().4s, \o2\().4s, \o1\().4s + fsub \t1\().4s, \o2\().4s, \o1\().4s + + fmul \t0\().4s, \t0\().4s, v31.4s + fmul \t1\().4s, \t1\().4s, v31.4s + + rev64 \t2\().4s, \t2\().4s + rev64 \o0\().4s, \o0\().4s + +.if \part == 0 + fsub \o1\().4s, \e1\().4s, \t2\().4s + fsub \o2\().4s, \e2\().4s, \t0\().4s + fsub \o3\().4s, \e3\().4s, \t1\().4s +.else + fadd \o2\().4s, \e1\().4s, \t0\().4s + fsub \o1\().4s, \e2\().4s, \t2\().4s + fadd \o3\().4s, \e3\().4s, \t1\().4s +.endif + +.if \part == 0 + fadd \e1\().4s, \e1\().4s, \t2\().4s + fadd \e2\().4s, \e2\().4s, \t0\().4s + fadd \e3\().4s, \e3\().4s, \t1\().4s +.else + fsub \e1\().4s, \e1\().4s, \t0\().4s // swapped + fadd \e2\().4s, \e2\().4s, \t2\().4s // swapped + fsub \e3\().4s, \e3\().4s, \t1\().4s +.endif + + mov \t1\().16b, \o0\().16b + + fsub \o0\().4s, \e0\().4s, \t1\().4s + fadd \e0\().4s, \e0\().4s, \t1\().4s +.endm + +.macro SR_COMBINE_4 len, part, off + add x10, x1, x21 + add x11, x1, x21, lsl #1 + add x12, x1, x22 + + ldp q0, q1, [x1, #((0 + \part)*32 + \off)] + ldp q4, q5, [x1, #((2 + \part)*32 + \off)] + ldp q2, q3, [x10, #((0 + \part)*32 + \off)] + ldp q6, q7, [x10, #((2 + \part)*32 + \off)] + + ldp q8, q9, [x11, #((0 + \part)*32 + \off)] + ldp q10, q11, [x11, #((2 + \part)*32 + \off)] + ldp q12, q13, [x12, #((0 + \part)*32 + \off)] + ldp q14, q15, [x12, #((2 + \part)*32 + \off)] + + SR_COMBINE v0, v1, v2, v3, v4, v6, v5, v7, \ + v8, v9, v10, v11, v12, v13, v14, v15, \ + x7, x8, x9, 0 + + stp q0, q1, [x1, #((0 + \part)*32 + \off)] + stp q4, q5, [x1, #((2 + \part)*32 + \off)] + stp q2, q3, [x10, #((0 + \part)*32 + \off)] + stp q6, q7, [x10, #((2 + \part)*32 + \off)] + + stp q8, q9, [x11, #((0 + \part)*32 + \off)] + stp q12, q13, [x11, #((2 + \part)*32 + \off)] + stp q10, q11, [x12, #((0 + \part)*32 + \off)] + stp q14, q15, [x12, #((2 + \part)*32 + \off)] +.endm + +.macro SR_COMBINE_FULL len, off=0 + add x10, x1, x21 + add x11, x1, x21, lsl #1 + add x12, x1, x22 + + SR_COMBINE_4 \len, 0, \off + SR_COMBINE_4 \len, 1, \off + SR_COMBINE_4 \len, 4, \off + SR_COMBINE_4 \len, 5, \off +.endm + +.macro SR_COMBINE_D2 part, off + add x10, x1, #((\part)*32 + \off) + add x11, x14, #((\part)*32 + \off) + add x12, x15, #((\part)*32 + \off) + add x13, x16, #((\part)*32 + \off) + + ldp q0, q1, [x10] + ldp q4, q5, [x10, #(2*32)] + ldp q2, q3, [x11] + ldp q6, q7, [x11, #(2*32)] + + ldp q8, q9, [x12] + ldp q10, q11, [x12, #(2*32)] + ldp q12, q13, [x13] + ldp q14, q15, [x13, #(2*32)] + + SR_COMBINE v0, v1, v2, v3, v4, v6, v5, v7, \ + v8, v9, v10, v11, v12, v13, v14, v15, \ + x7, x8, x9, 0, \ + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27 + + zip1 v16.2d, v0.2d, v4.2d + zip2 v17.2d, v0.2d, v4.2d + zip1 v18.2d, v1.2d, v5.2d + zip2 v19.2d, v1.2d, v5.2d + + zip1 v20.2d, v2.2d, v6.2d + zip2 v21.2d, v2.2d, v6.2d + zip1 v22.2d, v3.2d, v7.2d + zip2 v23.2d, v3.2d, v7.2d + + ldp q0, q1, [x10, #(1*32)] + ldp q4, q5, [x10, #(3*32)] + ldp q2, q3, [x11, #(1*32)] + ldp q6, q7, [x11, #(3*32)] + + st1 { v16.4s, v17.4s, v18.4s, v19.4s }, [x10], #64 + st1 { v20.4s, v21.4s, v22.4s, v23.4s }, [x11], #64 + + zip1 v20.2d, v8.2d, v12.2d + zip2 v21.2d, v8.2d, v12.2d + zip1 v22.2d, v9.2d, v13.2d + zip2 v23.2d, v9.2d, v13.2d + zip1 v24.2d, v10.2d, v14.2d + zip2 v25.2d, v10.2d, v14.2d + zip1 v26.2d, v11.2d, v15.2d + zip2 v27.2d, v11.2d, v15.2d + + ldp q8, q9, [x12, #(1*32)] + ldp q10, q11, [x12, #(3*32)] + ldp q12, q13, [x13, #(1*32)] + ldp q14, q15, [x13, #(3*32)] + + st1 { v20.4s, v21.4s, v22.4s, v23.4s }, [x12], #64 + st1 { v24.4s, v25.4s, v26.4s, v27.4s }, [x13], #64 + + SR_COMBINE v0, v1, v2, v3, v4, v6, v5, v7, \ + v8, v9, v10, v11, v12, v13, v14, v15, \ + x7, x8, x9, 0, \ + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27 + + zip1 v16.2d, v0.2d, v4.2d + zip2 v17.2d, v0.2d, v4.2d + zip1 v18.2d, v1.2d, v5.2d + zip2 v19.2d, v1.2d, v5.2d + st1 { v16.4s, v17.4s, v18.4s, v19.4s }, [x10] + + zip1 v16.2d, v2.2d, v6.2d + zip2 v17.2d, v2.2d, v6.2d + zip1 v18.2d, v3.2d, v7.2d + zip2 v19.2d, v3.2d, v7.2d + st1 { v16.4s, v17.4s, v18.4s, v19.4s }, [x11] + + zip1 v20.2d, v8.2d, v12.2d + zip2 v21.2d, v8.2d, v12.2d + zip1 v22.2d, v9.2d, v13.2d + zip2 v23.2d, v9.2d, v13.2d + st1 { v20.4s, v21.4s, v22.4s, v23.4s }, [x12] + + zip1 v24.2d, v10.2d, v14.2d + zip2 v25.2d, v10.2d, v14.2d + zip1 v26.2d, v11.2d, v15.2d + zip2 v27.2d, v11.2d, v15.2d + st1 { v24.4s, v25.4s, v26.4s, v27.4s }, [x13] +.endm + +.macro SR_COMBINE_DINT off=0 + add x14, x1, x21 + add x15, x1, x21, lsl #1 + add x16, x1, x22 + + SR_COMBINE_D2 0, \off + SR_COMBINE_D2 4, \off +.endm + +.macro FFT32_FN name, no_perm +function ff_tx_fft32_\name\()_neon, export=1 + stp d14, d15, [sp, #-16*4]! + stp d8, d9, [sp, #16*3] + stp d10, d11, [sp, #16*2] + stp d12, d13, [sp, #16] + + LOAD_SUBADD + SETUP_SR_RECOMB 32, x7, x8, x9 + + SETUP_LUT \no_perm + LOAD_INPUT 0, 1, 2, 3, x2, \no_perm + LOAD_INPUT 4, 5, 6, 7, x2, \no_perm + LOAD_INPUT 8, 9, 10, 11, x2, \no_perm + LOAD_INPUT 12, 13, 14, 15, x2, \no_perm + + FFT8_X2 v8, v9, v10, v11, v12, v13, v14, v15 + FFT16 v0, v1, v2, v3, v4, v5, v6, v7 + + SR_COMBINE v0, v1, v2, v3, v4, v5, v6, v7, \ + v8, v9, v10, v11, v12, v13, v14, v15, \ + x7, x8, x9, 0 + + zip1 v16.2d, v0.2d, v4.2d + zip2 v17.2d, v0.2d, v4.2d + zip1 v18.2d, v1.2d, v6.2d + zip2 v19.2d, v1.2d, v6.2d + st1 { v16.4s, v17.4s, v18.4s, v19.4s }, [x1], #64 + + zip1 v20.2d, v2.2d, v5.2d + zip2 v21.2d, v2.2d, v5.2d + zip1 v22.2d, v3.2d, v7.2d + zip2 v23.2d, v3.2d, v7.2d + st1 { v20.4s, v21.4s, v22.4s, v23.4s }, [x1], #64 + + zip1 v24.2d, v8.2d, v12.2d + zip2 v25.2d, v8.2d, v12.2d + zip1 v26.2d, v9.2d, v13.2d + zip2 v27.2d, v9.2d, v13.2d + st1 { v24.4s, v25.4s, v26.4s, v27.4s }, [x1], #64 + + zip1 v28.2d, v10.2d, v14.2d + zip2 v29.2d, v10.2d, v14.2d + zip1 v30.2d, v11.2d, v15.2d + zip2 v31.2d, v11.2d, v15.2d + st1 { v28.4s, v29.4s, v30.4s, v31.4s }, [x1] + + ldp d12, d13, [sp, #16] + ldp d10, d11, [sp, #16*2] + ldp d8, d9, [sp, #16*3] + ldp d14, d15, [sp], #16*4 + + ret +endfunc +.endm + +FFT32_FN float, 0 +FFT32_FN ns_float, 1 + +.macro cmp_imm reg, imm +.if \imm >= 4096 + cmp \reg, #((\imm)/4096), lsl #12 +.else + cmp \reg, #(\imm) +.endif +.endm + +.macro SR_TRANSFORM_DEF len, next=0 +\len: + stp x20, x30, [sp, #-16]! + mov w20, #(\len/4) + mov x5, #((\len*4) - (\len/1)) + add x1, x1, x5 + bl 32b + mov x5, #((\len*2) - (\len/2)) + add x1, x1, x5 + bl 32b + ldp x20, x30, [sp], #16 + ldr w5, =(\len*6 + \len/2) + sub x1, x1, x5 + + SETUP_SR_RECOMB \len, x7, x8, x9 + +.if \next\() != 0 + cmp_imm w19, \len + b.eq 0f + + mov w5, #(\len/128) +\len\()5: + SR_COMBINE_FULL \len + add x1, x1, 8*32 + subs w5, w5, 1 + b.gt \len\()5b + + cmp_imm w20, \len + b.gt \next\()f + ret +.endif +.endm + +.macro FFT_SPLIT_RADIX_FN name, no_perm +function ff_tx_fft_sr_\name\()_neon, export=1 + stp x21, x22, [sp, #-16*6]! + stp d8, d9, [sp, #16*5] + stp d10, d11, [sp, #16*4] + stp d12, d13, [sp, #16*3] + stp d14, d15, [sp, #16*2] + stp x19, x20, [sp, #16] + + ldr w19, [x0, #0] // global target + mov w20, w19 // local length + + LOAD_SUBADD + SETUP_LUT \no_perm + +32: + SETUP_SR_RECOMB 32, x7, x8, x9 + + LOAD_INPUT 0, 1, 2, 3, x2, \no_perm + LOAD_INPUT 4, 6, 5, 7, x2, \no_perm, 1 + LOAD_INPUT 8, 9, 10, 11, x2, \no_perm + LOAD_INPUT 12, 13, 14, 15, x2, \no_perm + + FFT8_X2 v8, v9, v10, v11, v12, v13, v14, v15 + FFT16 v0, v1, v2, v3, v4, v6, v5, v7 + + SR_COMBINE v0, v1, v2, v3, v4, v6, v5, v7, \ + v8, v9, v10, v11, v12, v13, v14, v15, \ + x7, x8, x9, 0 + + stp q2, q3, [x1, #32*1] + stp q6, q7, [x1, #32*3] + stp q10, q11, [x1, #32*5] + stp q14, q15, [x1, #32*7] + + cmp w20, #32 + b.gt 64f + + stp q0, q1, [x1, #32*0] + stp q4, q5, [x1, #32*2] + stp q8, q9, [x1, #32*4] + stp q12, q13, [x1, #32*6] + + ret +64: + SETUP_SR_RECOMB 64, x7, x8, x9 + + LOAD_INPUT 2, 3, 10, 11, x2, \no_perm, 1 + LOAD_INPUT 6, 14, 7, 15, x2, \no_perm, 1 + + FFT16 v2, v3, v10, v11, v6, v14, v7, v15 + + LOAD_INPUT 16, 17, 18, 19, x2, \no_perm + LOAD_INPUT 20, 22, 21, 23, x2, \no_perm, 1 + + FFT16 v16, v17, v18, v19, v20, v22, v21, v23, \ + v24, v25, v26, v27, v28, v29, v30 + + ld1 { v26.4s, v27.4s }, [x8], x9 + ldp q24, q25, [x7], #32 + + ext v26.16b, v26.16b, v26.16b, #8 + ext v27.16b, v27.16b, v27.16b, #8 + + cmp w19, #64 + b.eq 2f // custom deinterleave + + // TODO: investigate doing the 2 combines like in deinterleave + // TODO: experiment with spilling to gprs and converting to HALF or full + SR_COMBINE_LITE v0, v1, v8, v9, \ + v2, v3, v16, v17, \ + v24, v25, v26, v27, \ + v28, v29, v30, 0 + + stp q0, q1, [x1, #32* 0] + stp q8, q9, [x1, #32* 4] + stp q2, q3, [x1, #32* 8] + stp q16, q17, [x1, #32*12] + + SR_COMBINE_HALF v4, v5, v12, v13, \ + v6, v7, v20, v21, \ + v24, v25, v26, v27, \ + v28, v29, v30, v0, v1, v8, 1 + + stp q4, q20, [x1, #32* 2] + stp q12, q21, [x1, #32* 6] + stp q6, q5, [x1, #32*10] + stp q7, q13, [x1, #32*14] + + ldp q2, q3, [x1, #32*1] + ldp q6, q7, [x1, #32*3] + ldp q12, q13, [x1, #32*5] + ldp q16, q17, [x1, #32*7] + + SR_COMBINE v2, v3, v12, v13, v6, v16, v7, v17, \ + v10, v11, v14, v15, v18, v19, v22, v23, \ + x7, x8, x9, 0, \ + v24, v25, v26, v27, v28, v29, v30, v8, v0, v1, v4, v5 + + stp q2, q3, [x1, #32* 1] + stp q6, q7, [x1, #32* 3] + stp q12, q13, [x1, #32* 5] + stp q16, q17, [x1, #32* 7] + + stp q10, q11, [x1, #32* 9] + stp q18, q19, [x1, #32*11] + stp q14, q15, [x1, #32*13] + stp q22, q23, [x1, #32*15] + + cmp w20, #64 + b.gt 128f + ret +128: + stp x20, x30, [sp, #-16]! + mov w20, #32 + add x1, x1, #16*32 + bl 32b + add x1, x1, #8*32 + bl 32b + ldp x20, x30, [sp], #16 + sub x1, x1, #24*32 + + SETUP_SR_RECOMB 128, x7, x8, x9 + + cmp w19, #128 + b.eq 0f + + SR_COMBINE_FULL 128 + + cmp w20, #128 + b.gt 256f + ret +256: + stp x20, x30, [sp, #-16]! + mov w20, #64 + add x1, x1, #32*32 + bl 32b + add x1, x1, #16*32 + bl 32b + ldp x20, x30, [sp], #16 + sub x1, x1, #48*32 + + SETUP_SR_RECOMB 256, x7, x8, x9 + + cmp w19, #256 + b.eq 0f + + SR_COMBINE_FULL 256 + SR_COMBINE_FULL 256, 8*32 + + cmp w20, #256 + b.gt 512f + ret +512: + stp x20, x30, [sp, #-16]! + mov w20, #128 + add x1, x1, #64*32 + bl 32b + add x1, x1, #32*32 + bl 32b + ldp x20, x30, [sp], #16 + sub x1, x1, #96*32 + + SETUP_SR_RECOMB 512, x7, x8, x9 + + cmp w19, #512 + b.eq 0f + + mov x5, 4 +5125: + SR_COMBINE_FULL 512 + add x1, x1, 8*32 + subs w5, w5, 1 + b.gt 5125b + + cmp w20, #512 + b.gt 1024f + + ret +1024: + stp x20, x30, [sp, #-16]! + mov w20, #256 + add x1, x1, #96*32 + bl 32b + add x1, x1, #64*32 + bl 32b + ldp x20, x30, [sp], #16 + mov x5, #192*32 + sub x1, x1, x5 + + SETUP_SR_RECOMB 1024, x7, x8, x9 + + cmp w19, #1024 + b.eq 0f + + mov w5, 8 +10245: + SR_COMBINE_FULL 1024 + add x1, x1, 8*32 + subs w5, w5, 1 + b.gt 10245b + + cmp w20, #1024 + b.gt 2048f + + ret + +SR_TRANSFORM_DEF 2048, 4096 +SR_TRANSFORM_DEF 4096, 8192 +SR_TRANSFORM_DEF 8192, 16384 +SR_TRANSFORM_DEF 16384, 32768 +SR_TRANSFORM_DEF 32768, 65536 +SR_TRANSFORM_DEF 65536, 131072 +SR_TRANSFORM_DEF 131072 + +0: // general deinterleave loop + SR_COMBINE_DINT + add x1, x1, #32*8 + subs w19, w19, #32*4 + b.gt 0b + + ldp x19, x20, [sp, #16] + ldp d14, d15, [sp, #16*2] + ldp d12, d13, [sp, #16*3] + ldp d10, d11, [sp, #16*4] + ldp d8, d9, [sp, #16*5] + ldp x21, x22, [sp], #16*6 + + ret + +2: // special case for 64 point deinterleave + mov x10, v23.d[0] + mov x11, v23.d[1] + + SR_COMBINE_LITE v0, v1, v8, v9, \ + v2, v3, v16, v17, \ + v24, v25, v26, v27, \ + v28, v29, v30, 0 + + SR_COMBINE_HALF v4, v5, v12, v13, \ + v6, v7, v20, v21, \ + v24, v25, v26, v27, \ + v28, v29, v30, v23, v24, v26, 1 + + zip1 v23.2d, v0.2d, v4.2d + zip2 v24.2d, v0.2d, v4.2d + zip1 v25.2d, v1.2d, v20.2d + zip2 v26.2d, v1.2d, v20.2d + + zip1 v27.2d, v8.2d, v12.2d + zip2 v28.2d, v8.2d, v12.2d + zip1 v29.2d, v9.2d, v21.2d + zip2 v30.2d, v9.2d, v21.2d + + mov v20.16b, v5.16b + mov v21.16b, v7.16b + mov x12, x1 + add x13, x1, #32* 4 + add x14, x1, #32* 8 + add x15, x1, #32*12 + + zip1 v4.2d, v2.2d, v6.2d + zip2 v5.2d, v2.2d, v6.2d + zip1 v6.2d, v3.2d, v20.2d + zip2 v7.2d, v3.2d, v20.2d + + zip1 v0.2d, v16.2d, v21.2d + zip2 v1.2d, v16.2d, v21.2d + zip1 v2.2d, v17.2d, v13.2d + zip2 v3.2d, v17.2d, v13.2d + + // stp is faster by a little on A53, but this is faster on M1s (theory) + ldp q8, q9, [x1, #32*1] + ldp q12, q13, [x1, #32*5] + + st1 { v23.4s, v24.4s, v25.4s, v26.4s }, [x12], #64 // 32* 0...1 + st1 { v27.4s, v28.4s, v29.4s, v30.4s }, [x13], #64 // 32* 4...5 + st1 { v4.4s, v5.4s, v6.4s, v7.4s }, [x14], #64 // 32* 8...9 + st1 { v0.4s, v1.4s, v2.4s, v3.4s }, [x15], #64 // 32*12..13 + + mov v23.d[0], x10 + mov v23.d[1], x11 + + ldp q6, q7, [x1, #32*3] + ldp q16, q17, [x1, #32*7] + + SR_COMBINE v8, v9, v12, v13, v6, v16, v7, v17, \ + v10, v11, v14, v15, v18, v19, v22, v23, \ + x7, x8, x9, 0, \ + v24, v25, v26, v27, v28, v29, v30, v4, v0, v1, v5, v20 + + zip1 v0.2d, v8.2d, v6.2d + zip2 v1.2d, v8.2d, v6.2d + zip1 v2.2d, v9.2d, v7.2d + zip2 v3.2d, v9.2d, v7.2d + st1 { v0.4s, v1.4s, v2.4s, v3.4s }, [x12] + + zip1 v4.2d, v12.2d, v16.2d + zip2 v5.2d, v12.2d, v16.2d + zip1 v6.2d, v13.2d, v17.2d + zip2 v7.2d, v13.2d, v17.2d + st1 { v4.4s, v5.4s, v6.4s, v7.4s }, [x13] + + zip1 v0.2d, v10.2d, v18.2d + zip2 v1.2d, v10.2d, v18.2d + zip1 v2.2d, v11.2d, v19.2d + zip2 v3.2d, v11.2d, v19.2d + st1 { v0.4s, v1.4s, v2.4s, v3.4s }, [x14] + + zip1 v4.2d, v14.2d, v22.2d + zip2 v5.2d, v14.2d, v22.2d + zip1 v6.2d, v15.2d, v23.2d + zip2 v7.2d, v15.2d, v23.2d + st1 { v4.4s, v5.4s, v6.4s, v7.4s }, [x15] + + ldp x19, x20, [sp, #16] + ldp d14, d15, [sp, #16*2] + ldp d12, d13, [sp, #16*3] + ldp d10, d11, [sp, #16*4] + ldp d8, d9, [sp, #16*5] + ldp x21, x22, [sp], #16*6 + + ret +endfunc +.endm + +FFT_SPLIT_RADIX_FN float, 0 +FFT_SPLIT_RADIX_FN ns_float, 1 diff --git a/arm/raspi/third_party/ffmpeg/libavutil/adler32.c b/arm/raspi/third_party/ffmpeg/libavutil/adler32.c new file mode 100644 index 00000000..7124f188 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/adler32.c @@ -0,0 +1,96 @@ +/* + * Compute the Adler-32 checksum of a data stream. + * This is a modified version based on adler32.c from the zlib library. + * + * Copyright (C) 1995 Mark Adler + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +/** + * @file + * Computes the Adler-32 checksum of a data stream + * + * This is a modified version based on adler32.c from the zlib library. + * @author Mark Adler + * @ingroup lavu_adler32 + */ + +#include "config.h" +#include "adler32.h" +#include "intreadwrite.h" +#include "macros.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ + +#define DO1(buf) { s1 += *buf++; s2 += s1; } +#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); +#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); + +AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = adler >> 16; + + while (len > 0) { +#if HAVE_FAST_64BIT && HAVE_FAST_UNALIGNED && !CONFIG_SMALL + unsigned len2 = FFMIN((len-1) & ~7, 23*8); + if (len2) { + uint64_t a1= 0; + uint64_t a2= 0; + uint64_t b1= 0; + uint64_t b2= 0; + len -= len2; + s2 += s1*len2; + while (len2 >= 8) { + uint64_t v = AV_RN64(buf); + a2 += a1; + b2 += b1; + a1 += v &0x00FF00FF00FF00FF; + b1 += (v>>8)&0x00FF00FF00FF00FF; + len2 -= 8; + buf+=8; + } + + //We combine the 8 interleaved adler32 checksums without overflows + //Decreasing the number of iterations would allow below code to be + //simplified but would likely be slower due to the fewer iterations + //of the inner loop + s1 += ((a1+b1)*0x1000100010001)>>48; + s2 += ((((a2&0xFFFF0000FFFF)+(b2&0xFFFF0000FFFF)+((a2>>16)&0xFFFF0000FFFF)+((b2>>16)&0xFFFF0000FFFF))*0x800000008)>>32) +#if HAVE_BIGENDIAN + + 2*((b1*0x1000200030004)>>48) + + ((a1*0x1000100010001)>>48) + + 2*((a1*0x0000100020003)>>48); +#else + + 2*((a1*0x4000300020001)>>48) + + ((b1*0x1000100010001)>>48) + + 2*((b1*0x3000200010000)>>48); +#endif + } +#else + while (len > 4 && s2 < (1U << 31)) { + DO4(buf); + len -= 4; + } +#endif + DO1(buf); len--; + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/adler32.h b/arm/raspi/third_party/ffmpeg/libavutil/adler32.h new file mode 100644 index 00000000..232d07f5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/adler32.h @@ -0,0 +1,63 @@ +/* + * copyright (c) 2006 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_adler32 + * Public header for Adler-32 hash function implementation. + */ + +#ifndef AVUTIL_ADLER32_H +#define AVUTIL_ADLER32_H + +#include +#include +#include "attributes.h" + +/** + * @defgroup lavu_adler32 Adler-32 + * @ingroup lavu_hash + * Adler-32 hash function implementation. + * + * @{ + */ + +typedef uint32_t AVAdler; + +/** + * Calculate the Adler32 checksum of a buffer. + * + * Passing the return value to a subsequent av_adler32_update() call + * allows the checksum of multiple buffers to be calculated as though + * they were concatenated. + * + * @param adler initial checksum value + * @param buf pointer to input buffer + * @param len size of input buffer + * @return updated checksum + */ +AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, + size_t len) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_ADLER32_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aes.c b/arm/raspi/third_party/ffmpeg/libavutil/aes.c new file mode 100644 index 00000000..2f08fb41 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aes.c @@ -0,0 +1,274 @@ +/* + * copyright (c) 2007 Michael Niedermayer + * + * some optimization ideas from aes128.c by Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "aes.h" +#include "aes_internal.h" +#include "error.h" +#include "intreadwrite.h" +#include "macros.h" +#include "mem.h" + +const int av_aes_size= sizeof(AVAES); + +struct AVAES *av_aes_alloc(void) +{ + return av_mallocz(sizeof(struct AVAES)); +} + +static const uint8_t rcon[10] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +}; + +static uint8_t sbox[256]; +static uint8_t inv_sbox[256]; +#if CONFIG_SMALL +static uint32_t enc_multbl[1][256]; +static uint32_t dec_multbl[1][256]; +#else +static uint32_t enc_multbl[4][256]; +static uint32_t dec_multbl[4][256]; +#endif + +#if HAVE_BIGENDIAN +# define ROT(x, s) (((x) >> (s)) | ((x) << (32-(s)))) +#else +# define ROT(x, s) (((x) << (s)) | ((x) >> (32-(s)))) +#endif + +static inline void addkey(av_aes_block *dst, const av_aes_block *src, + const av_aes_block *round_key) +{ + dst->u64[0] = src->u64[0] ^ round_key->u64[0]; + dst->u64[1] = src->u64[1] ^ round_key->u64[1]; +} + +static inline void addkey_s(av_aes_block *dst, const uint8_t *src, + const av_aes_block *round_key) +{ + dst->u64[0] = AV_RN64(src) ^ round_key->u64[0]; + dst->u64[1] = AV_RN64(src + 8) ^ round_key->u64[1]; +} + +static inline void addkey_d(uint8_t *dst, const av_aes_block *src, + const av_aes_block *round_key) +{ + AV_WN64(dst, src->u64[0] ^ round_key->u64[0]); + AV_WN64(dst + 8, src->u64[1] ^ round_key->u64[1]); +} + +static void subshift(av_aes_block s0[2], int s, const uint8_t *box) +{ + unsigned char *s1_dst = (unsigned char*)s0[0].u8 + 3 - s; + const unsigned char *s1_src = s1_dst + sizeof(*s0); + unsigned char *s3_dst = (unsigned char*)s0[0].u8 + s + 1; + const unsigned char *s3_src = s3_dst + sizeof(*s0); + + s0[0].u8[ 0] = box[s0[1].u8[ 0]]; + s0[0].u8[ 4] = box[s0[1].u8[ 4]]; + s0[0].u8[ 8] = box[s0[1].u8[ 8]]; + s0[0].u8[12] = box[s0[1].u8[12]]; + s1_dst[ 0] = box[s1_src[ 4]]; + s1_dst[ 4] = box[s1_src[ 8]]; + s1_dst[ 8] = box[s1_src[12]]; + s1_dst[12] = box[s1_src[ 0]]; + s0[0].u8[ 2] = box[s0[1].u8[10]]; + s0[0].u8[10] = box[s0[1].u8[ 2]]; + s0[0].u8[ 6] = box[s0[1].u8[14]]; + s0[0].u8[14] = box[s0[1].u8[ 6]]; + s3_dst[ 0] = box[s3_src[12]]; + s3_dst[12] = box[s3_src[ 8]]; + s3_dst[ 8] = box[s3_src[ 4]]; + s3_dst[ 4] = box[s3_src[ 0]]; +} + +static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d) +{ +#if CONFIG_SMALL + return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24); +#else + return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d]; +#endif +} + +static inline void mix(av_aes_block state[2], uint32_t multbl[][256], int s1, int s3) +{ + uint8_t (*src)[4] = state[1].u8x4; + state[0].u32[0] = mix_core(multbl, src[0][0], src[s1 ][1], src[2][2], src[s3 ][3]); + state[0].u32[1] = mix_core(multbl, src[1][0], src[s3 - 1][1], src[3][2], src[s1 - 1][3]); + state[0].u32[2] = mix_core(multbl, src[2][0], src[s3 ][1], src[0][2], src[s1 ][3]); + state[0].u32[3] = mix_core(multbl, src[3][0], src[s1 - 1][1], src[1][2], src[s3 - 1][3]); +} + +static inline void aes_crypt(AVAES *a, int s, const uint8_t *sbox, + uint32_t multbl[][256]) +{ + int r; + + for (r = a->rounds - 1; r > 0; r--) { + mix(a->state, multbl, 3 - s, 1 + s); + addkey(&a->state[1], &a->state[0], &a->round_key[r]); + } + + subshift(&a->state[0], s, sbox); +} + +static void aes_encrypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds) +{ + while (count--) { + addkey_s(&a->state[1], src, &a->round_key[rounds]); + if (iv) + addkey_s(&a->state[1], iv, &a->state[1]); + aes_crypt(a, 2, sbox, enc_multbl); + addkey_d(dst, &a->state[0], &a->round_key[0]); + if (iv) + memcpy(iv, dst, 16); + src += 16; + dst += 16; + } +} + +static void aes_decrypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds) +{ + while (count--) { + addkey_s(&a->state[1], src, &a->round_key[rounds]); + aes_crypt(a, 0, inv_sbox, dec_multbl); + if (iv) { + addkey_s(&a->state[0], iv, &a->state[0]); + memcpy(iv, src, 16); + } + addkey_d(dst, &a->state[0], &a->round_key[0]); + src += 16; + dst += 16; + } +} + +void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + a->crypt(a, dst, src, count, iv, a->rounds); +} + +static void init_multbl2(uint32_t tbl[][256], const int c[4], + const uint8_t *log8, const uint8_t *alog8, + const uint8_t *sbox) +{ + int i; + + for (i = 0; i < 256; i++) { + int x = sbox[i]; + if (x) { + int k, l, m, n; + x = log8[x]; + k = alog8[x + log8[c[0]]]; + l = alog8[x + log8[c[1]]]; + m = alog8[x + log8[c[2]]]; + n = alog8[x + log8[c[3]]]; + tbl[0][i] = AV_NE(MKBETAG(k, l, m, n), MKTAG(k, l, m, n)); +#if !CONFIG_SMALL + tbl[1][i] = ROT(tbl[0][i], 8); + tbl[2][i] = ROT(tbl[0][i], 16); + tbl[3][i] = ROT(tbl[0][i], 24); +#endif + } + } +} + +// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen +int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) +{ + int i, j, t, rconpointer = 0; + uint8_t tk[8][4]; + int KC = key_bits >> 5; + int rounds = KC + 6; + uint8_t log8[256]; + uint8_t alog8[512]; + + a->crypt = decrypt ? aes_decrypt : aes_encrypt; + + if (!enc_multbl[FF_ARRAY_ELEMS(enc_multbl) - 1][FF_ARRAY_ELEMS(enc_multbl[0]) - 1]) { + j = 1; + for (i = 0; i < 255; i++) { + alog8[i] = alog8[i + 255] = j; + log8[j] = i; + j ^= j + j; + if (j > 255) + j ^= 0x11B; + } + for (i = 0; i < 256; i++) { + j = i ? alog8[255 - log8[i]] : 0; + j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4); + j = (j ^ (j >> 8) ^ 99) & 255; + inv_sbox[j] = i; + sbox[i] = j; + } + init_multbl2(dec_multbl, (const int[4]) { 0xe, 0x9, 0xd, 0xb }, + log8, alog8, inv_sbox); + init_multbl2(enc_multbl, (const int[4]) { 0x2, 0x1, 0x1, 0x3 }, + log8, alog8, sbox); + } + + if (key_bits != 128 && key_bits != 192 && key_bits != 256) + return AVERROR(EINVAL); + + a->rounds = rounds; + + memcpy(tk, key, KC * 4); + memcpy(a->round_key[0].u8, key, KC * 4); + + for (t = KC * 4; t < (rounds + 1) * 16; t += KC * 4) { + for (i = 0; i < 4; i++) + tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]]; + tk[0][0] ^= rcon[rconpointer++]; + + for (j = 1; j < KC; j++) { + if (KC != 8 || j != KC >> 1) + for (i = 0; i < 4; i++) + tk[j][i] ^= tk[j - 1][i]; + else + for (i = 0; i < 4; i++) + tk[j][i] ^= sbox[tk[j - 1][i]]; + } + + memcpy((unsigned char*)a->round_key + t, tk, KC * 4); + } + + if (decrypt) { + for (i = 1; i < rounds; i++) { + av_aes_block tmp[3]; + tmp[2] = a->round_key[i]; + subshift(&tmp[1], 0, sbox); + mix(tmp, dec_multbl, 1, 3); + a->round_key[i] = tmp[0]; + } + } else { + for (i = 0; i < (rounds + 1) >> 1; i++) + FFSWAP(av_aes_block, a->round_key[i], a->round_key[rounds - i]); + } + + return 0; +} + diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aes.h b/arm/raspi/third_party/ffmpeg/libavutil/aes.h new file mode 100644 index 00000000..4e734736 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aes.h @@ -0,0 +1,69 @@ +/* + * copyright (c) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_H +#define AVUTIL_AES_H + +#include + +#include "attributes.h" + +/** + * @defgroup lavu_aes AES + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_aes_size; + +struct AVAES; + +/** + * Allocate an AVAES context. + */ +struct AVAES *av_aes_alloc(void); + +/** + * Initialize an AVAES context. + * + * @param a The AVAES context + * @param key Pointer to the key + * @param key_bits 128, 192 or 256 + * @param decrypt 0 for encryption, 1 for decryption + */ +int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param a The AVAES context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_AES_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.c b/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.c new file mode 100644 index 00000000..c2d6d570 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.c @@ -0,0 +1,131 @@ +/* + * AES-CTR cipher + * Copyright (c) 2015 Eran Kornblau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "aes_ctr.h" +#include "aes.h" +#include "aes_internal.h" +#include "macros.h" +#include "mem.h" +#include "random_seed.h" + +#define AES_BLOCK_SIZE (16) + +typedef struct AVAESCTR { + uint8_t counter[AES_BLOCK_SIZE]; + uint8_t encrypted_counter[AES_BLOCK_SIZE]; + int block_offset; + AVAES aes; +} AVAESCTR; + +struct AVAESCTR *av_aes_ctr_alloc(void) +{ + return av_mallocz(sizeof(struct AVAESCTR)); +} + +void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv) +{ + memcpy(a->counter, iv, AES_CTR_IV_SIZE); + memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); + a->block_offset = 0; +} + +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv) +{ + memcpy(a->counter, iv, sizeof(a->counter)); + a->block_offset = 0; +} + +const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a) +{ + return a->counter; +} + +void av_aes_ctr_set_random_iv(struct AVAESCTR *a) +{ + uint32_t iv[2]; + + iv[0] = av_get_random_seed(); + iv[1] = av_get_random_seed(); + + av_aes_ctr_set_iv(a, (uint8_t*)iv); +} + +int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key) +{ + av_aes_init(&a->aes, key, 128, 0); + + memset(a->counter, 0, sizeof(a->counter)); + a->block_offset = 0; + + return 0; +} + +void av_aes_ctr_free(struct AVAESCTR *a) +{ + av_free(a); +} + +static void av_aes_ctr_increment_be64(uint8_t* counter) +{ + uint8_t* cur_pos; + + for (cur_pos = counter + 7; cur_pos >= counter; cur_pos--) { + (*cur_pos)++; + if (*cur_pos != 0) { + break; + } + } +} + +void av_aes_ctr_increment_iv(struct AVAESCTR *a) +{ + av_aes_ctr_increment_be64(a->counter); + memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); + a->block_offset = 0; +} + +void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count) +{ + const uint8_t* src_end = src + count; + const uint8_t* cur_end_pos; + uint8_t* encrypted_counter_pos; + + while (src < src_end) { + if (a->block_offset == 0) { + av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); + + av_aes_ctr_increment_be64(a->counter + 8); + } + + encrypted_counter_pos = a->encrypted_counter + a->block_offset; + cur_end_pos = src + AES_BLOCK_SIZE - a->block_offset; + cur_end_pos = FFMIN(cur_end_pos, src_end); + + a->block_offset += cur_end_pos - src; + a->block_offset &= (AES_BLOCK_SIZE - 1); + + while (src < cur_end_pos) { + *dst++ = *src++ ^ *encrypted_counter_pos++; + } + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.h b/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.h new file mode 100644 index 00000000..d98c0712 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aes_ctr.h @@ -0,0 +1,99 @@ +/* + * AES-CTR cipher + * Copyright (c) 2015 Eran Kornblau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_CTR_H +#define AVUTIL_AES_CTR_H + +/** + * @defgroup lavu_aes_ctr AES-CTR + * @ingroup lavu_crypto + * @{ + */ + +#include + +#include "attributes.h" + +#define AES_CTR_KEY_SIZE (16) +#define AES_CTR_IV_SIZE (8) + +struct AVAESCTR; + +/** + * Allocate an AVAESCTR context. + */ +struct AVAESCTR *av_aes_ctr_alloc(void); + +/** + * Initialize an AVAESCTR context. + * + * @param a The AVAESCTR context to initialize + * @param key encryption key, must have a length of AES_CTR_KEY_SIZE + */ +int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key); + +/** + * Release an AVAESCTR context. + * + * @param a The AVAESCTR context + */ +void av_aes_ctr_free(struct AVAESCTR *a); + +/** + * Process a buffer using a previously initialized context. + * + * @param a The AVAESCTR context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param size the size of src and dst + */ +void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int size); + +/** + * Get the current iv + */ +const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a); + +/** + * Generate a random iv + */ +void av_aes_ctr_set_random_iv(struct AVAESCTR *a); + +/** + * Forcefully change the 8-byte iv + */ +void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Forcefully change the "full" 16-byte iv, including the counter + */ +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Increment the top 64 bit of the iv (performed after each frame) + */ +void av_aes_ctr_increment_iv(struct AVAESCTR *a); + +/** + * @} + */ + +#endif /* AVUTIL_AES_CTR_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/aes_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/aes_internal.h new file mode 100644 index 00000000..c9d6c248 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/aes_internal.h @@ -0,0 +1,43 @@ +/* + * copyright (c) 2015 rcombs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_INTERNAL_H +#define AVUTIL_AES_INTERNAL_H + +#include "mem_internal.h" +#include + +typedef union { + uint64_t u64[2]; + uint32_t u32[4]; + uint8_t u8x4[4][4]; + uint8_t u8[16]; +} av_aes_block; + +typedef struct AVAES { + // Note: round_key[16] is accessed in the init code, but this only + // overwrites state, which does not matter (see also commit ba554c0). + DECLARE_ALIGNED(16, av_aes_block, round_key)[15]; + DECLARE_ALIGNED(16, av_aes_block, state)[2]; + int rounds; + void (*crypt)(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int rounds); +} AVAES; + +#endif /* AVUTIL_AES_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.c b/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.c new file mode 100644 index 00000000..c47458cf --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Jan Ekström + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ambient_viewing_environment.h" +#include "mem.h" + +AVAmbientViewingEnvironment *av_ambient_viewing_environment_alloc(size_t *size) +{ + AVAmbientViewingEnvironment *env = + av_mallocz(sizeof(AVAmbientViewingEnvironment)); + if (!env) + return NULL; + + if (size) + *size = sizeof(*env); + + return env; +} + +AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = + av_frame_new_side_data(frame, + AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, + sizeof(AVAmbientViewingEnvironment)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, side_data->size); + + return (AVAmbientViewingEnvironment *)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.h b/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.h new file mode 100644 index 00000000..e5e4ac21 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ambient_viewing_environment.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023 Jan Ekström + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AMBIENT_VIEWING_ENVIRONMENT_H +#define AVUTIL_AMBIENT_VIEWING_ENVIRONMENT_H + +#include +#include "frame.h" +#include "rational.h" + +/** + * Ambient viewing environment metadata as defined by H.274. The values are + * saved in AVRationals so that they keep their exactness, while allowing for + * easy access to a double value with f.ex. av_q2d. + * + * @note sizeof(AVAmbientViewingEnvironment) is not part of the public ABI, and + * it must be allocated using av_ambient_viewing_environment_alloc. + */ +typedef struct AVAmbientViewingEnvironment { + /** + * Environmental illuminance of the ambient viewing environment in lux. + */ + AVRational ambient_illuminance; + + /** + * Normalized x chromaticity coordinate of the environmental ambient light + * in the nominal viewing environment according to the CIE 1931 definition + * of x and y as specified in ISO/CIE 11664-1. + */ + AVRational ambient_light_x; + + /** + * Normalized y chromaticity coordinate of the environmental ambient light + * in the nominal viewing environment according to the CIE 1931 definition + * of x and y as specified in ISO/CIE 11664-1. + */ + AVRational ambient_light_y; +} AVAmbientViewingEnvironment; + +/** + * Allocate an AVAmbientViewingEnvironment structure. + * + * @return the newly allocated struct or NULL on failure + */ +AVAmbientViewingEnvironment *av_ambient_viewing_environment_alloc(size_t *size); + +/** + * Allocate and add an AVAmbientViewingEnvironment structure to an existing + * AVFrame as side data. + * + * @return the newly allocated struct, or NULL on failure + */ +AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_AMBIENT_VIEWING_ENVIRONMENT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/arm/Makefile new file mode 100644 index 00000000..5da44b05 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/Makefile @@ -0,0 +1,8 @@ +OBJS += arm/cpu.o \ + arm/float_dsp_init_arm.o \ + +VFP-OBJS += arm/float_dsp_init_vfp.o \ + arm/float_dsp_vfp.o \ + +NEON-OBJS += arm/float_dsp_init_neon.o \ + arm/float_dsp_neon.o \ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/asm.S b/arm/raspi/third_party/ffmpeg/libavutil/arm/asm.S new file mode 100644 index 00000000..e3a8c7f0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/asm.S @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#ifdef __ELF__ +# define ELF +#else +# define ELF @ +#endif + +#if CONFIG_THUMB +# define A @ +# define T +#else +# define A +# define T @ +#endif + +#if HAVE_AS_FUNC +# define FUNC +#else +# define FUNC @ +#endif + +#if HAVE_AS_FPU_DIRECTIVE +# define FPU +#else +# define FPU @ +#endif + +#if CONFIG_THUMB && defined(__APPLE__) +# define TFUNC +#else +# define TFUNC @ +#endif + +#if HAVE_AS_ARCH_DIRECTIVE +#if HAVE_NEON + .arch armv7-a +#elif HAVE_ARMV6T2 + .arch armv6t2 +#elif HAVE_ARMV6 + .arch armv6 +#elif HAVE_ARMV5TE + .arch armv5te +#endif +#endif +#if HAVE_AS_OBJECT_ARCH +ELF .object_arch armv4 +#endif + +#if HAVE_NEON +FPU .fpu neon +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch +ELF .eabi_attribute 12, 0 @ suppress Tag_Advanced_SIMD_arch +#elif HAVE_VFP +FPU .fpu vfp +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch +#endif + + .syntax unified +T .thumb +ELF .eabi_attribute 25, 1 @ Tag_ABI_align_preserved +ELF .section .note.GNU-stack,"",%progbits @ Mark stack as non-executable + +.macro function name, export=0, align=2 + .set .Lpic_idx, 0 + .set .Lpic_gp, 0 + .macro endfunc + .if .Lpic_idx + .align 2 + .altmacro + put_pic %(.Lpic_idx - 1) + .noaltmacro + .endif + .if .Lpic_gp + .unreq gp + .endif +ELF .size \name, . - \name +FUNC .endfunc + .purgem endfunc + .endm + .text + .align \align + .if \export + .global EXTERN_ASM\name +ELF .type EXTERN_ASM\name, %function +FUNC .func EXTERN_ASM\name +TFUNC .thumb_func EXTERN_ASM\name +EXTERN_ASM\name: + .else +ELF .type \name, %function +FUNC .func \name +TFUNC .thumb_func \name +\name: + .endif +.endm + +.macro const name, align=2, relocate=0 + .macro endconst +ELF .size \name, . - \name + .purgem endconst + .endm +#if HAVE_SECTION_DATA_REL_RO +.if \relocate + .section .data.rel.ro +.else + .section .rodata +.endif +#elif defined(_WIN32) + .section .rdata +#elif !defined(__MACH__) + .section .rodata +#else + .const_data +#endif + .align \align +\name: +.endm + +#if !HAVE_ARMV6T2_EXTERNAL +.macro movw rd, val + mov \rd, \val & 255 + orr \rd, \val & ~255 +.endm +#endif + +.macro mov32 rd, val +#if HAVE_ARMV6T2_EXTERNAL + movw \rd, #(\val) & 0xffff + .if (\val) >> 16 + movt \rd, #(\val) >> 16 + .endif +#else + ldr \rd, =\val +#endif +.endm + +.macro put_pic num + put_pic_\num +.endm + +.macro do_def_pic num, val, label + .macro put_pic_\num + .if \num + .altmacro + put_pic %(\num - 1) + .noaltmacro + .endif +\label: .word \val + .purgem put_pic_\num + .endm +.endm + +.macro def_pic val, label + .altmacro + do_def_pic %.Lpic_idx, \val, \label + .noaltmacro + .set .Lpic_idx, .Lpic_idx + 1 +.endm + +.macro ldpic rd, val, indir=0 + ldr \rd, .Lpicoff\@ +.Lpic\@: + .if \indir +A ldr \rd, [pc, \rd] +T add \rd, pc +T ldr \rd, [\rd] + .else + add \rd, pc + .endif + def_pic \val - (.Lpic\@ + (8 >> CONFIG_THUMB)), .Lpicoff\@ +.endm + +.macro movrel rd, val +#if CONFIG_PIC + ldpic \rd, \val +#elif HAVE_ARMV6T2_EXTERNAL && !defined(__APPLE__) + movw \rd, #:lower16:\val + movt \rd, #:upper16:\val +#else + ldr \rd, =\val +#endif +.endm + +.macro movrelx rd, val, gp + .ifc \rd,\gp + .error "movrelx needs two distinct registers" + .endif + .ifc \rd\()_\gp,r12_ + .warning "movrelx rd=\rd without explicit set gp" + .endif + .ifc \rd\()_\gp,ip_ + .warning "movrelx rd=\rd without explicit set gp" + .endif +#if CONFIG_PIC && defined(__ELF__) + .ifnb \gp + .if .Lpic_gp + .unreq gp + .endif + gp .req \gp + ldpic gp, _GLOBAL_OFFSET_TABLE_ + .elseif !.Lpic_gp + gp .req r12 + ldpic gp, _GLOBAL_OFFSET_TABLE_ + .endif + .set .Lpic_gp, 1 + ldr \rd, .Lpicoff\@ + ldr \rd, [gp, \rd] + def_pic \val(GOT), .Lpicoff\@ +#elif CONFIG_PIC && defined(__APPLE__) + ldpic \rd, .Lpic\@, indir=1 + .non_lazy_symbol_pointer +.Lpic\@: + .indirect_symbol \val + .word 0 + .text +#else + movrel \rd, \val +#endif +.endm + +.macro add_sh rd, rn, rm, sh:vararg +A add \rd, \rn, \rm, \sh +T mov \rm, \rm, \sh +T add \rd, \rn, \rm +.endm + +.macro ldr_pre rt, rn, rm:vararg +A ldr \rt, [\rn, \rm]! +T add \rn, \rn, \rm +T ldr \rt, [\rn] +.endm + +.macro ldr_dpre rt, rn, rm:vararg +A ldr \rt, [\rn, -\rm]! +T sub \rn, \rn, \rm +T ldr \rt, [\rn] +.endm + +.macro ldr_nreg rt, rn, rm:vararg +A ldr \rt, [\rn, -\rm] +T sub \rt, \rn, \rm +T ldr \rt, [\rt] +.endm + +.macro ldr_post rt, rn, rm:vararg +A ldr \rt, [\rn], \rm +T ldr \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro ldrc_pre cc, rt, rn, rm:vararg +A ldr\cc \rt, [\rn, \rm]! +T itt \cc +T add\cc \rn, \rn, \rm +T ldr\cc \rt, [\rn] +.endm + +.macro ldrd_reg rt, rt2, rn, rm +A ldrd \rt, \rt2, [\rn, \rm] +T add \rt, \rn, \rm +T ldrd \rt, \rt2, [\rt] +.endm + +.macro ldrd_post rt, rt2, rn, rm +A ldrd \rt, \rt2, [\rn], \rm +T ldrd \rt, \rt2, [\rn] +T add \rn, \rn, \rm +.endm + +.macro ldrh_pre rt, rn, rm +A ldrh \rt, [\rn, \rm]! +T add \rn, \rn, \rm +T ldrh \rt, [\rn] +.endm + +.macro ldrh_dpre rt, rn, rm +A ldrh \rt, [\rn, -\rm]! +T sub \rn, \rn, \rm +T ldrh \rt, [\rn] +.endm + +.macro ldrh_post rt, rn, rm +A ldrh \rt, [\rn], \rm +T ldrh \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro ldrb_post rt, rn, rm +A ldrb \rt, [\rn], \rm +T ldrb \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro str_post rt, rn, rm:vararg +A str \rt, [\rn], \rm +T str \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro strb_post rt, rn, rm:vararg +A strb \rt, [\rn], \rm +T strb \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro strd_post rt, rt2, rn, rm +A strd \rt, \rt2, [\rn], \rm +T strd \rt, \rt2, [\rn] +T add \rn, \rn, \rm +.endm + +.macro strh_pre rt, rn, rm +A strh \rt, [\rn, \rm]! +T add \rn, \rn, \rm +T strh \rt, [\rn] +.endm + +.macro strh_dpre rt, rn, rm +A strh \rt, [\rn, -\rm]! +T sub \rn, \rn, \rm +T strh \rt, [\rn] +.endm + +.macro strh_post rt, rn, rm +A strh \rt, [\rn], \rm +T strh \rt, [\rn] +T add \rn, \rn, \rm +.endm + +.macro strh_dpost rt, rn, rm +A strh \rt, [\rn], -\rm +T strh \rt, [\rn] +T sub \rn, \rn, \rm +.endm + +#if HAVE_VFP_ARGS +ELF .eabi_attribute 28, 1 +# define VFP +# define NOVFP @ +#else +# define VFP @ +# define NOVFP +#endif + +#define GLUE(a, b) a ## b +#define JOIN(a, b) GLUE(a, b) +#define X(s) JOIN(EXTERN_ASM, s) diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/autorename_libavutil_arm_cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/arm/autorename_libavutil_arm_cpu.c new file mode 100644 index 00000000..3adbdc6f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/autorename_libavutil_arm_cpu.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "cpu.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/bswap.h new file mode 100644 index 00000000..c3460e03 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/bswap.h @@ -0,0 +1,70 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_BSWAP_H +#define AVUTIL_ARM_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#ifdef __ARMCC_VERSION + +#if HAVE_ARMV6 +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return __rev(x); +} +#endif /* HAVE_ARMV6 */ + +#elif HAVE_INLINE_ASM + +#if HAVE_ARMV6_INLINE +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + unsigned y; + + __asm__("rev16 %0, %1" : "=r"(y) : "r"(x)); + return y; +} +#endif + +#if AV_GCC_VERSION_AT_MOST(4,4) +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + uint32_t y; +#if HAVE_ARMV6_INLINE + __asm__("rev %0, %1" : "=r"(y) : "r"(x)); +#else + uint32_t t; + __asm__ ("eor %1, %2, %2, ror #16 \n\t" + "bic %1, %1, #0xFF0000 \n\t" + "mov %0, %2, ror #8 \n\t" + "eor %0, %0, %1, lsr #8 \n\t" + : "=r"(y), "=&r"(t) : "r"(x)); +#endif /* HAVE_ARMV6_INLINE */ + return y; +} +#endif /* AV_GCC_VERSION_AT_MOST(4,4) */ + +#endif /* __ARMCC_VERSION */ + +#endif /* AVUTIL_ARM_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.c new file mode 100644 index 00000000..c84a655c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.c @@ -0,0 +1,188 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "config.h" + +#define CORE_FLAG(f) \ + (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE)) + +#define CORE_CPU_FLAGS \ + (CORE_FLAG(ARMV5TE) | \ + CORE_FLAG(ARMV6) | \ + CORE_FLAG(ARMV6T2) | \ + CORE_FLAG(VFP) | \ + CORE_FLAG(VFPV3) | \ + CORE_FLAG(NEON)) + +#if defined __linux__ || defined __ANDROID__ + +#include +#include +#include +#include "libavutil/avstring.h" + +#if HAVE_GETAUXVAL +#include +#endif + +#define AT_HWCAP 16 + +/* Relevant HWCAP values from kernel headers */ +#define HWCAP_VFP (1 << 6) +#define HWCAP_EDSP (1 << 7) +#define HWCAP_THUMBEE (1 << 11) +#define HWCAP_NEON (1 << 12) +#define HWCAP_VFPv3 (1 << 13) +#define HWCAP_TLS (1 << 15) + +static int get_auxval(uint32_t *hwcap) +{ +#if HAVE_GETAUXVAL + unsigned long ret = getauxval(AT_HWCAP); + if (ret == 0) + return -1; + *hwcap = ret; + return 0; +#else + return -1; +#endif +} + +static int get_hwcap(uint32_t *hwcap) +{ + struct { uint32_t a_type; uint32_t a_val; } auxv; + FILE *f = fopen("/proc/self/auxv", "r"); + int err = -1; + + if (!f) + return -1; + + while (fread(&auxv, sizeof(auxv), 1, f) > 0) { + if (auxv.a_type == AT_HWCAP) { + *hwcap = auxv.a_val; + err = 0; + break; + } + } + + fclose(f); + return err; +} + +static int get_cpuinfo(uint32_t *hwcap) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + + if (!f) + return -1; + + *hwcap = 0; + while (fgets(buf, sizeof(buf), f)) { + if (av_strstart(buf, "Features", NULL)) { + if (strstr(buf, " edsp ")) + *hwcap |= HWCAP_EDSP; + if (strstr(buf, " tls ")) + *hwcap |= HWCAP_TLS; + if (strstr(buf, " thumbee ")) + *hwcap |= HWCAP_THUMBEE; + if (strstr(buf, " vfp ")) + *hwcap |= HWCAP_VFP; + if (strstr(buf, " vfpv3 ")) + *hwcap |= HWCAP_VFPv3; + if (strstr(buf, " neon ") || strstr(buf, " asimd ")) + *hwcap |= HWCAP_NEON; + if (strstr(buf, " fp ")) // Listed on 64 bit ARMv8 kernels + *hwcap |= HWCAP_VFP | HWCAP_VFPv3; + break; + } + } + fclose(f); + return 0; +} + +int ff_get_cpu_flags_arm(void) +{ + int flags = CORE_CPU_FLAGS; + uint32_t hwcap; + + if (get_auxval(&hwcap) < 0) + if (get_hwcap(&hwcap) < 0) + if (get_cpuinfo(&hwcap) < 0) + return flags; + +#define check_cap(cap, flag) do { \ + if (hwcap & HWCAP_ ## cap) \ + flags |= AV_CPU_FLAG_ ## flag; \ + } while (0) + + /* No flags explicitly indicate v6 or v6T2 so check others which + imply support. */ + check_cap(EDSP, ARMV5TE); + check_cap(TLS, ARMV6); + check_cap(THUMBEE, ARMV6T2); + check_cap(VFP, VFP); + check_cap(VFPv3, VFPV3); + check_cap(NEON, NEON); + + /* The v6 checks above are not reliable so let higher flags + trickle down. */ + if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) + flags |= AV_CPU_FLAG_ARMV6T2; + else if (flags & (AV_CPU_FLAG_ARMV6T2 | AV_CPU_FLAG_ARMV6)) + /* Some functions use the 'setend' instruction which is deprecated on ARMv8 + * and serializing on some ARMv7 cores. This ensures such functions + * are only enabled on ARMv6. */ + flags |= AV_CPU_FLAG_SETEND; + + if (flags & AV_CPU_FLAG_ARMV6T2) + flags |= AV_CPU_FLAG_ARMV6; + + /* set the virtual VFPv2 vector mode flag */ + if ((flags & AV_CPU_FLAG_VFP) && !(flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))) + flags |= AV_CPU_FLAG_VFP_VM; + + return flags; +} + +#else + +int ff_get_cpu_flags_arm(void) +{ + return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE | + AV_CPU_FLAG_ARMV6 * HAVE_ARMV6 | + AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 | + AV_CPU_FLAG_VFP * HAVE_VFP | + AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 | + AV_CPU_FLAG_NEON * HAVE_NEON | + AV_CPU_FLAG_SETEND * !(HAVE_NEON | HAVE_VFPV3); +} + +#endif + +size_t ff_get_cpu_max_align_arm(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.h new file mode 100644 index 00000000..1d6cc65d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/cpu.h @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_CPU_H +#define AVUTIL_ARM_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_armv5te(flags) CPUEXT(flags, ARMV5TE) +#define have_armv6(flags) CPUEXT(flags, ARMV6) +#define have_armv6t2(flags) CPUEXT(flags, ARMV6T2) +#define have_vfp(flags) CPUEXT(flags, VFP) +#define have_vfpv3(flags) CPUEXT(flags, VFPV3) +#define have_neon(flags) CPUEXT(flags, NEON) +#define have_setend(flags) CPUEXT(flags, SETEND) + +/* some functions use the VFPv2 vector mode which is deprecated in ARMv7-A + * and might trap on such CPU depending on the OS configuration */ +#define have_vfp_vm(flags) \ + (HAVE_VFP && ((flags) & AV_CPU_FLAG_VFP_VM)) + +#endif /* AVUTIL_ARM_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_arm.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_arm.h new file mode 100644 index 00000000..fe311cc0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_arm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_FLOAT_DSP_ARM_H +#define AVUTIL_ARM_FLOAT_DSP_ARM_H + +#include "libavutil/float_dsp.h" + +void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags); +void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp); + +#endif /* AVUTIL_ARM_FLOAT_DSP_ARM_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_arm.c b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_arm.c new file mode 100644 index 00000000..67876286 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_arm.c @@ -0,0 +1,32 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "float_dsp_arm.h" + +av_cold void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_vfp(cpu_flags)) + ff_float_dsp_init_vfp(fdsp, cpu_flags); + if (have_neon(cpu_flags)) + ff_float_dsp_init_neon(fdsp); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_neon.c b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_neon.c new file mode 100644 index 00000000..689aa77c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_neon.c @@ -0,0 +1,59 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "float_dsp_arm.h" + +void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len); + +void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_window_neon(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_neon(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_neon(float *v1, float *v2, int len); + +float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); + +av_cold void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) +{ + fdsp->vector_fmul = ff_vector_fmul_neon; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; + fdsp->vector_fmul_window = ff_vector_fmul_window_neon; + fdsp->vector_fmul_add = ff_vector_fmul_add_neon; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon; + fdsp->butterflies_float = ff_butterflies_float_neon; + fdsp->scalarproduct_float = ff_scalarproduct_float_neon; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_vfp.c b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_vfp.c new file mode 100644 index 00000000..05873e7e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_init_vfp.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008 Siarhei Siamashka + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "float_dsp_arm.h" + +void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_fmul_window_vfp(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_vfp(float *av_restrict v1, float *av_restrict v2, int len); + +av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags) +{ + if (have_vfp_vm(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_vfp; + fdsp->vector_fmul_window = ff_vector_fmul_window_vfp; + } + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp; + if (have_vfp_vm(cpu_flags)) + fdsp->butterflies_float = ff_butterflies_float_vfp; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_neon.S b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_neon.S new file mode 100644 index 00000000..38232276 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_neon.S @@ -0,0 +1,271 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "asm.S" + +function ff_vector_fmul_neon, export=1 + subs r3, r3, #8 + vld1.32 {d0-d3}, [r1,:128]! + vld1.32 {d4-d7}, [r2,:128]! + vmul.f32 q8, q0, q2 + vmul.f32 q9, q1, q3 + beq 3f + bics ip, r3, #15 + beq 2f +1: subs ip, ip, #16 + vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! + vmul.f32 q10, q0, q2 + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! + vmul.f32 q11, q1, q3 + vst1.32 {d16-d19},[r0,:128]! + vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! + vmul.f32 q8, q0, q2 + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! + vmul.f32 q9, q1, q3 + vst1.32 {d20-d23},[r0,:128]! + bne 1b + ands r3, r3, #15 + beq 3f +2: vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! + vst1.32 {d16-d17},[r0,:128]! + vmul.f32 q8, q0, q2 + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! + vst1.32 {d18-d19},[r0,:128]! + vmul.f32 q9, q1, q3 +3: vst1.32 {d16-d19},[r0,:128]! + bx lr +endfunc + +function ff_vector_fmac_scalar_neon, export=1 +VFP len .req r2 +VFP acc .req r3 +NOVFP len .req r3 +NOVFP acc .req r2 +VFP vdup.32 q15, d0[0] +NOVFP vdup.32 q15, r2 + bics r12, len, #15 + mov acc, r0 + beq 3f + vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vld1.32 {q1}, [r1,:128]! + vld1.32 {q9}, [acc,:128]! +1: vmla.f32 q8, q0, q15 + vld1.32 {q2}, [r1,:128]! + vld1.32 {q10}, [acc,:128]! + vmla.f32 q9, q1, q15 + vld1.32 {q3}, [r1,:128]! + vld1.32 {q11}, [acc,:128]! + vmla.f32 q10, q2, q15 + vst1.32 {q8}, [r0,:128]! + vmla.f32 q11, q3, q15 + vst1.32 {q9}, [r0,:128]! + subs r12, r12, #16 + beq 2f + vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vst1.32 {q10}, [r0,:128]! + vld1.32 {q1}, [r1,:128]! + vld1.32 {q9}, [acc,:128]! + vst1.32 {q11}, [r0,:128]! + b 1b +2: vst1.32 {q10}, [r0,:128]! + vst1.32 {q11}, [r0,:128]! + ands len, len, #15 + it eq + bxeq lr +3: vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vmla.f32 q8, q0, q15 + vst1.32 {q8}, [r0,:128]! + subs len, len, #4 + bgt 3b + bx lr + .unreq len +endfunc + +function ff_vector_fmul_scalar_neon, export=1 +VFP len .req r2 +NOVFP len .req r3 +VFP vdup.32 q8, d0[0] +NOVFP vdup.32 q8, r2 + bics r12, len, #15 + beq 3f + vld1.32 {q0},[r1,:128]! + vld1.32 {q1},[r1,:128]! +1: vmul.f32 q0, q0, q8 + vld1.32 {q2},[r1,:128]! + vmul.f32 q1, q1, q8 + vld1.32 {q3},[r1,:128]! + vmul.f32 q2, q2, q8 + vst1.32 {q0},[r0,:128]! + vmul.f32 q3, q3, q8 + vst1.32 {q1},[r0,:128]! + subs r12, r12, #16 + beq 2f + vld1.32 {q0},[r1,:128]! + vst1.32 {q2},[r0,:128]! + vld1.32 {q1},[r1,:128]! + vst1.32 {q3},[r0,:128]! + b 1b +2: vst1.32 {q2},[r0,:128]! + vst1.32 {q3},[r0,:128]! + ands len, len, #15 + it eq + bxeq lr +3: vld1.32 {q0},[r1,:128]! + vmul.f32 q0, q0, q8 + vst1.32 {q0},[r0,:128]! + subs len, len, #4 + bgt 3b + bx lr + .unreq len +endfunc + +function ff_vector_fmul_window_neon, export=1 + push {r4,r5,lr} + ldr lr, [sp, #12] + sub r2, r2, #8 + sub r5, lr, #2 + add r2, r2, r5, lsl #2 + add r4, r3, r5, lsl #3 + add ip, r0, r5, lsl #3 + mov r5, #-16 + vld1.32 {d0,d1}, [r1,:128]! + vld1.32 {d2,d3}, [r2,:128], r5 + vld1.32 {d4,d5}, [r3,:128]! + vld1.32 {d6,d7}, [r4,:128], r5 +1: subs lr, lr, #4 + vmul.f32 d22, d0, d4 + vrev64.32 q3, q3 + vmul.f32 d23, d1, d5 + vrev64.32 q1, q1 + vmul.f32 d20, d0, d7 + vmul.f32 d21, d1, d6 + beq 2f + vmla.f32 d22, d3, d7 + vld1.32 {d0,d1}, [r1,:128]! + vmla.f32 d23, d2, d6 + vld1.32 {d18,d19},[r2,:128], r5 + vmls.f32 d20, d3, d4 + vld1.32 {d24,d25},[r3,:128]! + vmls.f32 d21, d2, d5 + vld1.32 {d6,d7}, [r4,:128], r5 + vmov q1, q9 + vrev64.32 q11, q11 + vmov q2, q12 + vswp d22, d23 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 + b 1b +2: vmla.f32 d22, d3, d7 + vmla.f32 d23, d2, d6 + vmls.f32 d20, d3, d4 + vmls.f32 d21, d2, d5 + vrev64.32 q11, q11 + vswp d22, d23 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 + pop {r4,r5,pc} +endfunc + +function ff_vector_fmul_add_neon, export=1 + ldr r12, [sp] + vld1.32 {q0-q1}, [r1,:128]! + vld1.32 {q8-q9}, [r2,:128]! + vld1.32 {q2-q3}, [r3,:128]! + vmul.f32 q10, q0, q8 + vmul.f32 q11, q1, q9 +1: vadd.f32 q12, q2, q10 + vadd.f32 q13, q3, q11 + pld [r1, #16] + pld [r2, #16] + pld [r3, #16] + subs r12, r12, #8 + beq 2f + vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [r2,:128]! + vmul.f32 q10, q0, q8 + vld1.32 {q1}, [r1,:128]! + vld1.32 {q9}, [r2,:128]! + vmul.f32 q11, q1, q9 + vld1.32 {q2-q3}, [r3,:128]! + vst1.32 {q12-q13},[r0,:128]! + b 1b +2: vst1.32 {q12-q13},[r0,:128]! + bx lr +endfunc + +function ff_vector_fmul_reverse_neon, export=1 + add r2, r2, r3, lsl #2 + sub r2, r2, #32 + mov r12, #-32 + vld1.32 {q0-q1}, [r1,:128]! + vld1.32 {q2-q3}, [r2,:128], r12 +1: pld [r1, #32] + vrev64.32 q3, q3 + vmul.f32 d16, d0, d7 + vmul.f32 d17, d1, d6 + pld [r2, #-32] + vrev64.32 q2, q2 + vmul.f32 d18, d2, d5 + vmul.f32 d19, d3, d4 + subs r3, r3, #8 + beq 2f + vld1.32 {q0-q1}, [r1,:128]! + vld1.32 {q2-q3}, [r2,:128], r12 + vst1.32 {q8-q9}, [r0,:128]! + b 1b +2: vst1.32 {q8-q9}, [r0,:128]! + bx lr +endfunc + +function ff_butterflies_float_neon, export=1 +1: vld1.32 {q0},[r0,:128] + vld1.32 {q1},[r1,:128] + vsub.f32 q2, q0, q1 + vadd.f32 q1, q0, q1 + vst1.32 {q2},[r1,:128]! + vst1.32 {q1},[r0,:128]! + subs r2, r2, #4 + bgt 1b + bx lr +endfunc + +function ff_scalarproduct_float_neon, export=1 + vmov.f32 q2, #0.0 +1: vld1.32 {q0},[r0,:128]! + vld1.32 {q1},[r1,:128]! + vmla.f32 q2, q0, q1 + subs r2, r2, #4 + bgt 1b + vadd.f32 d0, d4, d5 + vpadd.f32 d0, d0, d0 +NOVFP vmov.32 r0, d0[0] + bx lr +endfunc diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_vfp.S b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_vfp.S new file mode 100644 index 00000000..7db24522 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/float_dsp_vfp.S @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2008 Siarhei Siamashka + * + * This file is part of FFmpeg + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "asm.S" + +/** + * Assume that len is a positive number and is multiple of 8 + */ +@ void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, int len) +function ff_vector_fmul_vfp, export=1 + vpush {d8-d15} + fmrx r12, fpscr + orr r12, r12, #(3 << 16) /* set vector size to 4 */ + fmxr fpscr, r12 + + vldmia r1!, {s0-s3} + vldmia r2!, {s8-s11} + vldmia r1!, {s4-s7} + vldmia r2!, {s12-s15} + vmul.f32 s8, s0, s8 +1: + subs r3, r3, #16 + vmul.f32 s12, s4, s12 + itttt ge + vldmiage r1!, {s16-s19} + vldmiage r2!, {s24-s27} + vldmiage r1!, {s20-s23} + vldmiage r2!, {s28-s31} + it ge + vmulge.f32 s24, s16, s24 + vstmia r0!, {s8-s11} + vstmia r0!, {s12-s15} + it ge + vmulge.f32 s28, s20, s28 + itttt gt + vldmiagt r1!, {s0-s3} + vldmiagt r2!, {s8-s11} + vldmiagt r1!, {s4-s7} + vldmiagt r2!, {s12-s15} + ittt ge + vmulge.f32 s8, s0, s8 + vstmiage r0!, {s24-s27} + vstmiage r0!, {s28-s31} + bgt 1b + + bic r12, r12, #(7 << 16) /* set vector size back to 1 */ + fmxr fpscr, r12 + vpop {d8-d15} + bx lr +endfunc + +/** + * ARM VFP implementation of 'vector_fmul_window_c' function + * Assume that len is a positive non-zero number + */ +@ void ff_vector_fmul_window_vfp(float *dst, const float *src0, +@ const float *src1, const float *win, int len) +function ff_vector_fmul_window_vfp, export=1 +DST0 .req a1 +SRC0 .req a2 +SRC1 .req a3 +WIN0 .req a4 +LEN .req v1 +DST1 .req v2 +WIN1 .req v3 +OLDFPSCR .req ip + + push {v1-v3,lr} + ldr LEN, [sp, #4*4+0] + vpush {s16-s31} + fmrx OLDFPSCR, FPSCR + add DST1, DST0, LEN, lsl #3 + add SRC1, SRC1, LEN, lsl #2 + add WIN1, WIN0, LEN, lsl #3 + + tst LEN, #7 + beq 4f @ common case: len is a multiple of 8 + + ldr lr, =0x03000000 @ RunFast mode, scalar mode + fmxr FPSCR, lr + + tst LEN, #1 + beq 1f + vldmdb WIN1!, {s0} + vldmia SRC0!, {s8} + vldmia WIN0!, {s16} + vmul.f s24, s0, s8 + vldmdb SRC1!, {s20} + vmul.f s8, s16, s8 + vmls.f s24, s16, s20 + vmla.f s8, s0, s20 + vstmia DST0!, {s24} + vstmdb DST1!, {s8} +1: + tst LEN, #2 + beq 2f + vldmdb WIN1!, {s0} + vldmdb WIN1!, {s1} + vldmia SRC0!, {s8-s9} + vldmia WIN0!, {s16-s17} + vmul.f s24, s0, s8 + vmul.f s25, s1, s9 + vldmdb SRC1!, {s20} + vldmdb SRC1!, {s21} + vmul.f s8, s16, s8 + vmul.f s9, s17, s9 + vmls.f s24, s16, s20 + vmls.f s25, s17, s21 + vmla.f s8, s0, s20 + vmla.f s9, s1, s21 + vstmia DST0!, {s24-s25} + vstmdb DST1!, {s8} + vstmdb DST1!, {s9} +2: + tst LEN, #4 + beq 3f + vldmdb WIN1!, {s0} + vldmdb WIN1!, {s1} + vldmdb WIN1!, {s2} + vldmdb WIN1!, {s3} + vldmia SRC0!, {s8-s11} + vldmia WIN0!, {s16-s19} + vmul.f s24, s0, s8 + vmul.f s25, s1, s9 + vmul.f s26, s2, s10 + vmul.f s27, s3, s11 + vldmdb SRC1!, {s20} + vldmdb SRC1!, {s21} + vldmdb SRC1!, {s22} + vldmdb SRC1!, {s23} + vmul.f s8, s16, s8 + vmul.f s9, s17, s9 + vmul.f s10, s18, s10 + vmul.f s11, s19, s11 + vmls.f s24, s16, s20 + vmls.f s25, s17, s21 + vmls.f s26, s18, s22 + vmls.f s27, s19, s23 + vmla.f s8, s0, s20 + vmla.f s9, s1, s21 + vmla.f s10, s2, s22 + vmla.f s11, s3, s23 + vstmia DST0!, {s24-s27} + vstmdb DST1!, {s8} + vstmdb DST1!, {s9} + vstmdb DST1!, {s10} + vstmdb DST1!, {s11} +3: + bics LEN, LEN, #7 + beq 7f +4: + ldr lr, =0x03030000 @ RunFast mode, short vectors of length 4, stride 1 + fmxr FPSCR, lr + + vldmdb WIN1!, {s0} + vldmdb WIN1!, {s1} + vldmdb WIN1!, {s2} + vldmdb WIN1!, {s3} + vldmia SRC0!, {s8-s11} + vldmia WIN0!, {s16-s19} + vmul.f s24, s0, s8 @ vector * vector + vldmdb SRC1!, {s20} + vldmdb SRC1!, {s21} + vldmdb SRC1!, {s22} + vldmdb SRC1!, {s23} + vmul.f s8, s16, s8 @ vector * vector + vmls.f s24, s16, s20 @ vector * vector + vldmdb WIN1!, {s4} + vldmdb WIN1!, {s5} + vldmdb WIN1!, {s6} + vldmdb WIN1!, {s7} + vldmia SRC0!, {s12-s13} + vmla.f s8, s0, s20 @ vector * vector + vldmia SRC0!, {s14-s15} + subs LEN, LEN, #8 + beq 6f +5: vldmia WIN0!, {s20-s23} + vmul.f s28, s4, s12 @ vector * vector + vstmia DST0!, {s24-s25} + vldmdb SRC1!, {s16} + vldmdb SRC1!, {s17} + vldmdb SRC1!, {s18} + vldmdb SRC1!, {s19} + vmul.f s12, s20, s12 @ vector * vector + vstmia DST0!, {s26-s27} + vstmdb DST1!, {s8} + vstmdb DST1!, {s9} + vstmdb DST1!, {s10} + vstmdb DST1!, {s11} + vmls.f s28, s20, s16 @ vector * vector + vldmdb WIN1!, {s0} + vldmdb WIN1!, {s1} + vldmdb WIN1!, {s2} + vldmdb WIN1!, {s3} + vldmia SRC0!, {s8-s9} + vmla.f s12, s4, s16 @ vector * vector + vldmia SRC0!, {s10-s11} + subs LEN, LEN, #8 + vldmia WIN0!, {s16-s19} + vmul.f s24, s0, s8 @ vector * vector + vstmia DST0!, {s28-s29} + vldmdb SRC1!, {s20} + vldmdb SRC1!, {s21} + vldmdb SRC1!, {s22} + vldmdb SRC1!, {s23} + vmul.f s8, s16, s8 @ vector * vector + vstmia DST0!, {s30-s31} + vstmdb DST1!, {s12} + vstmdb DST1!, {s13} + vstmdb DST1!, {s14} + vstmdb DST1!, {s15} + vmls.f s24, s16, s20 @ vector * vector + vldmdb WIN1!, {s4} + vldmdb WIN1!, {s5} + vldmdb WIN1!, {s6} + vldmdb WIN1!, {s7} + vldmia SRC0!, {s12-s13} + vmla.f s8, s0, s20 @ vector * vector + vldmia SRC0!, {s14-s15} + bne 5b +6: vldmia WIN0!, {s20-s23} + vmul.f s28, s4, s12 @ vector * vector + vstmia DST0!, {s24-s25} + vldmdb SRC1!, {s16} + vldmdb SRC1!, {s17} + vldmdb SRC1!, {s18} + vldmdb SRC1!, {s19} + vmul.f s12, s20, s12 @ vector * vector + vstmia DST0!, {s26-s27} + vstmdb DST1!, {s8} + vstmdb DST1!, {s9} + vstmdb DST1!, {s10} + vstmdb DST1!, {s11} + vmls.f s28, s20, s16 @ vector * vector + vmla.f s12, s4, s16 @ vector * vector + vstmia DST0!, {s28-s31} + vstmdb DST1!, {s12} + vstmdb DST1!, {s13} + vstmdb DST1!, {s14} + vstmdb DST1!, {s15} +7: + fmxr FPSCR, OLDFPSCR + vpop {s16-s31} + pop {v1-v3,pc} + + .unreq DST0 + .unreq SRC0 + .unreq SRC1 + .unreq WIN0 + .unreq LEN + .unreq OLDFPSCR + .unreq DST1 + .unreq WIN1 +endfunc + +/** + * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function. + * Assume that len is a positive number and is multiple of 8 + */ +@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, +@ const float *src1, int len) +function ff_vector_fmul_reverse_vfp, export=1 + vpush {d8-d15} + add r2, r2, r3, lsl #2 + vldmdb r2!, {s0-s3} + vldmia r1!, {s8-s11} + vldmdb r2!, {s4-s7} + vldmia r1!, {s12-s15} + vmul.f32 s8, s3, s8 + vmul.f32 s9, s2, s9 + vmul.f32 s10, s1, s10 + vmul.f32 s11, s0, s11 +1: + subs r3, r3, #16 + it ge + vldmdbge r2!, {s16-s19} + vmul.f32 s12, s7, s12 + it ge + vldmiage r1!, {s24-s27} + vmul.f32 s13, s6, s13 + it ge + vldmdbge r2!, {s20-s23} + vmul.f32 s14, s5, s14 + it ge + vldmiage r1!, {s28-s31} + vmul.f32 s15, s4, s15 + it ge + vmulge.f32 s24, s19, s24 + it gt + vldmdbgt r2!, {s0-s3} + it ge + vmulge.f32 s25, s18, s25 + vstmia r0!, {s8-s13} + it ge + vmulge.f32 s26, s17, s26 + it gt + vldmiagt r1!, {s8-s11} + itt ge + vmulge.f32 s27, s16, s27 + vmulge.f32 s28, s23, s28 + it gt + vldmdbgt r2!, {s4-s7} + it ge + vmulge.f32 s29, s22, s29 + vstmia r0!, {s14-s15} + ittt ge + vmulge.f32 s30, s21, s30 + vmulge.f32 s31, s20, s31 + vmulge.f32 s8, s3, s8 + it gt + vldmiagt r1!, {s12-s15} + itttt ge + vmulge.f32 s9, s2, s9 + vmulge.f32 s10, s1, s10 + vstmiage r0!, {s24-s27} + vmulge.f32 s11, s0, s11 + it ge + vstmiage r0!, {s28-s31} + bgt 1b + + vpop {d8-d15} + bx lr +endfunc + +/** + * ARM VFP implementation of 'butterflies_float_c' function + * Assume that len is a positive non-zero number + */ +@ void ff_butterflies_float_vfp(float *restrict v1, float *restrict v2, int len) +function ff_butterflies_float_vfp, export=1 +BASE1 .req a1 +BASE2 .req a2 +LEN .req a3 +OLDFPSCR .req a4 + + vpush {s16-s31} + fmrx OLDFPSCR, FPSCR + + tst LEN, #7 + beq 4f @ common case: len is a multiple of 8 + + ldr ip, =0x03000000 @ RunFast mode, scalar mode + fmxr FPSCR, ip + + tst LEN, #1 + beq 1f + vldmia BASE1!, {s0} + vldmia BASE2!, {s8} + vadd.f s16, s0, s8 + vsub.f s24, s0, s8 + vstr s16, [BASE1, #0-4*1] + vstr s24, [BASE2, #0-4*1] +1: + tst LEN, #2 + beq 2f + vldmia BASE1!, {s0-s1} + vldmia BASE2!, {s8-s9} + vadd.f s16, s0, s8 + vadd.f s17, s1, s9 + vsub.f s24, s0, s8 + vsub.f s25, s1, s9 + vstr d8, [BASE1, #0-8*1] @ s16,s17 + vstr d12, [BASE2, #0-8*1] @ s24,s25 +2: + tst LEN, #4 + beq 3f + vldmia BASE1!, {s0-s1} + vldmia BASE2!, {s8-s9} + vldmia BASE1!, {s2-s3} + vldmia BASE2!, {s10-s11} + vadd.f s16, s0, s8 + vadd.f s17, s1, s9 + vsub.f s24, s0, s8 + vsub.f s25, s1, s9 + vadd.f s18, s2, s10 + vadd.f s19, s3, s11 + vsub.f s26, s2, s10 + vsub.f s27, s3, s11 + vstr d8, [BASE1, #0-16*1] @ s16,s17 + vstr d12, [BASE2, #0-16*1] @ s24,s25 + vstr d9, [BASE1, #8-16*1] @ s18,s19 + vstr d13, [BASE2, #8-16*1] @ s26,s27 +3: + bics LEN, LEN, #7 + beq 7f +4: + ldr ip, =0x03030000 @ RunFast mode, short vectors of length 4, stride 1 + fmxr FPSCR, ip + + vldmia BASE1!, {s0-s1} + vldmia BASE2!, {s8-s9} + vldmia BASE1!, {s2-s3} + vldmia BASE2!, {s10-s11} + vadd.f s16, s0, s8 + vldmia BASE1!, {s4-s5} + vldmia BASE2!, {s12-s13} + vldmia BASE1!, {s6-s7} + vldmia BASE2!, {s14-s15} + vsub.f s24, s0, s8 + vadd.f s20, s4, s12 + subs LEN, LEN, #8 + beq 6f +5: vldmia BASE1!, {s0-s3} + vldmia BASE2!, {s8-s11} + vsub.f s28, s4, s12 + vstr d8, [BASE1, #0-16*3] @ s16,s17 + vstr d9, [BASE1, #8-16*3] @ s18,s19 + vstr d12, [BASE2, #0-16*3] @ s24,s25 + vstr d13, [BASE2, #8-16*3] @ s26,s27 + vadd.f s16, s0, s8 + vldmia BASE1!, {s4-s7} + vldmia BASE2!, {s12-s15} + vsub.f s24, s0, s8 + vstr d10, [BASE1, #0-16*3] @ s20,s21 + vstr d11, [BASE1, #8-16*3] @ s22,s23 + vstr d14, [BASE2, #0-16*3] @ s28,s29 + vstr d15, [BASE2, #8-16*3] @ s30,s31 + vadd.f s20, s4, s12 + subs LEN, LEN, #8 + bne 5b +6: vsub.f s28, s4, s12 + vstr d8, [BASE1, #0-16*2] @ s16,s17 + vstr d9, [BASE1, #8-16*2] @ s18,s19 + vstr d12, [BASE2, #0-16*2] @ s24,s25 + vstr d13, [BASE2, #8-16*2] @ s26,s27 + vstr d10, [BASE1, #0-16*1] @ s20,s21 + vstr d11, [BASE1, #8-16*1] @ s22,s23 + vstr d14, [BASE2, #0-16*1] @ s28,s29 + vstr d15, [BASE2, #8-16*1] @ s30,s31 +7: + fmxr FPSCR, OLDFPSCR + vpop {s16-s31} + bx lr + + .unreq BASE1 + .unreq BASE2 + .unreq LEN + .unreq OLDFPSCR +endfunc diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/intmath.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/intmath.h new file mode 100644 index 00000000..f19b21e9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/intmath.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_INTMATH_H +#define AVUTIL_ARM_INTMATH_H + +#include + +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_INLINE_ASM + +#if HAVE_ARMV6_INLINE + +#define av_clip_uint8 av_clip_uint8_arm +static av_always_inline av_const int av_clip_uint8_arm(int a) +{ + int x; + __asm__ ("usat %0, #8, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_int8 av_clip_int8_arm +static av_always_inline av_const int av_clip_int8_arm(int a) +{ + int x; + __asm__ ("ssat %0, #8, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_uint16 av_clip_uint16_arm +static av_always_inline av_const int av_clip_uint16_arm(int a) +{ + int x; + __asm__ ("usat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_int16 av_clip_int16_arm +static av_always_inline av_const int av_clip_int16_arm(int a) +{ + int x; + __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_intp2 av_clip_intp2_arm +static av_always_inline av_const int av_clip_intp2_arm(int a, int p) +{ + if (av_builtin_constant_p(p)) { + unsigned x; + __asm__ ("ssat %0, %2, %1" : "=r"(x) : "r"(a), "i"(p+1)); + return x; + } else { + if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) + return (a >> 31) ^ ((1 << p) - 1); + else + return a; + } +} + +#define av_clip_uintp2 av_clip_uintp2_arm +static av_always_inline av_const unsigned av_clip_uintp2_arm(int a, int p) +{ + if (av_builtin_constant_p(p)) { + unsigned x; + __asm__ ("usat %0, %2, %1" : "=r"(x) : "r"(a), "i"(p)); + return x; + } else { + if (a & ~((1<> 31 & ((1< +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM && AV_GCC_VERSION_AT_MOST(4,6) + +#define AV_RN16 AV_RN16 +static av_always_inline unsigned AV_RN16(const void *p) +{ + const uint8_t *q = p; + unsigned v; +#if AV_GCC_VERSION_AT_MOST(4,5) + __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)q)); +#elif defined __thumb__ + __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(q[0]), "m"(q[1])); +#else + __asm__ ("ldrh %0, %1" : "=r"(v) : "Uq"(q[0]), "m"(q[1])); +#endif + return v; +} + +#define AV_WN16 AV_WN16 +static av_always_inline void AV_WN16(void *p, uint16_t v) +{ + __asm__ ("strh %1, %0" : "=m"(*(uint16_t *)p) : "r"(v)); +} + +#define AV_RN32 AV_RN32 +static av_always_inline uint32_t AV_RN32(const void *p) +{ + const struct __attribute__((packed)) { uint32_t v; } *q = p; + uint32_t v; + __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*q)); + return v; +} + +#define AV_WN32 AV_WN32 +static av_always_inline void AV_WN32(void *p, uint32_t v) +{ + __asm__ ("str %1, %0" : "=m"(*(uint32_t *)p) : "r"(v)); +} + +#if HAVE_ASM_MOD_Q + +#define AV_RN64 AV_RN64 +static av_always_inline uint64_t AV_RN64(const void *p) +{ + const struct __attribute__((packed)) { uint32_t v; } *q = p; + uint64_t v; + __asm__ ("ldr %Q0, %1 \n\t" + "ldr %R0, %2 \n\t" + : "=&r"(v) + : "m"(q[0]), "m"(q[1])); + return v; +} + +#define AV_WN64 AV_WN64 +static av_always_inline void AV_WN64(void *p, uint64_t v) +{ + __asm__ ("str %Q2, %0 \n\t" + "str %R2, %1 \n\t" + : "=m"(*(uint32_t*)p), "=m"(*((uint32_t*)p+1)) + : "r"(v)); +} + +#endif /* HAVE_ASM_MOD_Q */ + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_ARM_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/neontest.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/neontest.h new file mode 100644 index 00000000..d75ab838 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/neontest.h @@ -0,0 +1,67 @@ +/* + * check NEON registers for clobbering + * Copyright (c) 2008 Ramiro Polla + * Copyright (c) 2013 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_NEONTEST_H +#define AVUTIL_ARM_NEONTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storeneonregs(mem) \ + __asm__ volatile( \ + "vstm %0, {d8-d15}\n\t" \ + :: "r"(mem) : "memory") + +#define testneonclobbers(func, ctx, ...) \ + uint64_t neon[2][8]; \ + int ret; \ + storeneonregs(neon[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storeneonregs(neon[1]); \ + if (memcmp(neon[0], neon[1], sizeof(neon[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "NEON REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 8; i ++) \ + if (neon[0][i] != neon[1][i]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "d%-2d = %016"PRIx64"\n", \ + 8 + i, av_bswap64(neon[0][i])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"\n", \ + av_bswap64(neon[1][i])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_ARM_NEONTEST_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/arm/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/arm/timer.h new file mode 100644 index 00000000..caf23e2a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/arm/timer.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_TIMER_H +#define AVUTIL_ARM_TIMER_H + +#include +#include "config.h" + +#if defined(__APPLE__) + +#include + +#define AV_READ_TIME mach_absolute_time + +#elif HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + unsigned cc; + __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc)); + return cc; +} + +#endif /* HAVE_INLINE_ASM && __ARM_ARCH_7A__ */ + +#endif /* AVUTIL_ARM_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/attributes.h b/arm/raspi/third_party/ffmpeg/libavutil/attributes.h new file mode 100644 index 00000000..04c615c9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/attributes.h @@ -0,0 +1,173 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Macro definitions for various function/variable attributes + */ + +#ifndef AVUTIL_ATTRIBUTES_H +#define AVUTIL_ATTRIBUTES_H + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +# define AV_GCC_VERSION_AT_MOST(x,y) (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y)) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +# define AV_GCC_VERSION_AT_MOST(x,y) 0 +#endif + +#ifdef __has_builtin +# define AV_HAS_BUILTIN(x) __has_builtin(x) +#else +# define AV_HAS_BUILTIN(x) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +# define av_always_inline __forceinline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_extern_inline +#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__) +# define av_extern_inline extern inline +#else +# define av_extern_inline inline +#endif +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,4) +# define av_warn_unused_result __attribute__((warn_unused_result)) +#else +# define av_warn_unused_result +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#elif defined(_MSC_VER) +# define av_noinline __declspec(noinline) +#else +# define av_noinline +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) +# define av_const __attribute__((const)) +#else +# define av_const +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define attribute_deprecated __declspec(deprecated) +#else +# define attribute_deprecated +#endif + +/** + * Disable warnings about deprecated features + * This is useful for sections of code kept for backward compatibility and + * scheduled for removal. + */ +#ifndef AV_NOWARN_DEPRECATED +#if AV_GCC_VERSION_AT_LEAST(4,6) || defined(__clang__) +# define AV_NOWARN_DEPRECATED(code) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ + code \ + _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) +# define AV_NOWARN_DEPRECATED(code) \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4996)) \ + code; \ + __pragma(warning(pop)) +#else +# define AV_NOWARN_DEPRECATED(code) code +#endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif + +/** + * Mark a variable as used and prevent the compiler from optimizing it + * away. This is useful for variables accessed only from inline + * assembler without the compiler being aware. + */ +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_used __attribute__((used)) +#else +# define av_used +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) +# define av_alias __attribute__((may_alias)) +#else +# define av_alias +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_builtin_constant_p __builtin_constant_p +# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) +#else +# define av_builtin_constant_p(x) 0 +# define av_printf_format(fmtpos, attrpos) +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) +# define av_noreturn __attribute__((noreturn)) +#else +# define av_noreturn +#endif + +#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/attributes_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/attributes_internal.h new file mode 100644 index 00000000..3df1ee6a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/attributes_internal.h @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ATTRIBUTES_INTERNAL_H +#define AVUTIL_ATTRIBUTES_INTERNAL_H + +#include "attributes.h" + +#if (AV_GCC_VERSION_AT_LEAST(4,0) || defined(__clang__)) && (defined(__ELF__) || defined(__MACH__)) +# define attribute_visibility_hidden __attribute__((visibility("hidden"))) +# define FF_VISIBILITY_PUSH_HIDDEN _Pragma("GCC visibility push(hidden)") +# define FF_VISIBILITY_POP_HIDDEN _Pragma("GCC visibility pop") +#else +# define attribute_visibility_hidden +# define FF_VISIBILITY_PUSH_HIDDEN +# define FF_VISIBILITY_POP_HIDDEN +#endif + +#endif /* AVUTIL_ATTRIBUTES_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.c b/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.c new file mode 100644 index 00000000..f4103178 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.c @@ -0,0 +1,229 @@ +/* + * Audio FIFO + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Audio FIFO + */ + +#include +#include + +#include "audio_fifo.h" +#include "error.h" +#include "fifo.h" +#include "macros.h" +#include "mem.h" +#include "samplefmt.h" + +struct AVAudioFifo { + AVFifo **buf; /**< single buffer for interleaved, per-channel buffers for planar */ + int nb_buffers; /**< number of buffers */ + int nb_samples; /**< number of samples currently in the FIFO */ + int allocated_samples; /**< current allocated size, in samples */ + + int channels; /**< number of channels */ + enum AVSampleFormat sample_fmt; /**< sample format */ + int sample_size; /**< size, in bytes, of one sample in a buffer */ +}; + +void av_audio_fifo_free(AVAudioFifo *af) +{ + if (af) { + if (af->buf) { + int i; + for (i = 0; i < af->nb_buffers; i++) { + av_fifo_freep2(&af->buf[i]); + } + av_freep(&af->buf); + } + av_free(af); + } +} + +AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, + int nb_samples) +{ + AVAudioFifo *af; + int buf_size, i; + + /* get channel buffer size (also validates parameters) */ + if (av_samples_get_buffer_size(&buf_size, channels, nb_samples, sample_fmt, 1) < 0) + return NULL; + + af = av_mallocz(sizeof(*af)); + if (!af) + return NULL; + + af->channels = channels; + af->sample_fmt = sample_fmt; + af->sample_size = buf_size / nb_samples; + af->nb_buffers = av_sample_fmt_is_planar(sample_fmt) ? channels : 1; + + af->buf = av_calloc(af->nb_buffers, sizeof(*af->buf)); + if (!af->buf) + goto error; + + for (i = 0; i < af->nb_buffers; i++) { + af->buf[i] = av_fifo_alloc2(buf_size, 1, 0); + if (!af->buf[i]) + goto error; + } + af->allocated_samples = nb_samples; + + return af; + +error: + av_audio_fifo_free(af); + return NULL; +} + +int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples) +{ + const size_t cur_size = av_fifo_can_read (af->buf[0]) + + av_fifo_can_write(af->buf[0]); + int i, ret, buf_size; + + if ((ret = av_samples_get_buffer_size(&buf_size, af->channels, nb_samples, + af->sample_fmt, 1)) < 0) + return ret; + + if (buf_size > cur_size) { + for (i = 0; i < af->nb_buffers; i++) { + if ((ret = av_fifo_grow2(af->buf[i], buf_size - cur_size)) < 0) + return ret; + } + } + af->allocated_samples = nb_samples; + return 0; +} + +int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples) +{ + int i, ret, size; + + /* automatically reallocate buffers if needed */ + if (av_audio_fifo_space(af) < nb_samples) { + int current_size = av_audio_fifo_size(af); + /* check for integer overflow in new size calculation */ + if (INT_MAX / 2 - current_size < nb_samples) + return AVERROR(EINVAL); + /* reallocate buffers */ + if ((ret = av_audio_fifo_realloc(af, 2 * (current_size + nb_samples))) < 0) + return ret; + } + + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + ret = av_fifo_write(af->buf[i], data[i], size); + if (ret < 0) + return AVERROR_BUG; + } + af->nb_samples += nb_samples; + + return nb_samples; +} + +int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples) +{ + return av_audio_fifo_peek_at(af, data, nb_samples, 0); +} + +int av_audio_fifo_peek_at(AVAudioFifo *af, void **data, int nb_samples, int offset) +{ + int i, ret, size; + + if (offset < 0 || offset >= af->nb_samples) + return AVERROR(EINVAL); + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + if (!nb_samples) + return 0; + if (offset > af->nb_samples - nb_samples) + return AVERROR(EINVAL); + + offset *= af->sample_size; + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + if ((ret = av_fifo_peek(af->buf[i], data[i], size, offset)) < 0) + return AVERROR_BUG; + } + + return nb_samples; +} + +int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples) +{ + int i, size; + + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + if (!nb_samples) + return 0; + + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + if (av_fifo_read(af->buf[i], data[i], size) < 0) + return AVERROR_BUG; + } + af->nb_samples -= nb_samples; + + return nb_samples; +} + +int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples) +{ + int i, size; + + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + + if (nb_samples) { + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) + av_fifo_drain2(af->buf[i], size); + af->nb_samples -= nb_samples; + } + return 0; +} + +void av_audio_fifo_reset(AVAudioFifo *af) +{ + int i; + + for (i = 0; i < af->nb_buffers; i++) + av_fifo_reset2(af->buf[i]); + + af->nb_samples = 0; +} + +int av_audio_fifo_size(AVAudioFifo *af) +{ + return af->nb_samples; +} + +int av_audio_fifo_space(AVAudioFifo *af) +{ + return af->allocated_samples - af->nb_samples; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.h b/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.h new file mode 100644 index 00000000..d1e4c856 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/audio_fifo.h @@ -0,0 +1,186 @@ +/* + * Audio FIFO + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Audio FIFO Buffer + */ + +#ifndef AVUTIL_AUDIO_FIFO_H +#define AVUTIL_AUDIO_FIFO_H + +#include "attributes.h" +#include "samplefmt.h" + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_audiofifo Audio FIFO Buffer + * @{ + */ + +/** + * Context for an Audio FIFO Buffer. + * + * - Operates at the sample level rather than the byte level. + * - Supports multiple channels with either planar or packed sample format. + * - Automatic reallocation when writing to a full buffer. + */ +typedef struct AVAudioFifo AVAudioFifo; + +/** + * Free an AVAudioFifo. + * + * @param af AVAudioFifo to free + */ +void av_audio_fifo_free(AVAudioFifo *af); + +/** + * Allocate an AVAudioFifo. + * + * @param sample_fmt sample format + * @param channels number of channels + * @param nb_samples initial allocation size, in samples + * @return newly allocated AVAudioFifo, or NULL on error + */ +AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, + int nb_samples); + +/** + * Reallocate an AVAudioFifo. + * + * @param af AVAudioFifo to reallocate + * @param nb_samples new allocation size, in samples + * @return 0 if OK, or negative AVERROR code on failure + */ +av_warn_unused_result +int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples); + +/** + * Write data to an AVAudioFifo. + * + * The AVAudioFifo will be reallocated automatically if the available space + * is less than nb_samples. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to write to + * @param data audio data plane pointers + * @param nb_samples number of samples to write + * @return number of samples actually written, or negative AVERROR + * code on failure. If successful, the number of samples + * actually written will always be nb_samples. + */ +int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @param offset offset from current read position + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek_at(AVAudioFifo *af, void **data, int nb_samples, int offset); + +/** + * Read data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to read + * @return number of samples actually read, or negative AVERROR code + * on failure. The number of samples actually read will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Drain data from an AVAudioFifo. + * + * Removes the data without reading it. + * + * @param af AVAudioFifo to drain + * @param nb_samples number of samples to drain + * @return 0 if OK, or negative AVERROR code on failure + */ +int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples); + +/** + * Reset the AVAudioFifo buffer. + * + * This empties all data in the buffer. + * + * @param af AVAudioFifo to reset + */ +void av_audio_fifo_reset(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for reading. + * + * @param af the AVAudioFifo to query + * @return number of samples available for reading + */ +int av_audio_fifo_size(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for writing. + * + * @param af the AVAudioFifo to query + * @return number of samples available for writing + */ +int av_audio_fifo_space(AVAudioFifo *af); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_AUDIO_FIFO_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_cpu.c new file mode 100644 index 00000000..3adbdc6f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_cpu.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "cpu.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_fixed_dsp.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_fixed_dsp.c new file mode 100644 index 00000000..5d4d92a9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_fixed_dsp.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "fixed_dsp.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_float_dsp.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_float_dsp.c new file mode 100644 index 00000000..c189d0a0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_float_dsp.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "float_dsp.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_imgutils.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_imgutils.c new file mode 100644 index 00000000..4c2b8820 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_imgutils.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "imgutils.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_tx_float.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_tx_float.c new file mode 100644 index 00000000..7688264d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_tx_float.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "tx_float.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_utils.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_utils.c new file mode 100644 index 00000000..e6429512 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_utils.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "utils.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_version.c b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_version.c new file mode 100644 index 00000000..dafd77fd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/autorename_libavutil_version.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "version.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avassert.h b/arm/raspi/third_party/ffmpeg/libavutil/avassert.h new file mode 100644 index 00000000..51e462bb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avassert.h @@ -0,0 +1,75 @@ +/* + * copyright (c) 2010 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple assert() macros that are a bit more flexible than ISO C assert(). + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_AVASSERT_H +#define AVUTIL_AVASSERT_H + +#include +#include "log.h" +#include "macros.h" + +/** + * assert() equivalent, that is always enabled. + */ +#define av_assert0(cond) do { \ + if (!(cond)) { \ + av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n", \ + AV_STRINGIFY(cond), __FILE__, __LINE__); \ + abort(); \ + } \ +} while (0) + + +/** + * assert() equivalent, that does not lie in speed critical code. + * These asserts() thus can be enabled without fearing speed loss. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0 +#define av_assert1(cond) av_assert0(cond) +#else +#define av_assert1(cond) ((void)0) +#endif + + +/** + * assert() equivalent, that does lie in speed critical code. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 +#define av_assert2(cond) av_assert0(cond) +#define av_assert2_fpu() av_assert0_fpu() +#else +#define av_assert2(cond) ((void)0) +#define av_assert2_fpu() ((void)0) +#endif + +/** + * Assert that floating point operations can be executed. + * + * This will av_assert0() that the cpu is not in MMX state on X86 + */ +void av_assert0_fpu(void); + +#endif /* AVUTIL_AVASSERT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avr32/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/avr32/bswap.h new file mode 100644 index 00000000..e79d53f3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avr32/bswap.h @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVR32_BSWAP_H +#define AVUTIL_AVR32_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_INLINE_ASM + +#define av_bswap16 av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + __asm__ ("swap.bh %0" : "+r"(x)); + return x; +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__ ("swap.b %0" : "+r"(x)); + return x; +} + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_AVR32_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avr32/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/avr32/intreadwrite.h new file mode 100644 index 00000000..95179f1d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avr32/intreadwrite.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVR32_INTREADWRITE_H +#define AVUTIL_AVR32_INTREADWRITE_H + +#include +#include "config.h" +#include "libavutil/bswap.h" + +/* + * AVR32 does not support unaligned memory accesses, except for the AP + * series which supports unaligned 32-bit loads and stores. 16-bit + * and 64-bit accesses must be aligned to 16 and 32 bits, respectively. + * This means we cannot use the byte-swapping load/store instructions + * here. + * + * For 16-bit, 24-bit, and (on UC series) 32-bit loads, we instead use + * the LDINS.B instruction, which gcc fails to utilise with the + * generic code. GCC also fails to use plain LD.W and ST.W even for + * AP processors, so we override the generic code. The 64-bit + * versions are improved by using our optimised 32-bit functions. + */ + +#define AV_RL16 AV_RL16 +static av_always_inline uint16_t AV_RL16(const void *p) +{ + uint16_t v; + __asm__ ("ld.ub %0, %1 \n\t" + "ldins.b %0:l, %2 \n\t" + : "=&r"(v) + : "m"(*(const uint8_t*)p), "RKs12"(*((const uint8_t*)p+1))); + return v; +} + +#define AV_RB16 AV_RB16 +static av_always_inline uint16_t AV_RB16(const void *p) +{ + uint16_t v; + __asm__ ("ld.ub %0, %2 \n\t" + "ldins.b %0:l, %1 \n\t" + : "=&r"(v) + : "RKs12"(*(const uint8_t*)p), "m"(*((const uint8_t*)p+1))); + return v; +} + +#define AV_RB24 AV_RB24 +static av_always_inline uint32_t AV_RB24(const void *p) +{ + uint32_t v; + __asm__ ("ld.ub %0, %3 \n\t" + "ldins.b %0:l, %2 \n\t" + "ldins.b %0:u, %1 \n\t" + : "=&r"(v) + : "RKs12"(* (const uint8_t*)p), + "RKs12"(*((const uint8_t*)p+1)), + "m" (*((const uint8_t*)p+2))); + return v; +} + +#define AV_RL24 AV_RL24 +static av_always_inline uint32_t AV_RL24(const void *p) +{ + uint32_t v; + __asm__ ("ld.ub %0, %1 \n\t" + "ldins.b %0:l, %2 \n\t" + "ldins.b %0:u, %3 \n\t" + : "=&r"(v) + : "m" (* (const uint8_t*)p), + "RKs12"(*((const uint8_t*)p+1)), + "RKs12"(*((const uint8_t*)p+2))); + return v; +} + +#if ARCH_AVR32_AP + +#define AV_RB32 AV_RB32 +static av_always_inline uint32_t AV_RB32(const void *p) +{ + uint32_t v; + __asm__ ("ld.w %0, %1" : "=r"(v) : "m"(*(const uint32_t*)p)); + return v; +} + +#define AV_WB32 AV_WB32 +static av_always_inline void AV_WB32(void *p, uint32_t v) +{ + __asm__ ("st.w %0, %1" : "=m"(*(uint32_t*)p) : "r"(v)); +} + +/* These two would be defined by generic code, but we need them sooner. */ +#define AV_RL32(p) av_bswap32(AV_RB32(p)) +#define AV_WL32(p, v) AV_WB32(p, av_bswap32(v)) + +#define AV_WB64 AV_WB64 +static av_always_inline void AV_WB64(void *p, uint64_t v) +{ + union { uint64_t v; uint32_t hl[2]; } vv = { v }; + AV_WB32(p, vv.hl[0]); + AV_WB32((uint32_t*)p+1, vv.hl[1]); +} + +#define AV_WL64 AV_WL64 +static av_always_inline void AV_WL64(void *p, uint64_t v) +{ + union { uint64_t v; uint32_t hl[2]; } vv = { v }; + AV_WL32(p, vv.hl[1]); + AV_WL32((uint32_t*)p+1, vv.hl[0]); +} + +#else /* ARCH_AVR32_AP */ + +#define AV_RB32 AV_RB32 +static av_always_inline uint32_t AV_RB32(const void *p) +{ + uint32_t v; + __asm__ ("ld.ub %0, %4 \n\t" + "ldins.b %0:l, %3 \n\t" + "ldins.b %0:u, %2 \n\t" + "ldins.b %0:t, %1 \n\t" + : "=&r"(v) + : "RKs12"(* (const uint8_t*)p), + "RKs12"(*((const uint8_t*)p+1)), + "RKs12"(*((const uint8_t*)p+2)), + "m" (*((const uint8_t*)p+3))); + return v; +} + +#define AV_RL32 AV_RL32 +static av_always_inline uint32_t AV_RL32(const void *p) +{ + uint32_t v; + __asm__ ("ld.ub %0, %1 \n\t" + "ldins.b %0:l, %2 \n\t" + "ldins.b %0:u, %3 \n\t" + "ldins.b %0:t, %4 \n\t" + : "=&r"(v) + : "m" (* (const uint8_t*)p), + "RKs12"(*((const uint8_t*)p+1)), + "RKs12"(*((const uint8_t*)p+2)), + "RKs12"(*((const uint8_t*)p+3))); + return v; +} + +#endif /* ARCH_AVR32_AP */ + +#define AV_RB64 AV_RB64 +static av_always_inline uint64_t AV_RB64(const void *p) +{ + union { uint64_t v; uint32_t hl[2]; } v; + v.hl[0] = AV_RB32(p); + v.hl[1] = AV_RB32((const uint32_t*)p+1); + return v.v; +} + +#define AV_RL64 AV_RL64 +static av_always_inline uint64_t AV_RL64(const void *p) +{ + union { uint64_t v; uint32_t hl[2]; } v; + v.hl[1] = AV_RL32(p); + v.hl[0] = AV_RL32((const uint32_t*)p+1); + return v.v; +} + +#endif /* AVUTIL_AVR32_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avsscanf.c b/arm/raspi/third_party/ffmpeg/libavutil/avsscanf.c new file mode 100644 index 00000000..be9d7434 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avsscanf.c @@ -0,0 +1,974 @@ +/* + * Copyright (c) 2005-2014 Rich Felker, et al. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "avstring.h" +#include "libm.h" + +typedef struct FFFILE { + size_t buf_size; + unsigned char *buf; + unsigned char *rpos, *rend; + unsigned char *shend; + ptrdiff_t shlim, shcnt; + void *cookie; + size_t (*read)(struct FFFILE *, unsigned char *, size_t); +} FFFILE; + +#define SIZE_hh -2 +#define SIZE_h -1 +#define SIZE_def 0 +#define SIZE_l 1 +#define SIZE_L 2 +#define SIZE_ll 3 + +#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf)) + +static int fftoread(FFFILE *f) +{ + f->rpos = f->rend = f->buf + f->buf_size; + return 0; +} + +static size_t ffstring_read(FFFILE *f, unsigned char *buf, size_t len) +{ + char *src = f->cookie; + size_t k = len+256; + char *end = memchr(src, 0, k); + + if (end) k = end-src; + if (k < len) len = k; + memcpy(buf, src, len); + f->rpos = (void *)(src+len); + f->rend = (void *)(src+k); + f->cookie = src+k; + + return len; +} + +static int ffuflow(FFFILE *f) +{ + unsigned char c; + if (!fftoread(f) && f->read(f, &c, 1)==1) return c; + return EOF; +} + +static void ffshlim(FFFILE *f, ptrdiff_t lim) +{ + f->shlim = lim; + f->shcnt = f->buf - f->rpos; + /* If lim is nonzero, rend must be a valid pointer. */ + if (lim && f->rend - f->rpos > lim) + f->shend = f->rpos + lim; + else + f->shend = f->rend; +} + +static int ffshgetc(FFFILE *f) +{ + int c; + ptrdiff_t cnt = shcnt(f); + if (f->shlim && cnt >= f->shlim || (c=ffuflow(f)) < 0) { + f->shcnt = f->buf - f->rpos + cnt; + f->shend = 0; + return EOF; + } + cnt++; + if (f->shlim && f->rend - f->rpos > f->shlim - cnt) + f->shend = f->rpos + (f->shlim - cnt); + else + f->shend = f->rend; + f->shcnt = f->buf - f->rpos + cnt; + if (f->rpos[-1] != c) f->rpos[-1] = c; + return c; +} + +#define shlim(f, lim) ffshlim((f), (lim)) +#define shgetc(f) (((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc(f)) +#define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0) + +static const unsigned char table[] = { -1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +}; + +static unsigned long long ffintscan(FFFILE *f, unsigned base, int pok, unsigned long long lim) +{ + const unsigned char *val = table+1; + int c, neg=0; + unsigned x; + unsigned long long y; + if (base > 36 || base == 1) { + errno = EINVAL; + return 0; + } + while (av_isspace((c=shgetc(f)))); + if (c=='+' || c=='-') { + neg = -(c=='-'); + c = shgetc(f); + } + if ((base == 0 || base == 16) && c=='0') { + c = shgetc(f); + if ((c|32)=='x') { + c = shgetc(f); + if (val[c]>=16) { + shunget(f); + if (pok) shunget(f); + else shlim(f, 0); + return 0; + } + base = 16; + } else if (base == 0) { + base = 8; + } + } else { + if (base == 0) base = 10; + if (val[c] >= base) { + shunget(f); + shlim(f, 0); + errno = EINVAL; + return 0; + } + } + if (base == 10) { + for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f)) + x = x*10 + (c-'0'); + for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f)) + y = y*10 + (c-'0'); + if (c-'0'>=10U) goto done; + } else if (!(base & base-1)) { + int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7]; + for (x=0; val[c]>bs; c=shgetc(f)) + y = y<=lim) { + if (!(lim&1) && !neg) { + errno = ERANGE; + return lim-1; + } else if (y>lim) { + errno = ERANGE; + return lim; + } + } + return (y^neg)-neg; +} + +static long long scanexp(FFFILE *f, int pok) +{ + int c; + int x; + long long y; + int neg = 0; + + c = shgetc(f); + if (c=='+' || c=='-') { + neg = (c=='-'); + c = shgetc(f); + if (c-'0'>=10U && pok) shunget(f); + } + if (c-'0'>=10U) { + shunget(f); + return LLONG_MIN; + } + for (x=0; c-'0'<10U && x=0) { + shunget(f); + } + if (!gotdig) { + errno = EINVAL; + shlim(f, 0); + return 0; + } + + /* Handle zero specially to avoid nasty special cases later */ + if (!x[0]) return sign * 0.0; + + /* Optimize small integers (w/no exponent) and over/under-flow */ + if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0)) + return sign * (double)x[0]; + if (lrp > -emin/2) { + errno = ERANGE; + return sign * DBL_MAX * DBL_MAX; + } + if (lrp < emin-2*DBL_MANT_DIG) { + errno = ERANGE; + return sign * DBL_MIN * DBL_MIN; + } + + /* Align incomplete final B1B digit */ + if (j) { + for (; j<9; j++) x[k]*=10; + k++; + j=0; + } + + a = 0; + z = k; + e2 = 0; + rp = lrp; + + /* Optimize small to mid-size integers (even in exp. notation) */ + if (lnz<9 && lnz<=rp && rp < 18) { + int bitlim; + if (rp == 9) return sign * (double)x[0]; + if (rp < 9) return sign * (double)x[0] / p10s[8-rp]; + bitlim = bits-3*(int)(rp-9); + if (bitlim>30 || x[0]>>bitlim==0) + return sign * (double)x[0] * p10s[rp-10]; + } + + /* Drop trailing zeros */ + for (; !x[z-1]; z--); + + /* Align radix point to B1B digit boundary */ + if (rp % 9) { + int rpm9 = rp>=0 ? rp%9 : rp%9+9; + int p10 = p10s[8-rpm9]; + uint32_t carry = 0; + for (k=a; k!=z; k++) { + uint32_t tmp = x[k] % p10; + x[k] = x[k]/p10 + carry; + carry = 1000000000/p10 * tmp; + if (k==a && !x[k]) { + a = (a+1 & MASK); + rp -= 9; + } + } + if (carry) x[z++] = carry; + rp += 9-rpm9; + } + + /* Upscale until desired number of bits are left of radix point */ + while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a] 1000000000) { + carry = tmp / 1000000000; + x[k] = tmp % 1000000000; + } else { + carry = 0; + x[k] = tmp; + } + if (k==(z-1 & MASK) && k!=a && !x[k]) z = k; + if (k==a) break; + } + if (carry) { + rp += 9; + a = (a-1 & MASK); + if (a == z) { + z = (z-1 & MASK); + x[z-1 & MASK] |= x[z]; + } + x[a] = carry; + } + } + + /* Downscale until exactly number of bits are left of radix point */ + for (;;) { + uint32_t carry = 0; + int sh = 1; + for (i=0; i th[i]) break; + } + if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break; + /* FIXME: find a way to compute optimal sh */ + if (rp > 9+9*LD_B1B_DIG) sh = 9; + e2 += sh; + for (k=a; k!=z; k=(k+1 & MASK)) { + uint32_t tmp = x[k] & (1<>sh) + carry; + carry = (1000000000>>sh) * tmp; + if (k==a && !x[k]) { + a = (a+1 & MASK); + i--; + rp -= 9; + } + } + if (carry) { + if ((z+1 & MASK) != a) { + x[z] = carry; + z = (z+1 & MASK); + } else x[z-1 & MASK] |= 1; + } + } + + /* Assemble desired bits into floating point variable */ + for (y=i=0; i DBL_MANT_DIG+e2-emin) { + bits = DBL_MANT_DIG+e2-emin; + if (bits<0) bits=0; + denormal = 1; + } + + /* Calculate bias term to force rounding, move out lower bits */ + if (bits < DBL_MANT_DIG) { + bias = copysign(scalbn(1, 2*DBL_MANT_DIG-bits-1), y); + frac = fmod(y, scalbn(1, DBL_MANT_DIG-bits)); + y -= frac; + y += bias; + } + + /* Process tail of decimal input so it can affect rounding */ + if ((a+i & MASK) != z) { + uint32_t t = x[a+i & MASK]; + if (t < 500000000 && (t || (a+i+1 & MASK) != z)) + frac += 0.25*sign; + else if (t > 500000000) + frac += 0.75*sign; + else if (t == 500000000) { + if ((a+i+1 & MASK) == z) + frac += 0.5*sign; + else + frac += 0.75*sign; + } + if (DBL_MANT_DIG-bits >= 2 && !fmod(frac, 1)) + frac++; + } + + y += frac; + y -= bias; + + if ((e2+DBL_MANT_DIG & INT_MAX) > emax-5) { + if (fabs(y) >= pow(2, DBL_MANT_DIG)) { + if (denormal && bits==DBL_MANT_DIG+e2-emin) + denormal = 0; + y *= 0.5; + e2++; + } + if (e2+DBL_MANT_DIG>emax || (denormal && frac)) + errno = ERANGE; + } + + return scalbn(y, e2); +} + +static double hexfloat(FFFILE *f, int bits, int emin, int sign, int pok) +{ + uint32_t x = 0; + double y = 0; + double scale = 1; + double bias = 0; + int gottail = 0, gotrad = 0, gotdig = 0; + long long rp = 0; + long long dc = 0; + long long e2 = 0; + int d; + int c; + + c = shgetc(f); + + /* Skip leading zeros */ + for (; c=='0'; c = shgetc(f)) + gotdig = 1; + + if (c=='.') { + gotrad = 1; + c = shgetc(f); + /* Count zeros after the radix point before significand */ + for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1; + } + + for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) { + if (c=='.') { + if (gotrad) break; + rp = dc; + gotrad = 1; + } else { + gotdig = 1; + if (c > '9') d = (c|32)+10-'a'; + else d = c-'0'; + if (dc<8) { + x = x*16 + d; + } else if (dc < DBL_MANT_DIG/4+1) { + y += d*(scale/=16); + } else if (d && !gottail) { + y += 0.5*scale; + gottail = 1; + } + dc++; + } + } + if (!gotdig) { + shunget(f); + if (pok) { + shunget(f); + if (gotrad) shunget(f); + } else { + shlim(f, 0); + } + return sign * 0.0; + } + if (!gotrad) rp = dc; + while (dc<8) x *= 16, dc++; + if ((c|32)=='p') { + e2 = scanexp(f, pok); + if (e2 == LLONG_MIN) { + if (pok) { + shunget(f); + } else { + shlim(f, 0); + return 0; + } + e2 = 0; + } + } else { + shunget(f); + } + e2 += 4*rp - 32; + + if (!x) return sign * 0.0; + if (e2 > -emin) { + errno = ERANGE; + return sign * DBL_MAX * DBL_MAX; + } + if (e2 < emin-2*DBL_MANT_DIG) { + errno = ERANGE; + return sign * DBL_MIN * DBL_MIN; + } + + while (x < 0x80000000) { + if (y>=0.5) { + x += x + 1; + y += y - 1; + } else { + x += x; + y += y; + } + e2--; + } + + if (bits > 32+e2-emin) { + bits = 32+e2-emin; + if (bits<0) bits=0; + } + + if (bits < DBL_MANT_DIG) + bias = copysign(scalbn(1, 32+DBL_MANT_DIG-bits-1), sign); + + if (bits<32 && y && !(x&1)) x++, y=0; + + y = bias + sign*(double)x + sign*y; + y -= bias; + + if (!y) errno = ERANGE; + + return scalbn(y, e2); +} + +static double fffloatscan(FFFILE *f, int prec, int pok) +{ + int sign = 1; + size_t i; + int bits; + int emin; + int c; + + switch (prec) { + case 0: + bits = FLT_MANT_DIG; + emin = FLT_MIN_EXP-bits; + break; + case 1: + bits = DBL_MANT_DIG; + emin = DBL_MIN_EXP-bits; + break; + case 2: + bits = DBL_MANT_DIG; + emin = DBL_MIN_EXP-bits; + break; + default: + return 0; + } + + while (av_isspace((c = shgetc(f)))); + + if (c=='+' || c=='-') { + sign -= 2*(c=='-'); + c = shgetc(f); + } + + for (i=0; i<8 && (c|32)=="infinity"[i]; i++) + if (i<7) c = shgetc(f); + if (i==3 || i==8 || (i>3 && pok)) { + if (i!=8) { + shunget(f); + if (pok) for (; i>3; i--) shunget(f); + } + return sign * INFINITY; + } + if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++) + if (i<2) c = shgetc(f); + if (i==3) { + if (shgetc(f) != '(') { + shunget(f); + return NAN; + } + for (i=1; ; i++) { + c = shgetc(f); + if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_') + continue; + if (c==')') return NAN; + shunget(f); + if (!pok) { + errno = EINVAL; + shlim(f, 0); + return 0; + } + while (i--) shunget(f); + return NAN; + } + return NAN; + } + + if (i) { + shunget(f); + errno = EINVAL; + shlim(f, 0); + return 0; + } + + if (c=='0') { + c = shgetc(f); + if ((c|32) == 'x') + return hexfloat(f, bits, emin, sign, pok); + shunget(f); + c = '0'; + } + + return decfloat(f, c, bits, emin, sign, pok); +} + +static void *arg_n(va_list ap, unsigned int n) +{ + void *p; + unsigned int i; + va_list ap2; + va_copy(ap2, ap); + for (i=n; i>1; i--) va_arg(ap2, void *); + p = va_arg(ap2, void *); + va_end(ap2); + return p; +} + +static void store_int(void *dest, int size, unsigned long long i) +{ + if (!dest) return; + switch (size) { + case SIZE_hh: + *(char *)dest = i; + break; + case SIZE_h: + *(short *)dest = i; + break; + case SIZE_def: + *(int *)dest = i; + break; + case SIZE_l: + *(long *)dest = i; + break; + case SIZE_ll: + *(long long *)dest = i; + break; + } +} + +static int ff_vfscanf(FFFILE *f, const char *fmt, va_list ap) +{ + int width; + int size; + int base; + const unsigned char *p; + int c, t; + char *s; + void *dest=NULL; + int invert; + int matches=0; + unsigned long long x; + double y; + ptrdiff_t pos = 0; + unsigned char scanset[257]; + size_t i; + + for (p=(const unsigned char *)fmt; *p; p++) { + + if (av_isspace(*p)) { + while (av_isspace(p[1])) p++; + shlim(f, 0); + while (av_isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + continue; + } + if (*p != '%' || p[1] == '%') { + shlim(f, 0); + if (*p == '%') { + p++; + while (av_isspace((c=shgetc(f)))); + } else { + c = shgetc(f); + } + if (c!=*p) { + shunget(f); + if (c<0) goto input_fail; + goto match_fail; + } + pos += shcnt(f); + continue; + } + + p++; + if (*p=='*') { + dest = 0; p++; + } else if (av_isdigit(*p) && p[1]=='$') { + dest = arg_n(ap, *p-'0'); p+=2; + } else { + dest = va_arg(ap, void *); + } + + for (width=0; av_isdigit(*p); p++) { + width = 10*width + *p - '0'; + } + + if (*p=='m') { + s = 0; + p++; + } + + size = SIZE_def; + switch (*p++) { + case 'h': + if (*p == 'h') p++, size = SIZE_hh; + else size = SIZE_h; + break; + case 'l': + if (*p == 'l') p++, size = SIZE_ll; + else size = SIZE_l; + break; + case 'j': + size = SIZE_ll; + break; + case 'z': + case 't': + size = SIZE_l; + break; + case 'L': + size = SIZE_L; + break; + case 'd': case 'i': case 'o': case 'u': case 'x': + case 'a': case 'e': case 'f': case 'g': + case 'A': case 'E': case 'F': case 'G': case 'X': + case 's': case 'c': case '[': + case 'S': case 'C': + case 'p': case 'n': + p--; + break; + default: + goto fmt_fail; + } + + t = *p; + + /* C or S */ + if ((t&0x2f) == 3) { + t |= 32; + size = SIZE_l; + } + + switch (t) { + case 'c': + if (width < 1) width = 1; + case '[': + break; + case 'n': + store_int(dest, size, pos); + /* do not increment match count, etc! */ + continue; + default: + shlim(f, 0); + while (av_isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + } + + shlim(f, width); + if (shgetc(f) < 0) goto input_fail; + shunget(f); + + switch (t) { + case 's': + case 'c': + case '[': + if (t == 'c' || t == 's') { + memset(scanset, -1, sizeof scanset); + scanset[0] = 0; + if (t == 's') { + scanset[1 + '\t'] = 0; + scanset[1 + '\n'] = 0; + scanset[1 + '\v'] = 0; + scanset[1 + '\f'] = 0; + scanset[1 + '\r'] = 0; + scanset[1 + ' ' ] = 0; + } + } else { + if (*++p == '^') p++, invert = 1; + else invert = 0; + memset(scanset, invert, sizeof scanset); + scanset[0] = 0; + if (*p == '-') p++, scanset[1+'-'] = 1-invert; + else if (*p == ']') p++, scanset[1+']'] = 1-invert; + for (; *p != ']'; p++) { + if (!*p) goto fmt_fail; + if (*p=='-' && p[1] && p[1] != ']') + for (c=p++[-1]; c<*p; c++) + scanset[1+c] = 1-invert; + scanset[1+*p] = 1-invert; + } + } + s = 0; + i = 0; + if ((s = dest)) { + while (scanset[(c=shgetc(f))+1]) + s[i++] = c; + } else { + while (scanset[(c=shgetc(f))+1]); + } + shunget(f); + if (!shcnt(f)) goto match_fail; + if (t == 'c' && shcnt(f) != width) goto match_fail; + if (t != 'c') { + if (s) s[i] = 0; + } + break; + case 'p': + case 'X': + case 'x': + base = 16; + goto int_common; + case 'o': + base = 8; + goto int_common; + case 'd': + case 'u': + base = 10; + goto int_common; + case 'i': + base = 0; +int_common: + x = ffintscan(f, base, 0, ULLONG_MAX); + if (!shcnt(f)) + goto match_fail; + if (t=='p' && dest) + *(void **)dest = (void *)(uintptr_t)x; + else + store_int(dest, size, x); + break; + case 'a': case 'A': + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': + y = fffloatscan(f, size, 0); + if (!shcnt(f)) + goto match_fail; + if (dest) { + switch (size) { + case SIZE_def: + *(float *)dest = y; + break; + case SIZE_l: + *(double *)dest = y; + break; + case SIZE_L: + *(double *)dest = y; + break; + } + } + break; + } + + pos += shcnt(f); + if (dest) matches++; + } + if (0) { +fmt_fail: +input_fail: + if (!matches) matches--; + } +match_fail: + return matches; +} + +static int ff_vsscanf(const char *s, const char *fmt, va_list ap) +{ + FFFILE f = { + .buf = (void *)s, .cookie = (void *)s, + .read = ffstring_read, + }; + + return ff_vfscanf(&f, fmt, ap); +} + +// Chromium: av_sscanf() is ~8kb in implementation and isn't used by any +// methods needed for Chromium; drop to save binary size. +#if 0 +int av_sscanf(const char *string, const char *format, ...) +{ + int ret; + va_list ap; + va_start(ap, format); + ret = ff_vsscanf(string, format, ap); + va_end(ap); + return ret; +} +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avstring.c b/arm/raspi/third_party/ffmpeg/libavutil/avstring.c new file mode 100644 index 00000000..5ddbe921 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avstring.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "mem.h" +#include "avassert.h" +#include "avstring.h" +#include "bprint.h" +#include "error.h" +#include "macros.h" +#include "version.h" + +int av_strstart(const char *str, const char *pfx, const char **ptr) +{ + while (*pfx && *pfx == *str) { + pfx++; + str++; + } + if (!*pfx && ptr) + *ptr = str; + return !*pfx; +} + +int av_stristart(const char *str, const char *pfx, const char **ptr) +{ + while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) { + pfx++; + str++; + } + if (!*pfx && ptr) + *ptr = str; + return !*pfx; +} + +char *av_stristr(const char *s1, const char *s2) +{ + if (!*s2) + return (char*)(intptr_t)s1; + + do + if (av_stristart(s1, s2, NULL)) + return (char*)(intptr_t)s1; + while (*s1++); + + return NULL; +} + +char *av_strnstr(const char *haystack, const char *needle, size_t hay_length) +{ + size_t needle_len = strlen(needle); + if (!needle_len) + return (char*)haystack; + while (hay_length >= needle_len) { + hay_length--; + if (!memcmp(haystack, needle, needle_len)) + return (char*)haystack; + haystack++; + } + return NULL; +} + +size_t av_strlcpy(char *dst, const char *src, size_t size) +{ + size_t len = 0; + while (++len < size && *src) + *dst++ = *src++; + if (len <= size) + *dst = 0; + return len + strlen(src) - 1; +} + +size_t av_strlcat(char *dst, const char *src, size_t size) +{ + size_t len = strlen(dst); + if (size <= len + 1) + return len + strlen(src); + return len + av_strlcpy(dst + len, src, size - len); +} + +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) +{ + size_t len = strlen(dst); + va_list vl; + + va_start(vl, fmt); + len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl); + va_end(vl); + + return len; +} + +char *av_asprintf(const char *fmt, ...) +{ + char *p = NULL; + va_list va; + int len; + + va_start(va, fmt); + len = vsnprintf(NULL, 0, fmt, va); + va_end(va); + if (len < 0) + goto end; + + p = av_malloc(len + 1); + if (!p) + goto end; + + va_start(va, fmt); + len = vsnprintf(p, len + 1, fmt, va); + va_end(va); + if (len < 0) + av_freep(&p); + +end: + return p; +} + +#if FF_API_D2STR +char *av_d2str(double d) +{ + char *str = av_malloc(16); + if (str) + snprintf(str, 16, "%f", d); + return str; +} +#endif + +#define WHITESPACES " \n\t\r" + +char *av_get_token(const char **buf, const char *term) +{ + char *out = av_malloc(strlen(*buf) + 1); + char *ret = out, *end = out; + const char *p = *buf; + if (!out) + return NULL; + p += strspn(p, WHITESPACES); + + while (*p && !strspn(p, term)) { + char c = *p++; + if (c == '\\' && *p) { + *out++ = *p++; + end = out; + } else if (c == '\'') { + while (*p && *p != '\'') + *out++ = *p++; + if (*p) { + p++; + end = out; + } + } else { + *out++ = c; + } + } + + do + *out-- = 0; + while (out >= end && strspn(out, WHITESPACES)); + + *buf = p; + + return ret; +} + +char *av_strtok(char *s, const char *delim, char **saveptr) +{ + char *tok; + + if (!s && !(s = *saveptr)) + return NULL; + + /* skip leading delimiters */ + s += strspn(s, delim); + + /* s now points to the first non delimiter char, or to the end of the string */ + if (!*s) { + *saveptr = NULL; + return NULL; + } + tok = s++; + + /* skip non delimiters */ + s += strcspn(s, delim); + if (*s) { + *s = 0; + *saveptr = s+1; + } else { + *saveptr = NULL; + } + + return tok; +} + +int av_strcasecmp(const char *a, const char *b) +{ + uint8_t c1, c2; + do { + c1 = av_tolower(*a++); + c2 = av_tolower(*b++); + } while (c1 && c1 == c2); + return c1 - c2; +} + +int av_strncasecmp(const char *a, const char *b, size_t n) +{ + uint8_t c1, c2; + if (n <= 0) + return 0; + do { + c1 = av_tolower(*a++); + c2 = av_tolower(*b++); + } while (--n && c1 && c1 == c2); + return c1 - c2; +} + +char *av_strireplace(const char *str, const char *from, const char *to) +{ + char *ret = NULL; + const char *pstr2, *pstr = str; + size_t tolen = strlen(to), fromlen = strlen(from); + AVBPrint pbuf; + + av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); + while ((pstr2 = av_stristr(pstr, from))) { + av_bprint_append_data(&pbuf, pstr, pstr2 - pstr); + pstr = pstr2 + fromlen; + av_bprint_append_data(&pbuf, to, tolen); + } + av_bprint_append_data(&pbuf, pstr, strlen(pstr)); + if (!av_bprint_is_complete(&pbuf)) { + av_bprint_finalize(&pbuf, NULL); + } else { + av_bprint_finalize(&pbuf, &ret); + } + + return ret; +} + +const char *av_basename(const char *path) +{ + char *p; +#if HAVE_DOS_PATHS + char *q, *d; +#endif + + if (!path || *path == '\0') + return "."; + + p = strrchr(path, '/'); +#if HAVE_DOS_PATHS + q = strrchr(path, '\\'); + d = strchr(path, ':'); + p = FFMAX3(p, q, d); +#endif + + if (!p) + return path; + + return p + 1; +} + +const char *av_dirname(char *path) +{ + char *p = path ? strrchr(path, '/') : NULL; + +#if HAVE_DOS_PATHS + char *q = path ? strrchr(path, '\\') : NULL; + char *d = path ? strchr(path, ':') : NULL; + + d = d ? d + 1 : d; + + p = FFMAX3(p, q, d); +#endif + + if (!p) + return "."; + + *p = '\0'; + + return path; +} + +char *av_append_path_component(const char *path, const char *component) +{ + size_t p_len, c_len; + char *fullpath; + + if (!path) + return av_strdup(component); + if (!component) + return av_strdup(path); + + p_len = strlen(path); + c_len = strlen(component); + if (p_len > SIZE_MAX - c_len || p_len + c_len > SIZE_MAX - 2) + return NULL; + fullpath = av_malloc(p_len + c_len + 2); + if (fullpath) { + if (p_len) { + av_strlcpy(fullpath, path, p_len + 1); + if (c_len) { + if (fullpath[p_len - 1] != '/' && component[0] != '/') + fullpath[p_len++] = '/'; + else if (fullpath[p_len - 1] == '/' && component[0] == '/') + p_len--; + } + } + av_strlcpy(&fullpath[p_len], component, c_len + 1); + fullpath[p_len + c_len] = 0; + } + return fullpath; +} + +int av_escape(char **dst, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags) +{ + AVBPrint dstbuf; + int ret; + + av_bprint_init(&dstbuf, 1, INT_MAX); /* (int)dstbuf.len must be >= 0 */ + av_bprint_escape(&dstbuf, src, special_chars, mode, flags); + + if (!av_bprint_is_complete(&dstbuf)) { + av_bprint_finalize(&dstbuf, NULL); + return AVERROR(ENOMEM); + } + if ((ret = av_bprint_finalize(&dstbuf, dst)) < 0) + return ret; + return dstbuf.len; +} + +int av_match_name(const char *name, const char *names) +{ + const char *p; + int len, namelen; + + if (!name || !names) + return 0; + + namelen = strlen(name); + while (*names) { + int negate = '-' == *names; + p = strchr(names, ','); + if (!p) + p = names + strlen(names); + names += negate; + len = FFMAX(p - names, namelen); + if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names))) + return !negate; + names = p + (*p == ','); + } + return 0; +} + +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, + unsigned int flags) +{ + const uint8_t *p = *bufp; + uint32_t top; + uint64_t code; + int ret = 0, tail_len; + uint32_t overlong_encoding_mins[6] = { + 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000, + }; + + if (p >= buf_end) + return 0; + + code = *p++; + + /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111, + which is not admitted */ + if ((code & 0xc0) == 0x80 || code >= 0xFE) { + ret = AVERROR(EILSEQ); + goto end; + } + top = (code & 128) >> 1; + + tail_len = 0; + while (code & top) { + int tmp; + tail_len++; + if (p >= buf_end) { + (*bufp) ++; + return AVERROR(EILSEQ); /* incomplete sequence */ + } + + /* we assume the byte to be in the form 10xx-xxxx */ + tmp = *p++ - 128; /* strip leading 1 */ + if (tmp>>6) { + (*bufp) ++; + return AVERROR(EILSEQ); + } + code = (code<<6) + tmp; + top <<= 5; + } + code &= (top << 1) - 1; + + /* check for overlong encodings */ + av_assert0(tail_len <= 5); + if (code < overlong_encoding_mins[tail_len]) { + ret = AVERROR(EILSEQ); + goto end; + } + + if (code >= 1U<<31) { + ret = AVERROR(EILSEQ); /* out-of-range value */ + goto end; + } + + *codep = code; + + if (code > 0x10FFFF && + !(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES)) + ret = AVERROR(EILSEQ); + if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD && + flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES) + ret = AVERROR(EILSEQ); + if (code >= 0xD800 && code <= 0xDFFF && + !(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES)) + ret = AVERROR(EILSEQ); + if ((code == 0xFFFE || code == 0xFFFF) && + !(flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS)) + ret = AVERROR(EILSEQ); + +end: + *bufp = p; + return ret; +} + +int av_match_list(const char *name, const char *list, char separator) +{ + const char *p, *q; + + for (p = name; p && *p; ) { + for (q = list; q && *q; ) { + int k; + for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++) + if (k && (!p[k] || p[k] == separator)) + return 1; + q = strchr(q, separator); + q += !!q; + } + p = strchr(p, separator); + p += !!p; + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avstring.h b/arm/raspi/third_party/ffmpeg/libavutil/avstring.h new file mode 100644 index 00000000..1094b2b4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avstring.h @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVSTRING_H +#define AVUTIL_AVSTRING_H + +#include +#include +#include "attributes.h" +#include "version.h" + +/** + * @addtogroup lavu_string + * @{ + */ + +/** + * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to + * the address of the first character in str after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_strstart(const char *str, const char *pfx, const char **ptr); + +/** + * Return non-zero if pfx is a prefix of str independent of case. If + * it is, *ptr is set to the address of the first character in str + * after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_stristart(const char *str, const char *pfx, const char **ptr); + +/** + * Locate the first case-independent occurrence in the string haystack + * of the string needle. A zero-length string needle is considered to + * match at the start of haystack. + * + * This function is a case-insensitive version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_stristr(const char *haystack, const char *needle); + +/** + * Locate the first occurrence of the string needle in the string haystack + * where not more than hay_length characters are searched. A zero-length + * string needle is considered to match at the start of haystack. + * + * This function is a length-limited version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @param hay_length length of string to search in + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_strnstr(const char *haystack, const char *needle, size_t hay_length); + +/** + * Copy the string src to dst, but no more than size - 1 bytes, and + * null-terminate dst. + * + * This function is the same as BSD strlcpy(). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the length of src + * + * @warning since the return value is the length of src, src absolutely + * _must_ be a properly 0-terminated string, otherwise this will read beyond + * the end of the buffer and possibly crash. + */ +size_t av_strlcpy(char *dst, const char *src, size_t size); + +/** + * Append the string src to the string dst, but to a total length of + * no more than size - 1 bytes, and null-terminate dst. + * + * This function is similar to BSD strlcat(), but differs when + * size <= strlen(dst). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the total length of src and dst + * + * @warning since the return value use the length of src and dst, these + * absolutely _must_ be a properly 0-terminated strings, otherwise this + * will read beyond the end of the buffer and possibly crash. + */ +size_t av_strlcat(char *dst, const char *src, size_t size); + +/** + * Append output to a string, according to a format. Never write out of + * the destination buffer, and always put a terminating 0 within + * the buffer. + * @param dst destination buffer (string to which the output is + * appended) + * @param size total size of the destination buffer + * @param fmt printf-compatible format string, specifying how the + * following parameters are used + * @return the length of the string that would have been generated + * if enough space had been available + */ +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4); + +/** + * Get the count of continuous non zero chars starting from the beginning. + * + * @param s the string whose length to count + * @param len maximum number of characters to check in the string, that + * is the maximum value which is returned by the function + */ +static inline size_t av_strnlen(const char *s, size_t len) +{ + size_t i; + for (i = 0; i < len && s[i]; i++) + ; + return i; +} + +/** + * Print arguments following specified format into a large enough auto + * allocated buffer. It is similar to GNU asprintf(). + * @param fmt printf-compatible format string, specifying how the + * following parameters are used. + * @return the allocated string + * @note You have to free the string yourself with av_free(). + */ +char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2); + +#if FF_API_D2STR +/** + * Convert a number to an av_malloced string. + * @deprecated use av_asprintf() with "%f" or a more specific format + */ +attribute_deprecated +char *av_d2str(double d); +#endif + +/** + * Unescape the given string until a non escaped terminating char, + * and return the token corresponding to the unescaped string. + * + * The normal \ and ' escaping is supported. Leading and trailing + * whitespaces are removed, unless they are escaped with '\' or are + * enclosed between ''. + * + * @param buf the buffer to parse, buf will be updated to point to the + * terminating char + * @param term a 0-terminated list of terminating chars + * @return the malloced unescaped string, which must be av_freed by + * the user, NULL in case of allocation failure + */ +char *av_get_token(const char **buf, const char *term); + +/** + * Split the string into several tokens which can be accessed by + * successive calls to av_strtok(). + * + * A token is defined as a sequence of characters not belonging to the + * set specified in delim. + * + * On the first call to av_strtok(), s should point to the string to + * parse, and the value of saveptr is ignored. In subsequent calls, s + * should be NULL, and saveptr should be unchanged since the previous + * call. + * + * This function is similar to strtok_r() defined in POSIX.1. + * + * @param s the string to parse, may be NULL + * @param delim 0-terminated list of token delimiters, must be non-NULL + * @param saveptr user-provided pointer which points to stored + * information necessary for av_strtok() to continue scanning the same + * string. saveptr is updated to point to the next character after the + * first delimiter found, or to NULL if the string was terminated + * @return the found token, or NULL when no token is found + */ +char *av_strtok(char *s, const char *delim, char **saveptr); + +/** + * Locale-independent conversion of ASCII isdigit. + */ +static inline av_const int av_isdigit(int c) +{ + return c >= '0' && c <= '9'; +} + +/** + * Locale-independent conversion of ASCII isgraph. + */ +static inline av_const int av_isgraph(int c) +{ + return c > 32 && c < 127; +} + +/** + * Locale-independent conversion of ASCII isspace. + */ +static inline av_const int av_isspace(int c) +{ + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || + c == '\v'; +} + +/** + * Locale-independent conversion of ASCII characters to uppercase. + */ +static inline av_const int av_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII characters to lowercase. + */ +static inline av_const int av_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII isxdigit. + */ +static inline av_const int av_isxdigit(int c) +{ + c = av_tolower(c); + return av_isdigit(c) || (c >= 'a' && c <= 'f'); +} + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strcasecmp(const char *a, const char *b); + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strncasecmp(const char *a, const char *b, size_t n); + +/** + * Locale-independent strings replace. + * @note This means only ASCII-range characters are replace + */ +char *av_strireplace(const char *str, const char *from, const char *to); + +/** + * Thread safe basename. + * @param path the string to parse, on DOS both \ and / are considered separators. + * @return pointer to the basename substring. + * If path does not contain a slash, the function returns a copy of path. + * If path is a NULL pointer or points to an empty string, a pointer + * to a string "." is returned. + */ +const char *av_basename(const char *path); + +/** + * Thread safe dirname. + * @param path the string to parse, on DOS both \ and / are considered separators. + * @return A pointer to a string that's the parent directory of path. + * If path is a NULL pointer or points to an empty string, a pointer + * to a string "." is returned. + * @note the function may modify the contents of the path, so copies should be passed. + */ +const char *av_dirname(char *path); + +/** + * Match instances of a name in a comma-separated list of names. + * List entries are checked from the start to the end of the names list, + * the first match ends further processing. If an entry prefixed with '-' + * matches, then 0 is returned. The "ALL" list entry is considered to + * match all names. + * + * @param name Name to look for. + * @param names List of names. + * @return 1 on match, 0 otherwise. + */ +int av_match_name(const char *name, const char *names); + +/** + * Append path component to the existing path. + * Path separator '/' is placed between when needed. + * Resulting string have to be freed with av_free(). + * @param path base path + * @param component component to be appended + * @return new path or NULL on error. + */ +char *av_append_path_component(const char *path, const char *component); + +enum AVEscapeMode { + AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode. + AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping. + AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping. + AV_ESCAPE_MODE_XML, ///< Use XML non-markup character data escaping. +}; + +/** + * Consider spaces special and escape them even in the middle of the + * string. + * + * This is equivalent to adding the whitespace characters to the special + * characters lists, except it is guaranteed to use the exact same list + * of whitespace characters as the rest of libavutil. + */ +#define AV_ESCAPE_FLAG_WHITESPACE (1 << 0) + +/** + * Escape only specified special characters. + * Without this flag, escape also any characters that may be considered + * special by av_get_token(), such as the single quote. + */ +#define AV_ESCAPE_FLAG_STRICT (1 << 1) + +/** + * Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single + * quoted attributes. + */ +#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES (1 << 2) + +/** + * Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double + * quoted attributes. + */ +#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES (1 << 3) + + +/** + * Escape string in src, and put the escaped string in an allocated + * string in *dst, which must be freed with av_free(). + * + * @param dst pointer where an allocated string is put + * @param src string to escape, must be non-NULL + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_ macros + * @return the length of the allocated string, or a negative error code in case of error + * @see av_bprint_escape() + */ +av_warn_unused_result +int av_escape(char **dst, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +#define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 ///< accept codepoints over 0x10FFFF +#define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 ///< accept non-characters - 0xFFFE and 0xFFFF +#define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 ///< accept UTF-16 surrogates codes +#define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 ///< exclude control codes not accepted by XML + +#define AV_UTF8_FLAG_ACCEPT_ALL \ + AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES + +/** + * Read and decode a single UTF-8 code point (character) from the + * buffer in *buf, and update *buf to point to the next byte to + * decode. + * + * In case of an invalid byte sequence, the pointer will be updated to + * the next byte after the invalid sequence and the function will + * return an error code. + * + * Depending on the specified flags, the function will also fail in + * case the decoded code point does not belong to a valid range. + * + * @note For speed-relevant code a carefully implemented use of + * GET_UTF8() may be preferred. + * + * @param codep pointer used to return the parsed code in case of success. + * The value in *codep is set even in case the range check fails. + * @param bufp pointer to the address the first byte of the sequence + * to decode, updated by the function to point to the + * byte next after the decoded sequence + * @param buf_end pointer to the end of the buffer, points to the next + * byte past the last in the buffer. This is used to + * avoid buffer overreads (in case of an unfinished + * UTF-8 sequence towards the end of the buffer). + * @param flags a collection of AV_UTF8_FLAG_* flags + * @return >= 0 in case a sequence was successfully read, a negative + * value in case of invalid sequence + */ +av_warn_unused_result +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, + unsigned int flags); + +/** + * Check if a name is in a list. + * @returns 0 if not found, or the 1 based index where it has been found in the + * list. + */ +int av_match_list(const char *name, const char *list, char separator); + +/** + * See libc sscanf manual for more information. + * Locale-independent sscanf implementation. + */ +#if 0 +int av_sscanf(const char *string, const char *format, ...); +#else +// Chromium: av_sscanf() is ~8kb in implementation and isn't used by any +// methods needed for Chromium; drop to save binary size. +#define av_sscanf sscanf +#endif + +/** + * @} + */ + +#endif /* AVUTIL_AVSTRING_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/avutil.h b/arm/raspi/third_party/ffmpeg/libavutil/avutil.h new file mode 100644 index 00000000..64b68bdb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/avutil.h @@ -0,0 +1,371 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file + * @ingroup lavu + * Convenience header that includes @ref lavu "libavutil"'s core. + */ + +/** + * @mainpage + * + * @section ffmpeg_intro Introduction + * + * This document describes the usage of the different libraries + * provided by FFmpeg. + * + * @li @ref libavc "libavcodec" encoding/decoding library + * @li @ref lavfi "libavfilter" graph-based frame editing library + * @li @ref libavf "libavformat" I/O and muxing/demuxing library + * @li @ref lavd "libavdevice" special devices muxing/demuxing library + * @li @ref lavu "libavutil" common utility library + * @li @ref lswr "libswresample" audio resampling, format conversion and mixing + * @li @ref lpp "libpostproc" post processing library + * @li @ref libsws "libswscale" color conversion and scaling library + * + * @section ffmpeg_versioning Versioning and compatibility + * + * Each of the FFmpeg libraries contains a version.h header, which defines a + * major, minor and micro version number with the + * LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO} macros. The major version + * number is incremented with backward incompatible changes - e.g. removing + * parts of the public API, reordering public struct members, etc. The minor + * version number is incremented for backward compatible API changes or major + * new features - e.g. adding a new public function or a new decoder. The micro + * version number is incremented for smaller changes that a calling program + * might still want to check for - e.g. changing behavior in a previously + * unspecified situation. + * + * FFmpeg guarantees backward API and ABI compatibility for each library as long + * as its major version number is unchanged. This means that no public symbols + * will be removed or renamed. Types and names of the public struct members and + * values of public macros and enums will remain the same (unless they were + * explicitly declared as not part of the public API). Documented behavior will + * not change. + * + * In other words, any correct program that works with a given FFmpeg snapshot + * should work just as well without any changes with any later snapshot with the + * same major versions. This applies to both rebuilding the program against new + * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program + * links against. + * + * However, new public symbols may be added and new members may be appended to + * public structs whose size is not part of public ABI (most public structs in + * FFmpeg). New macros and enum values may be added. Behavior in undocumented + * situations may change slightly (and be documented). All those are accompanied + * by an entry in doc/APIchanges and incrementing either the minor or micro + * version number. + */ + +/** + * @defgroup lavu libavutil + * Common code shared across all FFmpeg libraries. + * + * @note + * libavutil is designed to be modular. In most cases, in order to use the + * functions provided by one component of libavutil you must explicitly include + * the specific header containing that feature. If you are only using + * media-related components, you could simply include libavutil/avutil.h, which + * brings in most of the "core" components. + * + * @{ + * + * @defgroup lavu_crypto Crypto and Hashing + * + * @{ + * @} + * + * @defgroup lavu_math Mathematics + * @{ + * + * @} + * + * @defgroup lavu_string String Manipulation + * + * @{ + * + * @} + * + * @defgroup lavu_mem Memory Management + * + * @{ + * + * @} + * + * @defgroup lavu_data Data Structures + * @{ + * + * @} + * + * @defgroup lavu_video Video related + * + * @{ + * + * @} + * + * @defgroup lavu_audio Audio related + * + * @{ + * + * @} + * + * @defgroup lavu_error Error Codes + * + * @{ + * + * @} + * + * @defgroup lavu_log Logging Facility + * + * @{ + * + * @} + * + * @defgroup lavu_misc Other + * + * @{ + * + * @defgroup preproc_misc Preprocessor String Macros + * + * @{ + * + * @} + * + * @defgroup version_utils Library Version Macros + * + * @{ + * + * @} + */ + + +/** + * @addtogroup lavu_ver + * @{ + */ + +/** + * Return the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +/** + * Return an informative version string. This usually is the actual release + * version number or a git commit description. This string has no fixed format + * and can change any time. It should never be parsed by code. + */ +const char *av_version_info(void); + +/** + * Return the libavutil build-time configuration. + */ +const char *avutil_configuration(void); + +/** + * Return the libavutil license. + */ +const char *avutil_license(void); + +/** + * @} + */ + +/** + * @addtogroup lavu_media Media Type + * @brief Media Type + */ + +enum AVMediaType { + AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse + AVMEDIA_TYPE_NB +}; + +/** + * Return a string describing the media_type enum, NULL if media_type + * is unknown. + */ +const char *av_get_media_type_string(enum AVMediaType media_type); + +/** + * @defgroup lavu_const Constants + * @{ + * + * @defgroup lavu_enc Encoding specific + * + * @note those definition should move to avcodec + * @{ + */ + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< +#include "libavutil/version.h" +#include "libavutil/ffversion.h" +#include "config.h" + +1 VERSIONINFO +FILEVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0 +PRODUCTVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904B0" + { + VALUE "CompanyName", "FFmpeg Project" + VALUE "FileDescription", "FFmpeg utility library" + VALUE "FileVersion", AV_STRINGIFY(LIBAVUTIL_VERSION) + VALUE "InternalName", "libavutil" + VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project" + VALUE "OriginalFilename", "avutil" BUILDSUF "-" AV_STRINGIFY(LIBAVUTIL_VERSION_MAJOR) SLIBSUF + VALUE "ProductName", "FFmpeg" + VALUE "ProductVersion", FFMPEG_VERSION + } + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04B0 + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/base64.c b/arm/raspi/third_party/ffmpeg/libavutil/base64.c new file mode 100644 index 00000000..3e66f4fc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/base64.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief Base64 encode/decode + * @author Ryan Martell (with lots of Michael) + */ + +#include +#include + +#include "base64.h" +#include "error.h" +#include "intreadwrite.h" + +/* ---------------- private code */ +static const uint8_t map2[256] = +{ + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, + + 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, + 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +#define BASE64_DEC_STEP(i) do { \ + bits = map2[in[i]]; \ + if (bits & 0x80) \ + goto out ## i; \ + v = i ? (v << 6) + bits : bits; \ +} while(0) + +int av_base64_decode(uint8_t *out, const char *in_str, int out_size) +{ + uint8_t *dst = out; + uint8_t *end; + // no sign extension + const uint8_t *in = in_str; + unsigned bits = 0xff; + unsigned v; + + if (!out) + goto validity_check; + + end = out + out_size; + while (end - dst > 3) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + // Using AV_WB32 directly confuses compiler + v = av_be2ne32(v << 8); + AV_WN32(dst, v); + dst += 3; + in += 4; + } + if (end - dst) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + *dst++ = v >> 16; + if (end - dst) + *dst++ = v >> 8; + if (end - dst) + *dst++ = v; + in += 4; + } +validity_check: + while (1) { + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + } + +out3: + *dst++ = v >> 10; + v <<= 2; +out2: + *dst++ = v >> 4; +out1: +out0: + return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0; +} + +/***************************************************************************** +* b64_encode: Stolen from VLC's http.c. +* Simplified by Michael. +* Fixed edge cases and made it work from data (vs. strings) by Ryan. +*****************************************************************************/ + +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size) +{ + static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *ret, *dst; + unsigned i_bits = 0; + int i_shift = 0; + int bytes_remaining = in_size; + + if (in_size >= UINT_MAX / 4 || + out_size < AV_BASE64_SIZE(in_size)) + return NULL; + ret = dst = out; + while (bytes_remaining > 3) { + i_bits = AV_RB32(in); + in += 3; bytes_remaining -= 3; + *dst++ = b64[ i_bits>>26 ]; + *dst++ = b64[(i_bits>>20) & 0x3F]; + *dst++ = b64[(i_bits>>14) & 0x3F]; + *dst++ = b64[(i_bits>>8 ) & 0x3F]; + } + i_bits = 0; + while (bytes_remaining) { + i_bits = (i_bits << 8) + *in++; + bytes_remaining--; + i_shift += 8; + } + while (i_shift > 0) { + *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; + i_shift -= 6; + } + while ((dst - ret) & 3) + *dst++ = '='; + *dst = '\0'; + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/base64.h b/arm/raspi/third_party/ffmpeg/libavutil/base64.h new file mode 100644 index 00000000..2954c12d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/base64.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BASE64_H +#define AVUTIL_BASE64_H + +#include + +/** + * @defgroup lavu_base64 Base64 + * @ingroup lavu_crypto + * @{ + */ + +/** + * Decode a base64-encoded string. + * + * @param out buffer for decoded data + * @param in null-terminated input string + * @param out_size size in bytes of the out buffer, must be at + * least 3/4 of the length of in, that is AV_BASE64_DECODE_SIZE(strlen(in)) + * @return number of bytes written, or a negative value in case of + * invalid input + */ +int av_base64_decode(uint8_t *out, const char *in, int out_size); + +/** + * Calculate the output size in bytes needed to decode a base64 string + * with length x to a data buffer. + */ +#define AV_BASE64_DECODE_SIZE(x) ((x) * 3LL / 4) + +/** + * Encode data to base64 and null-terminate. + * + * @param out buffer for encoded data + * @param out_size size in bytes of the out buffer (including the + * null terminator), must be at least AV_BASE64_SIZE(in_size) + * @param in input buffer containing the data to encode + * @param in_size size in bytes of the in buffer + * @return out or NULL in case of error + */ +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); + +/** + * Calculate the output size needed to base64-encode x bytes to a + * null-terminated string. + */ +#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) + + /** + * @} + */ + +#endif /* AVUTIL_BASE64_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/bfin/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/bfin/bswap.h new file mode 100644 index 00000000..363ed40b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/bfin/bswap.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007 Marc Hoffman + * + * 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 + * byte swapping routines + */ + +#ifndef AVUTIL_BFIN_BSWAP_H +#define AVUTIL_BFIN_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + unsigned tmp; + __asm__("%1 = %0 >> 8 (V); \n\t" + "%0 = %0 << 8 (V); \n\t" + "%0 = %0 | %1; \n\t" + "%0 = PACK(%0.L, %0.H); \n\t" + : "+d"(x), "=&d"(tmp)); + return x; +} + +#endif /* AVUTIL_BFIN_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/bfin/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/bfin/timer.h new file mode 100644 index 00000000..644573da --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/bfin/timer.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Marc Hoffman + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BFIN_TIMER_H +#define AVUTIL_BFIN_TIMER_H + +#include + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + union { + struct { + unsigned lo; + unsigned hi; + } p; + unsigned long long c; + } t; + __asm__ volatile ("%0=cycles; %1=cycles2;" : "=d" (t.p.lo), "=d" (t.p.hi)); + return t.c; +} + +#endif /* AVUTIL_BFIN_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/blowfish.c b/arm/raspi/third_party/ffmpeg/libavutil/blowfish.c new file mode 100644 index 00000000..6df60150 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/blowfish.c @@ -0,0 +1,425 @@ +/* + * Blowfish algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * loosely based on Paul Kocher's implementation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "attributes.h" +#include "intreadwrite.h" +#include "mem.h" +#include "blowfish.h" + +static const uint32_t orig_p[AV_BF_ROUNDS + 2] = { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B +}; + +static const uint32_t orig_s[4][256] = { + { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }, + { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }, + { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }, + { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 } +}; + +#define F(Xl, Xr, P) \ + Xr ^=((( ctx->s[0][ Xl >> 24 ] \ + + ctx->s[1][(Xl >> 16) & 0xFF])\ + ^ ctx->s[2][(Xl >> 8) & 0xFF])\ + + ctx->s[3][ Xl & 0xFF])\ + ^ P; + +AVBlowfish *av_blowfish_alloc(void) +{ + return av_mallocz(sizeof(struct AVBlowfish)); +} + +av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len) +{ + uint32_t data, data_l, data_r; + int i, j, k; + + memcpy(ctx->s, orig_s, sizeof(orig_s)); + + j = 0; + for (i = 0; i < AV_BF_ROUNDS + 2; ++i) { + data = 0; + for (k = 0; k < 4; k++) { + data = (data << 8) | key[j]; + if (++j >= key_len) + j = 0; + } + ctx->p[i] = orig_p[i] ^ data; + } + + data_l = data_r = 0; + + for (i = 0; i < AV_BF_ROUNDS + 2; i += 2) { + av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0); + ctx->p[i] = data_l; + ctx->p[i + 1] = data_r; + } + + for (i = 0; i < 4; ++i) { + for (j = 0; j < 256; j += 2) { + av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0); + ctx->s[i][j] = data_l; + ctx->s[i][j + 1] = data_r; + } + } +} + +void av_blowfish_crypt_ecb(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, + int decrypt) +{ + uint32_t Xl, Xr; + int i; + + Xl = *xl; + Xr = *xr; + + if (decrypt) { + Xl ^= ctx->p[AV_BF_ROUNDS + 1]; + for (i = AV_BF_ROUNDS; i > 0; i-=2) { + F(Xl, Xr, ctx->p[i ]); + F(Xr, Xl, ctx->p[i-1]); + } + + Xr ^= ctx->p[0]; + } else { + Xl ^= ctx->p[0]; + for (i = 1; i < AV_BF_ROUNDS+1; i+=2){ + F(Xl, Xr, ctx->p[i ]); + F(Xr, Xl, ctx->p[i+1]); + } + + Xr ^= ctx->p[AV_BF_ROUNDS + 1]; + } + + *xl = Xr; + *xr = Xl; +} + +void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + uint32_t v0, v1; + int i; + + if (decrypt) { + while (count--) { + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); + + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + v0 = AV_RB32(dst); + v1 = AV_RB32(dst + 4); + } else { + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + } + + av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); + + if (iv) + memcpy(iv, dst, 8); + + src += 8; + dst += 8; + } + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/blowfish.h b/arm/raspi/third_party/ffmpeg/libavutil/blowfish.h new file mode 100644 index 00000000..9e289a40 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/blowfish.h @@ -0,0 +1,82 @@ +/* + * Blowfish algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BLOWFISH_H +#define AVUTIL_BLOWFISH_H + +#include + +/** + * @defgroup lavu_blowfish Blowfish + * @ingroup lavu_crypto + * @{ + */ + +#define AV_BF_ROUNDS 16 + +typedef struct AVBlowfish { + uint32_t p[AV_BF_ROUNDS + 2]; + uint32_t s[4][256]; +} AVBlowfish; + +/** + * Allocate an AVBlowfish context. + */ +AVBlowfish *av_blowfish_alloc(void); + +/** + * Initialize an AVBlowfish context. + * + * @param ctx an AVBlowfish context + * @param key a key + * @param key_len length of the key + */ +void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param xl left four bytes halves of input to be encrypted + * @param xr right four bytes halves of input to be encrypted + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, + int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_BLOWFISH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/bprint.c b/arm/raspi/third_party/ffmpeg/libavutil/bprint.c new file mode 100644 index 00000000..5b540ebc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/bprint.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "avstring.h" +#include "bprint.h" +#include "compat/va_copy.h" +#include "error.h" +#include "macros.h" +#include "mem.h" + +#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size)) +#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer) + +static int av_bprint_alloc(AVBPrint *buf, unsigned room) +{ + char *old_str, *new_str; + unsigned min_size, new_size; + + if (buf->size == buf->size_max) + return AVERROR(EIO); + if (!av_bprint_is_complete(buf)) + return AVERROR_INVALIDDATA; /* it is already truncated anyway */ + min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room); + new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2; + if (new_size < min_size) + new_size = FFMIN(buf->size_max, min_size); + old_str = av_bprint_is_allocated(buf) ? buf->str : NULL; + new_str = av_realloc(old_str, new_size); + if (!new_str) + return AVERROR(ENOMEM); + if (!old_str) + memcpy(new_str, buf->str, buf->len + 1); + buf->str = new_str; + buf->size = new_size; + return 0; +} + +static void av_bprint_grow(AVBPrint *buf, unsigned extra_len) +{ + /* arbitrary margin to avoid small overflows */ + extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len); + buf->len += extra_len; + if (buf->size) + buf->str[FFMIN(buf->len, buf->size - 1)] = 0; +} + +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max) +{ + unsigned size_auto = (char *)buf + sizeof(*buf) - + buf->reserved_internal_buffer; + + if (size_max == 1) + size_max = size_auto; + buf->str = buf->reserved_internal_buffer; + buf->len = 0; + buf->size = FFMIN(size_auto, size_max); + buf->size_max = size_max; + *buf->str = 0; + if (size_init > buf->size) + av_bprint_alloc(buf, size_init - 1); +} + +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size) +{ + buf->str = buffer; + buf->len = 0; + buf->size = size; + buf->size_max = size; + *buf->str = 0; +} + +void av_bprintf(AVBPrint *buf, const char *fmt, ...) +{ + unsigned room; + char *dst; + va_list vl; + int extra_len; + + while (1) { + room = av_bprint_room(buf); + dst = room ? buf->str + buf->len : NULL; + va_start(vl, fmt); + extra_len = vsnprintf(dst, room, fmt, vl); + va_end(vl); + if (extra_len <= 0) + return; + if (extra_len < room) + break; + if (av_bprint_alloc(buf, extra_len)) + break; + } + av_bprint_grow(buf, extra_len); +} + +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg) +{ + unsigned room; + char *dst; + int extra_len; + va_list vl; + + while (1) { + room = av_bprint_room(buf); + dst = room ? buf->str + buf->len : NULL; + va_copy(vl, vl_arg); + extra_len = vsnprintf(dst, room, fmt, vl); + va_end(vl); + if (extra_len <= 0) + return; + if (extra_len < room) + break; + if (av_bprint_alloc(buf, extra_len)) + break; + } + av_bprint_grow(buf, extra_len); +} + +void av_bprint_chars(AVBPrint *buf, char c, unsigned n) +{ + unsigned room, real_n; + + while (1) { + room = av_bprint_room(buf); + if (n < room) + break; + if (av_bprint_alloc(buf, n)) + break; + } + if (room) { + real_n = FFMIN(n, room - 1); + memset(buf->str + buf->len, c, real_n); + } + av_bprint_grow(buf, n); +} + +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size) +{ + unsigned room, real_n; + + while (1) { + room = av_bprint_room(buf); + if (size < room) + break; + if (av_bprint_alloc(buf, size)) + break; + } + if (room) { + real_n = FFMIN(size, room - 1); + memcpy(buf->str + buf->len, data, real_n); + } + av_bprint_grow(buf, size); +} + +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm) +{ + unsigned room; + size_t l; + + if (!*fmt) + return; + while (1) { + room = av_bprint_room(buf); + if (room && (l = strftime(buf->str + buf->len, room, fmt, tm))) + break; + /* strftime does not tell us how much room it would need: let us + retry with twice as much until the buffer is large enough */ + room = !room ? strlen(fmt) + 1 : + room <= INT_MAX / 2 ? room * 2 : INT_MAX; + if (av_bprint_alloc(buf, room)) { + /* impossible to grow, try to manage something useful anyway */ + room = av_bprint_room(buf); + if (room < 1024) { + /* if strftime fails because the buffer has (almost) reached + its maximum size, let us try in a local buffer; 1k should + be enough to format any real date+time string */ + char buf2[1024]; + if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) { + av_bprintf(buf, "%s", buf2); + return; + } + } + if (room) { + /* if anything else failed and the buffer is not already + truncated, let us add a stock string and force truncation */ + static const char txt[] = "[truncated strftime output]"; + memset(buf->str + buf->len, '!', room); + memcpy(buf->str + buf->len, txt, FFMIN(sizeof(txt) - 1, room)); + av_bprint_grow(buf, room); /* force truncation */ + } + return; + } + } + av_bprint_grow(buf, l); +} + +void av_bprint_get_buffer(AVBPrint *buf, unsigned size, + unsigned char **mem, unsigned *actual_size) +{ + if (size > av_bprint_room(buf)) + av_bprint_alloc(buf, size); + *actual_size = av_bprint_room(buf); + *mem = *actual_size ? buf->str + buf->len : NULL; +} + +void av_bprint_clear(AVBPrint *buf) +{ + if (buf->len) { + *buf->str = 0; + buf->len = 0; + } +} + +int av_bprint_finalize(AVBPrint *buf, char **ret_str) +{ + unsigned real_size = FFMIN(buf->len + 1, buf->size); + char *str; + int ret = 0; + + if (ret_str) { + if (av_bprint_is_allocated(buf)) { + str = av_realloc(buf->str, real_size); + if (!str) + str = buf->str; + buf->str = NULL; + } else { + str = av_memdup(buf->str, real_size); + if (!str) + ret = AVERROR(ENOMEM); + } + *ret_str = str; + } else { + if (av_bprint_is_allocated(buf)) + av_freep(&buf->str); + } + buf->size = real_size; + return ret; +} + +#define WHITESPACES " \n\t\r" + +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags) +{ + const char *src0 = src; + + if (mode == AV_ESCAPE_MODE_AUTO) + mode = AV_ESCAPE_MODE_BACKSLASH; /* TODO: implement a heuristic */ + + switch (mode) { + case AV_ESCAPE_MODE_QUOTE: + /* enclose the string between '' */ + av_bprint_chars(dstbuf, '\'', 1); + for (; *src; src++) { + if (*src == '\'') + av_bprintf(dstbuf, "'\\''"); + else + av_bprint_chars(dstbuf, *src, 1); + } + av_bprint_chars(dstbuf, '\'', 1); + break; + + case AV_ESCAPE_MODE_XML: + /* escape XML non-markup character data as per 2.4 by default: */ + /* [^<&]* - ([^<&]* ']]>' [^<&]*) */ + + /* additionally, given one of the AV_ESCAPE_FLAG_XML_* flags, */ + /* escape those specific characters as required. */ + for (; *src; src++) { + switch (*src) { + case '&' : av_bprintf(dstbuf, "%s", "&"); break; + case '<' : av_bprintf(dstbuf, "%s", "<"); break; + case '>' : av_bprintf(dstbuf, "%s", ">"); break; + case '\'': + if (!(flags & AV_ESCAPE_FLAG_XML_SINGLE_QUOTES)) + goto XML_DEFAULT_HANDLING; + + av_bprintf(dstbuf, "%s", "'"); + break; + case '"' : + if (!(flags & AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES)) + goto XML_DEFAULT_HANDLING; + + av_bprintf(dstbuf, "%s", """); + break; +XML_DEFAULT_HANDLING: + default: av_bprint_chars(dstbuf, *src, 1); + } + } + break; + + /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */ + default: + /* \-escape characters */ + for (; *src; src++) { + int is_first_last = src == src0 || !*(src+1); + int is_ws = !!strchr(WHITESPACES, *src); + int is_strictly_special = special_chars && strchr(special_chars, *src); + int is_special = + is_strictly_special || strchr("'\\", *src) || + (is_ws && (flags & AV_ESCAPE_FLAG_WHITESPACE)); + + if (is_strictly_special || + (!(flags & AV_ESCAPE_FLAG_STRICT) && + (is_special || (is_ws && is_first_last)))) + av_bprint_chars(dstbuf, '\\', 1); + av_bprint_chars(dstbuf, *src, 1); + } + break; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/bprint.h b/arm/raspi/third_party/ffmpeg/libavutil/bprint.h new file mode 100644 index 00000000..f27d30f7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/bprint.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * 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 + * @ingroup lavu_avbprint + * AVBPrint public header + */ + +#ifndef AVUTIL_BPRINT_H +#define AVUTIL_BPRINT_H + +#include + +#include "attributes.h" +#include "avstring.h" + +/** + * @defgroup lavu_avbprint AVBPrint + * @ingroup lavu_data + * + * A buffer to print data progressively + * @{ + */ + +/** + * Define a structure with extra padding to a fixed size + * This helps ensuring binary compatibility with future versions. + */ + +#define FF_PAD_STRUCTURE(name, size, ...) \ +struct ff_pad_helper_##name { __VA_ARGS__ }; \ +typedef struct name { \ + __VA_ARGS__ \ + char reserved_padding[size - sizeof(struct ff_pad_helper_##name)]; \ +} name; + +/** + * Buffer to print data progressively + * + * The string buffer grows as necessary and is always 0-terminated. + * The content of the string is never accessed, and thus is + * encoding-agnostic and can even hold binary data. + * + * Small buffers are kept in the structure itself, and thus require no + * memory allocation at all (unless the contents of the buffer is needed + * after the structure goes out of scope). This is almost as lightweight as + * declaring a local `char buf[512]`. + * + * The length of the string can go beyond the allocated size: the buffer is + * then truncated, but the functions still keep account of the actual total + * length. + * + * In other words, AVBPrint.len can be greater than AVBPrint.size and records + * the total length of what would have been to the buffer if there had been + * enough memory. + * + * Append operations do not need to be tested for failure: if a memory + * allocation fails, data stop being appended to the buffer, but the length + * is still updated. This situation can be tested with + * av_bprint_is_complete(). + * + * The AVBPrint.size_max field determines several possible behaviours: + * - `size_max = -1` (= `UINT_MAX`) or any large value will let the buffer be + * reallocated as necessary, with an amortized linear cost. + * - `size_max = 0` prevents writing anything to the buffer: only the total + * length is computed. The write operations can then possibly be repeated in + * a buffer with exactly the necessary size + * (using `size_init = size_max = len + 1`). + * - `size_max = 1` is automatically replaced by the exact size available in the + * structure itself, thus ensuring no dynamic memory allocation. The + * internal buffer is large enough to hold a reasonable paragraph of text, + * such as the current paragraph. + */ + +FF_PAD_STRUCTURE(AVBPrint, 1024, + char *str; /**< string so far */ + unsigned len; /**< length so far */ + unsigned size; /**< allocated memory */ + unsigned size_max; /**< maximum allocated memory */ + char reserved_internal_buffer[1]; +) + +/** + * @name Max size special values + * Convenience macros for special values for av_bprint_init() size_max + * parameter. + * @{ + */ + +/** + * Buffer will be reallocated as necessary, with an amortized linear cost. + */ +#define AV_BPRINT_SIZE_UNLIMITED ((unsigned)-1) +/** + * Use the exact size available in the AVBPrint structure itself. + * + * Thus ensuring no dynamic memory allocation. The internal buffer is large + * enough to hold a reasonable paragraph of text, such as the current paragraph. + */ +#define AV_BPRINT_SIZE_AUTOMATIC 1 +/** + * Do not write anything to the buffer, only calculate the total length. + * + * The write operations can then possibly be repeated in a buffer with + * exactly the necessary size (using `size_init = size_max = AVBPrint.len + 1`). + */ +#define AV_BPRINT_SIZE_COUNT_ONLY 0 +/** @} */ + +/** + * Init a print buffer. + * + * @param buf buffer to init + * @param size_init initial size (including the final 0) + * @param size_max maximum size; + * - `0` means do not write anything, just count the length + * - `1` is replaced by the maximum value for automatic storage + * any large value means that the internal buffer will be + * reallocated as needed up to that limit + * - `-1` is converted to `UINT_MAX`, the largest limit possible. + * Check also `AV_BPRINT_SIZE_*` macros. + */ +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max); + +/** + * Init a print buffer using a pre-existing buffer. + * + * The buffer will not be reallocated. + * + * @param buf buffer structure to init + * @param buffer byte buffer to use for the string data + * @param size size of buffer + */ +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size); + +/** + * Append a formatted string to a print buffer. + */ +void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3); + +/** + * Append a formatted string to a print buffer. + */ +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg); + +/** + * Append char c n times to a print buffer. + */ +void av_bprint_chars(AVBPrint *buf, char c, unsigned n); + +/** + * Append data to a print buffer. + * + * param buf bprint buffer to use + * param data pointer to data + * param size size of data + */ +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size); + +struct tm; +/** + * Append a formatted date and time to a print buffer. + * + * param buf bprint buffer to use + * param fmt date and time format string, see strftime() + * param tm broken-down time structure to translate + * + * @note due to poor design of the standard strftime function, it may + * produce poor results if the format string expands to a very long text and + * the bprint buffer is near the limit stated by the size_max option. + */ +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm); + +/** + * Allocate bytes in the buffer for external use. + * + * @param[in] buf buffer structure + * @param[in] size required size + * @param[out] mem pointer to the memory area + * @param[out] actual_size size of the memory area after allocation; + * can be larger or smaller than size + */ +void av_bprint_get_buffer(AVBPrint *buf, unsigned size, + unsigned char **mem, unsigned *actual_size); + +/** + * Reset the string to "" but keep internal allocated data. + */ +void av_bprint_clear(AVBPrint *buf); + +/** + * Test if the print buffer is complete (not truncated). + * + * It may have been truncated due to a memory allocation failure + * or the size_max limit (compare size and size_max if necessary). + */ +static inline int av_bprint_is_complete(const AVBPrint *buf) +{ + return buf->len < buf->size; +} + +/** + * Finalize a print buffer. + * + * The print buffer can no longer be used afterwards, + * but the len and size fields are still valid. + * + * @arg[out] ret_str if not NULL, used to return a permanent copy of the + * buffer contents, or NULL if memory allocation fails; + * if NULL, the buffer is discarded and freed + * @return 0 for success or error code (probably AVERROR(ENOMEM)) + */ +int av_bprint_finalize(AVBPrint *buf, char **ret_str); + +/** + * Escape the content in src and append it to dstbuf. + * + * @param dstbuf already inited destination bprint buffer + * @param src string containing the text to escape + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_* macros + */ +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +/** @} */ + +#endif /* AVUTIL_BPRINT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/bswap.h new file mode 100644 index 00000000..4840ab43 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/bswap.h @@ -0,0 +1,111 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * byte swapping routines + */ + +#ifndef AVUTIL_BSWAP_H +#define AVUTIL_BSWAP_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_AARCH64 +# include "aarch64/bswap.h" +#elif ARCH_ARM +# include "arm/bswap.h" +#elif ARCH_AVR32 +# include "avr32/bswap.h" +#elif ARCH_RISCV +# include "riscv/bswap.h" +#elif ARCH_SH4 +# include "sh4/bswap.h" +#elif ARCH_X86 +# include "x86/bswap.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +#define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) +#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16)) +#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32)) + +#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x) + +#ifndef av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + x= (x>>8) | (x<<8); + return x; +} +#endif + +#ifndef av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return AV_BSWAP32C(x); +} +#endif + +#ifndef av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32); +} +#endif + +// be2ne ... big-endian to native-endian +// le2ne ... little-endian to native-endian + +#if AV_HAVE_BIGENDIAN +#define av_be2ne16(x) (x) +#define av_be2ne32(x) (x) +#define av_be2ne64(x) (x) +#define av_le2ne16(x) av_bswap16(x) +#define av_le2ne32(x) av_bswap32(x) +#define av_le2ne64(x) av_bswap64(x) +#define AV_BE2NEC(s, x) (x) +#define AV_LE2NEC(s, x) AV_BSWAPC(s, x) +#else +#define av_be2ne16(x) av_bswap16(x) +#define av_be2ne32(x) av_bswap32(x) +#define av_be2ne64(x) av_bswap64(x) +#define av_le2ne16(x) (x) +#define av_le2ne32(x) (x) +#define av_le2ne64(x) (x) +#define AV_BE2NEC(s, x) AV_BSWAPC(s, x) +#define AV_LE2NEC(s, x) (x) +#endif + +#define AV_BE2NE16C(x) AV_BE2NEC(16, x) +#define AV_BE2NE32C(x) AV_BE2NEC(32, x) +#define AV_BE2NE64C(x) AV_BE2NEC(64, x) +#define AV_LE2NE16C(x) AV_LE2NEC(16, x) +#define AV_LE2NE32C(x) AV_LE2NEC(32, x) +#define AV_LE2NE64C(x) AV_LE2NEC(64, x) + +#endif /* AVUTIL_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/buffer.c b/arm/raspi/third_party/ffmpeg/libavutil/buffer.c new file mode 100644 index 00000000..e4562a79 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/buffer.c @@ -0,0 +1,416 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "avassert.h" +#include "buffer_internal.h" +#include "common.h" +#include "mem.h" +#include "thread.h" + +static AVBufferRef *buffer_create(AVBuffer *buf, uint8_t *data, size_t size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags) +{ + AVBufferRef *ref = NULL; + + buf->data = data; + buf->size = size; + buf->free = free ? free : av_buffer_default_free; + buf->opaque = opaque; + + atomic_init(&buf->refcount, 1); + + buf->flags = flags; + + ref = av_mallocz(sizeof(*ref)); + if (!ref) + return NULL; + + ref->buffer = buf; + ref->data = data; + ref->size = size; + + return ref; +} + +AVBufferRef *av_buffer_create(uint8_t *data, size_t size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags) +{ + AVBufferRef *ret; + AVBuffer *buf = av_mallocz(sizeof(*buf)); + if (!buf) + return NULL; + + ret = buffer_create(buf, data, size, free, opaque, flags); + if (!ret) { + av_free(buf); + return NULL; + } + return ret; +} + +void av_buffer_default_free(void *opaque, uint8_t *data) +{ + av_free(data); +} + +AVBufferRef *av_buffer_alloc(size_t size) +{ + AVBufferRef *ret = NULL; + uint8_t *data = NULL; + + data = av_malloc(size); + if (!data) + return NULL; + + ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); + if (!ret) + av_freep(&data); + + return ret; +} + +AVBufferRef *av_buffer_allocz(size_t size) +{ + AVBufferRef *ret = av_buffer_alloc(size); + if (!ret) + return NULL; + + memset(ret->data, 0, size); + return ret; +} + +AVBufferRef *av_buffer_ref(const AVBufferRef *buf) +{ + AVBufferRef *ret = av_mallocz(sizeof(*ret)); + + if (!ret) + return NULL; + + *ret = *buf; + + atomic_fetch_add_explicit(&buf->buffer->refcount, 1, memory_order_relaxed); + + return ret; +} + +static void buffer_replace(AVBufferRef **dst, AVBufferRef **src) +{ + AVBuffer *b; + + b = (*dst)->buffer; + + if (src) { + **dst = **src; + av_freep(src); + } else + av_freep(dst); + + if (atomic_fetch_sub_explicit(&b->refcount, 1, memory_order_acq_rel) == 1) { + /* b->free below might already free the structure containing *b, + * so we have to read the flag now to avoid use-after-free. */ + int free_avbuffer = !(b->flags_internal & BUFFER_FLAG_NO_FREE); + b->free(b->opaque, b->data); + if (free_avbuffer) + av_free(b); + } +} + +void av_buffer_unref(AVBufferRef **buf) +{ + if (!buf || !*buf) + return; + + buffer_replace(buf, NULL); +} + +int av_buffer_is_writable(const AVBufferRef *buf) +{ + if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY) + return 0; + + return atomic_load(&buf->buffer->refcount) == 1; +} + +void *av_buffer_get_opaque(const AVBufferRef *buf) +{ + return buf->buffer->opaque; +} + +int av_buffer_get_ref_count(const AVBufferRef *buf) +{ + return atomic_load(&buf->buffer->refcount); +} + +int av_buffer_make_writable(AVBufferRef **pbuf) +{ + AVBufferRef *newbuf, *buf = *pbuf; + + if (av_buffer_is_writable(buf)) + return 0; + + newbuf = av_buffer_alloc(buf->size); + if (!newbuf) + return AVERROR(ENOMEM); + + memcpy(newbuf->data, buf->data, buf->size); + + buffer_replace(pbuf, &newbuf); + + return 0; +} + +int av_buffer_realloc(AVBufferRef **pbuf, size_t size) +{ + AVBufferRef *buf = *pbuf; + uint8_t *tmp; + int ret; + + if (!buf) { + /* allocate a new buffer with av_realloc(), so it will be reallocatable + * later */ + uint8_t *data = av_realloc(NULL, size); + if (!data) + return AVERROR(ENOMEM); + + buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); + if (!buf) { + av_freep(&data); + return AVERROR(ENOMEM); + } + + buf->buffer->flags_internal |= BUFFER_FLAG_REALLOCATABLE; + *pbuf = buf; + + return 0; + } else if (buf->size == size) + return 0; + + if (!(buf->buffer->flags_internal & BUFFER_FLAG_REALLOCATABLE) || + !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { + /* cannot realloc, allocate a new reallocable buffer and copy data */ + AVBufferRef *new = NULL; + + ret = av_buffer_realloc(&new, size); + if (ret < 0) + return ret; + + memcpy(new->data, buf->data, FFMIN(size, buf->size)); + + buffer_replace(pbuf, &new); + return 0; + } + + tmp = av_realloc(buf->buffer->data, size); + if (!tmp) + return AVERROR(ENOMEM); + + buf->buffer->data = buf->data = tmp; + buf->buffer->size = buf->size = size; + return 0; +} + +int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src) +{ + AVBufferRef *dst = *pdst; + AVBufferRef *tmp; + + if (!src) { + av_buffer_unref(pdst); + return 0; + } + + if (dst && dst->buffer == src->buffer) { + /* make sure the data pointers match */ + dst->data = src->data; + dst->size = src->size; + return 0; + } + + tmp = av_buffer_ref(src); + if (!tmp) + return AVERROR(ENOMEM); + + av_buffer_unref(pdst); + *pdst = tmp; + return 0; +} + +AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, size_t size), + void (*pool_free)(void *opaque)) +{ + AVBufferPool *pool = av_mallocz(sizeof(*pool)); + if (!pool) + return NULL; + + ff_mutex_init(&pool->mutex, NULL); + + pool->size = size; + pool->opaque = opaque; + pool->alloc2 = alloc; + pool->alloc = av_buffer_alloc; // fallback + pool->pool_free = pool_free; + + atomic_init(&pool->refcount, 1); + + return pool; +} + +AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)) +{ + AVBufferPool *pool = av_mallocz(sizeof(*pool)); + if (!pool) + return NULL; + + ff_mutex_init(&pool->mutex, NULL); + + pool->size = size; + pool->alloc = alloc ? alloc : av_buffer_alloc; + + atomic_init(&pool->refcount, 1); + + return pool; +} + +static void buffer_pool_flush(AVBufferPool *pool) +{ + while (pool->pool) { + BufferPoolEntry *buf = pool->pool; + pool->pool = buf->next; + + buf->free(buf->opaque, buf->data); + av_freep(&buf); + } +} + +/* + * This function gets called when the pool has been uninited and + * all the buffers returned to it. + */ +static void buffer_pool_free(AVBufferPool *pool) +{ + buffer_pool_flush(pool); + ff_mutex_destroy(&pool->mutex); + + if (pool->pool_free) + pool->pool_free(pool->opaque); + + av_freep(&pool); +} + +void av_buffer_pool_uninit(AVBufferPool **ppool) +{ + AVBufferPool *pool; + + if (!ppool || !*ppool) + return; + pool = *ppool; + *ppool = NULL; + + ff_mutex_lock(&pool->mutex); + buffer_pool_flush(pool); + ff_mutex_unlock(&pool->mutex); + + if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) + buffer_pool_free(pool); +} + +static void pool_release_buffer(void *opaque, uint8_t *data) +{ + BufferPoolEntry *buf = opaque; + AVBufferPool *pool = buf->pool; + + ff_mutex_lock(&pool->mutex); + buf->next = pool->pool; + pool->pool = buf; + ff_mutex_unlock(&pool->mutex); + + if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1) + buffer_pool_free(pool); +} + +/* allocate a new buffer and override its free() callback so that + * it is returned to the pool on free */ +static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) +{ + BufferPoolEntry *buf; + AVBufferRef *ret; + + av_assert0(pool->alloc || pool->alloc2); + + ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) : + pool->alloc(pool->size); + if (!ret) + return NULL; + + buf = av_mallocz(sizeof(*buf)); + if (!buf) { + av_buffer_unref(&ret); + return NULL; + } + + buf->data = ret->buffer->data; + buf->opaque = ret->buffer->opaque; + buf->free = ret->buffer->free; + buf->pool = pool; + + ret->buffer->opaque = buf; + ret->buffer->free = pool_release_buffer; + + return ret; +} + +AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) +{ + AVBufferRef *ret; + BufferPoolEntry *buf; + + ff_mutex_lock(&pool->mutex); + buf = pool->pool; + if (buf) { + memset(&buf->buffer, 0, sizeof(buf->buffer)); + ret = buffer_create(&buf->buffer, buf->data, pool->size, + pool_release_buffer, buf, 0); + if (ret) { + pool->pool = buf->next; + buf->next = NULL; + buf->buffer.flags_internal |= BUFFER_FLAG_NO_FREE; + } + } else { + ret = pool_alloc_buffer(pool); + } + ff_mutex_unlock(&pool->mutex); + + if (ret) + atomic_fetch_add_explicit(&pool->refcount, 1, memory_order_relaxed); + + return ret; +} + +void *av_buffer_pool_buffer_get_opaque(const AVBufferRef *ref) +{ + BufferPoolEntry *buf = ref->buffer->opaque; + av_assert0(buf); + return buf->opaque; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/buffer.h b/arm/raspi/third_party/ffmpeg/libavutil/buffer.h new file mode 100644 index 00000000..e1ef5b7f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/buffer.h @@ -0,0 +1,322 @@ +/* + * 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 + * @ingroup lavu_buffer + * refcounted data buffer API + */ + +#ifndef AVUTIL_BUFFER_H +#define AVUTIL_BUFFER_H + +#include +#include + +/** + * @defgroup lavu_buffer AVBuffer + * @ingroup lavu_data + * + * @{ + * AVBuffer is an API for reference-counted data buffers. + * + * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer + * represents the data buffer itself; it is opaque and not meant to be accessed + * by the caller directly, but only through AVBufferRef. However, the caller may + * e.g. compare two AVBuffer pointers to check whether two different references + * are describing the same data buffer. AVBufferRef represents a single + * reference to an AVBuffer and it is the object that may be manipulated by the + * caller directly. + * + * There are two functions provided for creating a new AVBuffer with a single + * reference -- av_buffer_alloc() to just allocate a new buffer, and + * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing + * reference, additional references may be created with av_buffer_ref(). + * Use av_buffer_unref() to free a reference (this will automatically free the + * data once all the references are freed). + * + * The convention throughout this API and the rest of FFmpeg is such that the + * buffer is considered writable if there exists only one reference to it (and + * it has not been marked as read-only). The av_buffer_is_writable() function is + * provided to check whether this is true and av_buffer_make_writable() will + * automatically create a new writable buffer when necessary. + * Of course nothing prevents the calling code from violating this convention, + * however that is safe only when all the existing references are under its + * control. + * + * @note Referencing and unreferencing the buffers is thread-safe and thus + * may be done from multiple threads simultaneously without any need for + * additional locking. + * + * @note Two different references to the same buffer can point to different + * parts of the buffer (i.e. their AVBufferRef.data will not be equal). + */ + +/** + * A reference counted buffer type. It is opaque and is meant to be used through + * references (AVBufferRef). + */ +typedef struct AVBuffer AVBuffer; + +/** + * A reference to a data buffer. + * + * The size of this struct is not a part of the public ABI and it is not meant + * to be allocated directly. + */ +typedef struct AVBufferRef { + AVBuffer *buffer; + + /** + * The data buffer. It is considered writable if and only if + * this is the only reference to the buffer, in which case + * av_buffer_is_writable() returns 1. + */ + uint8_t *data; + /** + * Size of data in bytes. + */ + size_t size; +} AVBufferRef; + +/** + * Allocate an AVBuffer of the given size using av_malloc(). + * + * @return an AVBufferRef of given size or NULL when out of memory + */ +AVBufferRef *av_buffer_alloc(size_t size); + +/** + * Same as av_buffer_alloc(), except the returned buffer will be initialized + * to zero. + */ +AVBufferRef *av_buffer_allocz(size_t size); + +/** + * Always treat the buffer as read-only, even when it has only one + * reference. + */ +#define AV_BUFFER_FLAG_READONLY (1 << 0) + +/** + * Create an AVBuffer from an existing array. + * + * If this function is successful, data is owned by the AVBuffer. The caller may + * only access data through the returned AVBufferRef and references derived from + * it. + * If this function fails, data is left untouched. + * @param data data array + * @param size size of data in bytes + * @param free a callback for freeing this buffer's data + * @param opaque parameter to be got for processing or passed to free + * @param flags a combination of AV_BUFFER_FLAG_* + * + * @return an AVBufferRef referring to data on success, NULL on failure. + */ +AVBufferRef *av_buffer_create(uint8_t *data, size_t size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags); + +/** + * Default free callback, which calls av_free() on the buffer data. + * This function is meant to be passed to av_buffer_create(), not called + * directly. + */ +void av_buffer_default_free(void *opaque, uint8_t *data); + +/** + * Create a new reference to an AVBuffer. + * + * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on + * failure. + */ +AVBufferRef *av_buffer_ref(const AVBufferRef *buf); + +/** + * Free a given reference and automatically free the buffer if there are no more + * references to it. + * + * @param buf the reference to be freed. The pointer is set to NULL on return. + */ +void av_buffer_unref(AVBufferRef **buf); + +/** + * @return 1 if the caller may write to the data referred to by buf (which is + * true if and only if buf is the only reference to the underlying AVBuffer). + * Return 0 otherwise. + * A positive answer is valid until av_buffer_ref() is called on buf. + */ +int av_buffer_is_writable(const AVBufferRef *buf); + +/** + * @return the opaque parameter set by av_buffer_create. + */ +void *av_buffer_get_opaque(const AVBufferRef *buf); + +int av_buffer_get_ref_count(const AVBufferRef *buf); + +/** + * Create a writable reference from a given buffer reference, avoiding data copy + * if possible. + * + * @param buf buffer reference to make writable. On success, buf is either left + * untouched, or it is unreferenced and a new writable AVBufferRef is + * written in its place. On failure, buf is left untouched. + * @return 0 on success, a negative AVERROR on failure. + */ +int av_buffer_make_writable(AVBufferRef **buf); + +/** + * Reallocate a given buffer. + * + * @param buf a buffer reference to reallocate. On success, buf will be + * unreferenced and a new reference with the required size will be + * written in its place. On failure buf will be left untouched. *buf + * may be NULL, then a new buffer is allocated. + * @param size required new buffer size. + * @return 0 on success, a negative AVERROR on failure. + * + * @note the buffer is actually reallocated with av_realloc() only if it was + * initially allocated through av_buffer_realloc(NULL) and there is only one + * reference to it (i.e. the one passed to this function). In all other cases + * a new buffer is allocated and the data is copied. + */ +int av_buffer_realloc(AVBufferRef **buf, size_t size); + +/** + * Ensure dst refers to the same data as src. + * + * When *dst is already equivalent to src, do nothing. Otherwise unreference dst + * and replace it with a new reference to src. + * + * @param dst Pointer to either a valid buffer reference or NULL. On success, + * this will point to a buffer reference equivalent to src. On + * failure, dst will be left untouched. + * @param src A buffer reference to replace dst with. May be NULL, then this + * function is equivalent to av_buffer_unref(dst). + * @return 0 on success + * AVERROR(ENOMEM) on memory allocation failure. + */ +int av_buffer_replace(AVBufferRef **dst, const AVBufferRef *src); + +/** + * @} + */ + +/** + * @defgroup lavu_bufferpool AVBufferPool + * @ingroup lavu_data + * + * @{ + * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers. + * + * Frequently allocating and freeing large buffers may be slow. AVBufferPool is + * meant to solve this in cases when the caller needs a set of buffers of the + * same size (the most obvious use case being buffers for raw video or audio + * frames). + * + * At the beginning, the user must call av_buffer_pool_init() to create the + * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to + * get a reference to a new buffer, similar to av_buffer_alloc(). This new + * reference works in all aspects the same way as the one created by + * av_buffer_alloc(). However, when the last reference to this buffer is + * unreferenced, it is returned to the pool instead of being freed and will be + * reused for subsequent av_buffer_pool_get() calls. + * + * When the caller is done with the pool and no longer needs to allocate any new + * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable. + * Once all the buffers are released, it will automatically be freed. + * + * Allocating and releasing buffers with this API is thread-safe as long as + * either the default alloc callback is used, or the user-supplied one is + * thread-safe. + */ + +/** + * The buffer pool. This structure is opaque and not meant to be accessed + * directly. It is allocated with av_buffer_pool_init() and freed with + * av_buffer_pool_uninit(). + */ +typedef struct AVBufferPool AVBufferPool; + +/** + * Allocate and initialize a buffer pool. + * + * @param size size of each buffer in this pool + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. May be NULL, then the default allocator will be used + * (av_buffer_alloc()). + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)); + +/** + * Allocate and initialize a buffer pool with a more complex allocator. + * + * @param size size of each buffer in this pool + * @param opaque arbitrary user data used by the allocator + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. May be NULL, then the default allocator will be + * used (av_buffer_alloc()). + * @param pool_free a function that will be called immediately before the pool + * is freed. I.e. after av_buffer_pool_uninit() is called + * by the caller and all the frames are returned to the pool + * and freed. It is intended to uninitialize the user opaque + * data. May be NULL. + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, size_t size), + void (*pool_free)(void *opaque)); + +/** + * Mark the pool as being available for freeing. It will actually be freed only + * once all the allocated buffers associated with the pool are released. Thus it + * is safe to call this function while some of the allocated buffers are still + * in use. + * + * @param pool pointer to the pool to be freed. It will be set to NULL. + */ +void av_buffer_pool_uninit(AVBufferPool **pool); + +/** + * Allocate a new AVBuffer, reusing an old buffer from the pool when available. + * This function may be called simultaneously from multiple threads. + * + * @return a reference to the new buffer on success, NULL on error. + */ +AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); + +/** + * Query the original opaque parameter of an allocated buffer in the pool. + * + * @param ref a buffer reference to a buffer returned by av_buffer_pool_get. + * @return the opaque parameter set by the buffer allocator function of the + * buffer pool. + * + * @note the opaque parameter of ref is used by the buffer pool implementation, + * therefore you have to use this function to access the original opaque + * parameter of an allocated buffer. + */ +void *av_buffer_pool_buffer_get_opaque(const AVBufferRef *ref); + +/** + * @} + */ + +#endif /* AVUTIL_BUFFER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/buffer_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/buffer_internal.h new file mode 100644 index 00000000..adb916aa --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/buffer_internal.h @@ -0,0 +1,110 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BUFFER_INTERNAL_H +#define AVUTIL_BUFFER_INTERNAL_H + +#include +#include + +#include "buffer.h" +#include "thread.h" + +/** + * The buffer was av_realloc()ed, so it is reallocatable. + */ +#define BUFFER_FLAG_REALLOCATABLE (1 << 0) +/** + * The AVBuffer structure is part of a larger structure + * and should not be freed. + */ +#define BUFFER_FLAG_NO_FREE (1 << 1) + +struct AVBuffer { + uint8_t *data; /**< data described by this buffer */ + size_t size; /**< size of data in bytes */ + + /** + * number of existing AVBufferRef instances referring to this buffer + */ + atomic_uint refcount; + + /** + * a callback for freeing the data + */ + void (*free)(void *opaque, uint8_t *data); + + /** + * an opaque pointer, to be used by the freeing callback + */ + void *opaque; + + /** + * A combination of AV_BUFFER_FLAG_* + */ + int flags; + + /** + * A combination of BUFFER_FLAG_* + */ + int flags_internal; +}; + +typedef struct BufferPoolEntry { + uint8_t *data; + + /* + * Backups of the original opaque/free of the AVBuffer corresponding to + * data. They will be used to free the buffer when the pool is freed. + */ + void *opaque; + void (*free)(void *opaque, uint8_t *data); + + AVBufferPool *pool; + struct BufferPoolEntry *next; + + /* + * An AVBuffer structure to (re)use as AVBuffer for subsequent uses + * of this BufferPoolEntry. + */ + AVBuffer buffer; +} BufferPoolEntry; + +struct AVBufferPool { + AVMutex mutex; + BufferPoolEntry *pool; + + /* + * This is used to track when the pool is to be freed. + * The pointer to the pool itself held by the caller is considered to + * be one reference. Each buffer requested by the caller increases refcount + * by one, returning the buffer to the pool decreases it by one. + * refcount reaches zero when the buffer has been uninited AND all the + * buffers have been released, then it's safe to free the pool and all + * the buffers in it. + */ + atomic_uint refcount; + + size_t size; + void *opaque; + AVBufferRef* (*alloc)(size_t size); + AVBufferRef* (*alloc2)(void *opaque, size_t size); + void (*pool_free)(void *opaque); +}; + +#endif /* AVUTIL_BUFFER_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/camellia.c b/arm/raspi/third_party/ffmpeg/libavutil/camellia.c new file mode 100644 index 00000000..3fc3b082 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/camellia.c @@ -0,0 +1,416 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "camellia.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" +#include "attributes.h" + +#define LR32(x,c) ((x) << (c) | (x) >> (32 - (c))) +#define RR32(x,c) ((x) >> (c) | (x) << (32 - (c))) + +#define MASK8 0xff +#define MASK32 0xffffffff +#define MASK64 0xffffffffffffffff + +#define Sigma1 0xA09E667F3BCC908B +#define Sigma2 0xB67AE8584CAA73B2 +#define Sigma3 0xC6EF372FE94F82BE +#define Sigma4 0x54FF53A5F1D36F1C +#define Sigma5 0x10E527FADE682D1D +#define Sigma6 0xB05688C2B3E6C1FD + +static uint64_t SP[8][256]; + +typedef struct AVCAMELLIA { + uint64_t Kw[4]; + uint64_t Ke[6]; + uint64_t K[24]; + int key_bits; +} AVCAMELLIA; + +static const uint8_t SBOX1[256] = { +112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, +134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, +166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, +139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, +223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, +254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, +170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, +135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, +233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, +120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, +114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 +}; + +static const uint8_t SBOX2[256] = { +224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, +191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, +253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, +164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, +211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, +240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, +228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, +128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 +}; + +static const uint8_t SBOX3[256] = { + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, +145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, +197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, +239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, +127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, +195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, +244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 +}; + +static const uint8_t SBOX4[256] = { +112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, +134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, +139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, +170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, +135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, +233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, +114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, +130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, +184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, +208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, +121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 +}; + +const int av_camellia_size = sizeof(AVCAMELLIA); + +static void LR128(uint64_t d[2], const uint64_t K[2], int x) +{ + int i = 0; + if (64 <= x && x < 128) { + i = 1; + x -= 64; + } + if (x <= 0 || x >= 128) { + d[0] = K[i]; + d[1] = K[!i]; + return; + } + d[0] = (K[i] << x | K[!i] >> (64 - x)); + d[1] = (K[!i] << x | K[i] >> (64 - x)); +} + +static uint64_t F(uint64_t F_IN, uint64_t KE) +{ + KE ^= F_IN; + F_IN=SP[0][KE >> 56]^SP[1][(KE >> 48) & MASK8]^SP[2][(KE >> 40) & MASK8]^SP[3][(KE >> 32) & MASK8]^SP[4][(KE >> 24) & MASK8]^SP[5][(KE >> 16) & MASK8]^SP[6][(KE >> 8) & MASK8]^SP[7][KE & MASK8]; + return F_IN; +} + +static uint64_t FL(uint64_t FL_IN, uint64_t KE) +{ + uint32_t x1, x2, k1, k2; + x1 = FL_IN >> 32; + x2 = FL_IN & MASK32; + k1 = KE >> 32; + k2 = KE & MASK32; + x2 = x2 ^ LR32((x1 & k1), 1); + x1 = x1 ^ (x2 | k2); + return ((uint64_t)x1 << 32) | (uint64_t)x2; +} + +static uint64_t FLINV(uint64_t FLINV_IN, uint64_t KE) +{ + uint32_t x1, x2, k1, k2; + x1 = FLINV_IN >> 32; + x2 = FLINV_IN & MASK32; + k1 = KE >> 32; + k2 = KE & MASK32; + x1 = x1 ^ (x2 | k2); + x2 = x2 ^ LR32((x1 & k1), 1); + return ((uint64_t)x1 << 32) | (uint64_t)x2; +} + +static const uint8_t shifts[2][12] = { + {0, 15, 15, 45, 45, 60, 94, 94, 111}, + {0, 15, 15, 30, 45, 45, 60, 60, 77, 94, 94, 111} +}; + +static const uint8_t vars[2][12] = { + {2, 0, 2, 0, 2, 2, 0, 2, 0}, + {3, 1, 2, 3, 0, 2, 1, 3, 0, 1, 2, 0} +}; + +static void generate_round_keys(AVCAMELLIA *cs, uint64_t Kl[2], uint64_t Kr[2], uint64_t Ka[2], uint64_t Kb[2]) +{ + int i; + uint64_t *Kd[4], d[2]; + Kd[0] = Kl; + Kd[1] = Kr; + Kd[2] = Ka; + Kd[3] = Kb; + cs->Kw[0] = Kl[0]; + cs->Kw[1] = Kl[1]; + if (cs->key_bits == 128) { + for (i = 0; i < 9; i++) { + LR128(d, Kd[vars[0][i]], shifts[0][i]); + cs->K[2*i] = d[0]; + cs->K[2*i+1] = d[1]; + } + LR128(d, Kd[0], 60); + cs->K[9] = d[1]; + LR128(d, Kd[2], 30); + cs->Ke[0] = d[0]; + cs->Ke[1] = d[1]; + LR128(d, Kd[0], 77); + cs->Ke[2] = d[0]; + cs->Ke[3] = d[1]; + LR128(d, Kd[2], 111); + cs->Kw[2] = d[0]; + cs->Kw[3] = d[1]; + } else { + for (i = 0; i < 12; i++) { + LR128(d, Kd[vars[1][i]], shifts[1][i]); + cs->K[2*i] = d[0]; + cs->K[2*i+1] = d[1]; + } + LR128(d, Kd[1], 30); + cs->Ke[0] = d[0]; + cs->Ke[1] = d[1]; + LR128(d, Kd[0], 60); + cs->Ke[2] = d[0]; + cs->Ke[3] = d[1]; + LR128(d, Kd[2], 77); + cs->Ke[4] = d[0]; + cs->Ke[5] = d[1]; + LR128(d, Kd[3], 111); + cs->Kw[2] = d[0]; + cs->Kw[3] = d[1]; + } +} + +static void camellia_encrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src) +{ + uint64_t D1, D2; + D1 = AV_RB64(src); + D2 = AV_RB64(src + 8); + D1 ^= cs->Kw[0]; + D2 ^= cs->Kw[1]; + D2 ^= F(D1, cs->K[0]); + D1 ^= F(D2, cs->K[1]); + D2 ^= F(D1, cs->K[2]); + D1 ^= F(D2, cs->K[3]); + D2 ^= F(D1, cs->K[4]); + D1 ^= F(D2, cs->K[5]); + D1 = FL(D1, cs->Ke[0]); + D2 = FLINV(D2, cs->Ke[1]); + D2 ^= F(D1, cs->K[6]); + D1 ^= F(D2, cs->K[7]); + D2 ^= F(D1, cs->K[8]); + D1 ^= F(D2, cs->K[9]); + D2 ^= F(D1, cs->K[10]); + D1 ^= F(D2, cs->K[11]); + D1 = FL(D1, cs->Ke[2]); + D2 = FLINV(D2, cs->Ke[3]); + D2 ^= F(D1, cs->K[12]); + D1 ^= F(D2, cs->K[13]); + D2 ^= F(D1, cs->K[14]); + D1 ^= F(D2, cs->K[15]); + D2 ^= F(D1, cs->K[16]); + D1 ^= F(D2, cs->K[17]); + if (cs->key_bits != 128) { + D1 = FL(D1, cs->Ke[4]); + D2 = FLINV(D2, cs->Ke[5]); + D2 ^= F(D1, cs->K[18]); + D1 ^= F(D2, cs->K[19]); + D2 ^= F(D1, cs->K[20]); + D1 ^= F(D2, cs->K[21]); + D2 ^= F(D1, cs->K[22]); + D1 ^= F(D2, cs->K[23]); + } + D2 ^= cs->Kw[2]; + D1 ^= cs->Kw[3]; + AV_WB64(dst, D2); + AV_WB64(dst + 8, D1); +} + +static void camellia_decrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv) +{ + uint64_t D1, D2; + D1 = AV_RB64(src); + D2 = AV_RB64(src + 8); + D1 ^= cs->Kw[2]; + D2 ^= cs->Kw[3]; + if (cs->key_bits != 128) { + D2 ^= F(D1, cs->K[23]); + D1 ^= F(D2, cs->K[22]); + D2 ^= F(D1, cs->K[21]); + D1 ^= F(D2, cs->K[20]); + D2 ^= F(D1, cs->K[19]); + D1 ^= F(D2, cs->K[18]); + D1 = FL(D1, cs->Ke[5]); + D2 = FLINV(D2, cs->Ke[4]); + } + D2 ^= F(D1, cs->K[17]); + D1 ^= F(D2, cs->K[16]); + D2 ^= F(D1, cs->K[15]); + D1 ^= F(D2, cs->K[14]); + D2 ^= F(D1, cs->K[13]); + D1 ^= F(D2, cs->K[12]); + D1 = FL(D1, cs->Ke[3]); + D2 = FLINV(D2, cs->Ke[2]); + D2 ^= F(D1, cs->K[11]); + D1 ^= F(D2, cs->K[10]); + D2 ^= F(D1, cs->K[9]); + D1 ^= F(D2, cs->K[8]); + D2 ^= F(D1, cs->K[7]); + D1 ^= F(D2, cs->K[6]); + D1 = FL(D1, cs->Ke[1]); + D2 = FLINV(D2, cs->Ke[0]); + D2 ^= F(D1, cs->K[5]); + D1 ^= F(D2, cs->K[4]); + D2 ^= F(D1, cs->K[3]); + D1 ^= F(D2, cs->K[2]); + D2 ^= F(D1, cs->K[1]); + D1 ^= F(D2, cs->K[0]); + D2 ^= cs->Kw[0]; + D1 ^= cs->Kw[1]; + if (iv) { + D2 ^= AV_RB64(iv); + D1 ^= AV_RB64(iv + 8); + memcpy(iv, src, 16); + } + AV_WB64(dst, D2); + AV_WB64(dst + 8, D1); +} + +static void computeSP(void) +{ + uint64_t z; + int i; + for (i = 0; i < 256; i++) { + z = SBOX1[i]; + SP[0][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ z; + SP[7][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ (z << 16) ^ (z << 8); + z = SBOX2[i]; + SP[1][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 16); + SP[4][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8) ^ z; + z = SBOX3[i]; + SP[2][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8); + SP[5][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 8) ^ z; + z = SBOX4[i]; + SP[3][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 8) ^ z; + SP[6][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 24) ^ (z << 16) ^ z; + } +} + +struct AVCAMELLIA *av_camellia_alloc(void) +{ + return av_mallocz(sizeof(struct AVCAMELLIA)); +} + +av_cold int av_camellia_init(AVCAMELLIA *cs, const uint8_t *key, int key_bits) +{ + uint64_t Kl[2], Kr[2], Ka[2], Kb[2]; + uint64_t D1, D2; + if (key_bits != 128 && key_bits != 192 && key_bits != 256) + return AVERROR(EINVAL); + memset(Kb, 0, sizeof(Kb)); + memset(Kr, 0, sizeof(Kr)); + cs->key_bits = key_bits; + Kl[0] = AV_RB64(key); + Kl[1] = AV_RB64(key + 8); + if (key_bits == 192) { + Kr[0] = AV_RB64(key + 16); + Kr[1] = ~Kr[0]; + } else if (key_bits == 256) { + Kr[0] = AV_RB64(key + 16); + Kr[1] = AV_RB64(key + 24); + } + computeSP(); + D1 = Kl[0] ^ Kr[0]; + D2 = Kl[1] ^ Kr[1]; + D2 ^= F(D1, Sigma1); + D1 ^= F(D2, Sigma2); + D1 ^= Kl[0]; + D2 ^= Kl[1]; + D2 ^= F(D1, Sigma3); + D1 ^= F(D2, Sigma4); + Ka[0] = D1; + Ka[1] = D2; + if (key_bits != 128) { + D1 = Ka[0] ^ Kr[0]; + D2 = Ka[1] ^ Kr[1]; + D2 ^= F(D1, Sigma5); + D1 ^= F(D2, Sigma6); + Kb[0] = D1; + Kb[1] = D2; + } + generate_round_keys(cs, Kl, Kr, Ka, Kb); + return 0; +} + +void av_camellia_crypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + camellia_decrypt(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 16; i++) + dst[i] = src[i] ^ iv[i]; + camellia_encrypt(cs, dst, dst); + memcpy(iv, dst, 16); + } else { + camellia_encrypt(cs, dst, src); + } + } + src = src + 16; + dst = dst + 16; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/camellia.h b/arm/raspi/third_party/ffmpeg/libavutil/camellia.h new file mode 100644 index 00000000..96787102 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/camellia.h @@ -0,0 +1,70 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAMELLIA_H +#define AVUTIL_CAMELLIA_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAMELLIA algorithm + * @defgroup lavu_camellia CAMELLIA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_camellia_size; + +struct AVCAMELLIA; + +/** + * Allocate an AVCAMELLIA context + * To free the struct: av_free(ptr) + */ +struct AVCAMELLIA *av_camellia_alloc(void); + +/** + * Initialize an AVCAMELLIA context. + * + * @param ctx an AVCAMELLIA context + * @param key a key of 16, 24, 32 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 128, 192, 256 + */ +int av_camellia_init(struct AVCAMELLIA *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAMELLIA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @param iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_camellia_crypt(struct AVCAMELLIA *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_CAMELLIA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cast5.c b/arm/raspi/third_party/ffmpeg/libavutil/cast5.c new file mode 100644 index 00000000..e1d2c5ca --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cast5.c @@ -0,0 +1,511 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "cast5.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" +#include "attributes.h" + +#define IA(x) ((x) >> 24) +#define IB(x) (((x) >> 16) & 0xff) +#define IC(x) (((x) >> 8) & 0xff) +#define ID(x) ((x) & 0xff) + +#define LR(x, c) (((x) << (c)) | ((x) >> ((32 - (c)) & 31))) + +#define F3(l, r, i) \ + do { \ + I = LR(cs->Km[i] - r, cs->Kr[i]); \ + f = ((S1[IA(I)] + S2[IB(I)]) ^ S3[IC(I)]) - S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define F2(l, r, i) \ + do { \ + I = LR(cs->Km[i] ^ r, cs->Kr[i]); \ + f = ((S1[IA(I)] - S2[IB(I)]) + S3[IC(I)]) ^ S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define F1(l, r, i) \ + do { \ + I = LR(cs->Km[i] + r, cs->Kr[i]); \ + f = ((S1[IA(I)] ^ S2[IB(I)]) - S3[IC(I)]) + S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define COMPUTE_Z \ + do { \ + z[0] = x[0] ^ S5[IB(x[3])] ^ S6[ID(x[3])] ^ S7[IA(x[3])] ^ S8[IC(x[3])] ^ S7[IA(x[2])]; \ + z[1] = x[2] ^ S5[IA(z[0])] ^ S6[IC(z[0])] ^ S7[IB(z[0])] ^ S8[ID(z[0])] ^ S8[IC(x[2])]; \ + z[2] = x[3] ^ S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S5[IB(x[2])]; \ + z[3] = x[1] ^ S5[IC(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[2])] ^ S8[IA(z[2])] ^ S6[ID(x[2])]; \ + } while (0) + +#define COMPUTE_X \ + do { \ + x[0] = z[2] ^ S5[IB(z[1])] ^ S6[ID(z[1])] ^ S7[IA(z[1])] ^ S8[IC(z[1])] ^ S7[IA(z[0])]; \ + x[1] = z[0] ^ S5[IA(x[0])] ^ S6[IC(x[0])] ^ S7[IB(x[0])] ^ S8[ID(x[0])] ^ S8[IC(z[0])]; \ + x[2] = z[1] ^ S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S5[IB(z[0])]; \ + x[3] = z[3] ^ S5[IC(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[2])] ^ S8[IA(x[2])] ^ S6[ID(z[0])]; \ + } while (0) + + +typedef struct AVCAST5 { + uint32_t Km[17]; + uint32_t Kr[17]; + int rounds; +} AVCAST5; + +const int av_cast5_size = sizeof(AVCAST5); + +static const uint32_t S1[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf +}; + +static const uint32_t S2[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 +}; + +static const uint32_t S3[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 +}; + +static const uint32_t S4[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 +}; + +static const uint32_t S5[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 +}; + +static const uint32_t S6[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f +}; + +static const uint32_t S7[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 +}; + +static const uint32_t S8[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e +}; + +static void generate_round_keys(int rnds, uint32_t* K, uint32_t* x, uint32_t* z) +{ + COMPUTE_Z; + + K[1] = S5[IA(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[1])] ^ S8[IC(z[1])] ^ S5[IC(z[0])]; + K[2] = S5[IC(z[2])] ^ S6[ID(z[2])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S6[IC(z[1])]; + K[3] = S5[IA(z[3])] ^ S6[IB(z[3])] ^ S7[ID(z[0])] ^ S8[IC(z[0])] ^ S7[IB(z[2])]; + K[4] = S5[IC(z[3])] ^ S6[ID(z[3])] ^ S7[IB(z[0])] ^ S8[IA(z[0])] ^ S8[IA(z[3])]; + + COMPUTE_X; + + K[5] = S5[ID(x[0])] ^ S6[IC(x[0])] ^ S7[IA(x[3])] ^ S8[IB(x[3])] ^ S5[IA(x[2])]; + K[6] = S5[IB(x[0])] ^ S6[IA(x[0])] ^ S7[IC(x[3])] ^ S8[ID(x[3])] ^ S6[IB(x[3])]; + K[7] = S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IA(x[2])] ^ S8[IB(x[2])] ^ S7[ID(x[0])]; + K[8] = S5[IB(x[1])] ^ S6[IA(x[1])] ^ S7[IC(x[2])] ^ S8[ID(x[2])] ^ S8[ID(x[1])]; + + COMPUTE_Z; + + K[9] = S5[ID(z[0])] ^ S6[IC(z[0])] ^ S7[IA(z[3])] ^ S8[IB(z[3])] ^ S5[IB(z[2])]; + K[10] = S5[IB(z[0])] ^ S6[IA(z[0])] ^ S7[IC(z[3])] ^ S8[ID(z[3])] ^ S6[IA(z[3])]; + K[11] = S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IA(z[2])] ^ S8[IB(z[2])] ^ S7[IC(z[0])]; + K[12] = S5[IB(z[1])] ^ S6[IA(z[1])] ^ S7[IC(z[2])] ^ S8[ID(z[2])] ^ S8[IC(z[1])]; + + COMPUTE_X; + + if (rnds == 16) { + K[13] = S5[IA(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[1])] ^ S8[IC(x[1])] ^ S5[ID(x[0])]; + K[14] = S5[IC(x[2])] ^ S6[ID(x[2])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S6[ID(x[1])]; + K[15] = S5[IA(x[3])] ^ S6[IB(x[3])] ^ S7[ID(x[0])] ^ S8[IC(x[0])] ^ S7[IA(x[2])]; + K[16] = S5[IC(x[3])] ^ S6[ID(x[3])] ^ S7[IB(x[0])] ^ S8[IA(x[0])] ^ S8[IB(x[3])]; + } +} + +static void encipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src) +{ + uint32_t r, l, f, I; + l = AV_RB32(src); + r = AV_RB32(src + 4); + F1(l, r, 1); + F2(r, l, 2); + F3(l, r, 3); + F1(r, l, 4); + F2(l, r, 5); + F3(r, l, 6); + F1(l, r, 7); + F2(r, l, 8); + F3(l, r, 9); + F1(r, l, 10); + F2(l, r, 11); + F3(r, l, 12); + if (cs->rounds == 16) { + F1(l, r, 13); + F2(r, l, 14); + F3(l, r, 15); + F1(r, l, 16); + } + AV_WB32(dst, r); + AV_WB32(dst + 4, l); +} + +static void decipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src, uint8_t *iv) +{ + uint32_t f, I, r, l; + l = AV_RB32(src); + r = AV_RB32(src + 4); + if (cs->rounds == 16) { + F1(l, r, 16); + F3(r, l, 15); + F2(l, r, 14); + F1(r, l, 13); + } + F3(l, r, 12); + F2(r, l, 11); + F1(l, r, 10); + F3(r, l, 9); + F2(l, r, 8); + F1(r, l, 7); + F3(l, r, 6); + F2(r, l, 5); + F1(l, r, 4); + F3(r, l, 3); + F2(l, r, 2); + F1(r, l, 1); + if (iv) { + r ^= AV_RB32(iv); + l ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + AV_WB32(dst, r); + AV_WB32(dst + 4, l); +} + +struct AVCAST5 *av_cast5_alloc(void) +{ + return av_mallocz(sizeof(struct AVCAST5)); +} + +av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits) +{ + uint8_t newKey[16]; + int i; + uint32_t p[4], q[4]; + if (key_bits % 8 || key_bits < 40 || key_bits > 128) + return AVERROR(EINVAL); + memset(newKey, 0, sizeof(newKey)); + memcpy(newKey, key, key_bits >> 3); + + cs->rounds = key_bits <= 80 ? 12 : 16; + for (i = 0; i < 4; i++) + q[i] = AV_RB32(newKey + (4 * i)); + generate_round_keys(cs->rounds, cs->Km, q, p); + generate_round_keys(cs->rounds, cs->Kr, q, p); + for (i = 0; i <= cs->rounds; i++) + cs->Kr[i] = cs->Kr[i] & 0x1f; + return 0; +} + +void av_cast5_crypt2(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + decipher(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + encipher(cs, dst, dst); + memcpy(iv, dst, 8); + } else { + encipher(cs, dst, src); + } + } + src = src + 8; + dst = dst + 8; + } +} +void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt) +{ + while (count--) { + if (decrypt){ + decipher(cs, dst, src, NULL); + } else { + encipher(cs, dst, src); + } + src = src + 8; + dst = dst + 8; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cast5.h b/arm/raspi/third_party/ffmpeg/libavutil/cast5.h new file mode 100644 index 00000000..ad5b347e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cast5.h @@ -0,0 +1,80 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAST5_H +#define AVUTIL_CAST5_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAST5 algorithm + * @defgroup lavu_cast5 CAST5 + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_cast5_size; + +struct AVCAST5; + +/** + * Allocate an AVCAST5 context + * To free the struct: av_free(ptr) + */ +struct AVCAST5 *av_cast5_alloc(void); +/** + * Initialize an AVCAST5 context. + * + * @param ctx an AVCAST5 context + * @param key a key of 5,6,...16 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 40,48,...,128 + * @return 0 on success, less than 0 on failure + */ +int av_cast5_init(struct AVCAST5 *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, ECB mode only + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt2(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); +/** + * @} + */ +#endif /* AVUTIL_CAST5_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.c b/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.c new file mode 100644 index 00000000..e2f75122 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.c @@ -0,0 +1,1006 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio channel layout utility functions + */ + +#include +#include +#include + +#include "avassert.h" +#include "channel_layout.h" +#include "bprint.h" +#include "common.h" +#include "error.h" +#include "macros.h" +#include "opt.h" + +#define CHAN_IS_AMBI(x) ((x) >= AV_CHAN_AMBISONIC_BASE &&\ + (x) <= AV_CHAN_AMBISONIC_END) + +struct channel_name { + const char *name; + const char *description; +}; + +static const struct channel_name channel_names[] = { + [AV_CHAN_FRONT_LEFT ] = { "FL", "front left" }, + [AV_CHAN_FRONT_RIGHT ] = { "FR", "front right" }, + [AV_CHAN_FRONT_CENTER ] = { "FC", "front center" }, + [AV_CHAN_LOW_FREQUENCY ] = { "LFE", "low frequency" }, + [AV_CHAN_BACK_LEFT ] = { "BL", "back left" }, + [AV_CHAN_BACK_RIGHT ] = { "BR", "back right" }, + [AV_CHAN_FRONT_LEFT_OF_CENTER ] = { "FLC", "front left-of-center" }, + [AV_CHAN_FRONT_RIGHT_OF_CENTER] = { "FRC", "front right-of-center" }, + [AV_CHAN_BACK_CENTER ] = { "BC", "back center" }, + [AV_CHAN_SIDE_LEFT ] = { "SL", "side left" }, + [AV_CHAN_SIDE_RIGHT ] = { "SR", "side right" }, + [AV_CHAN_TOP_CENTER ] = { "TC", "top center" }, + [AV_CHAN_TOP_FRONT_LEFT ] = { "TFL", "top front left" }, + [AV_CHAN_TOP_FRONT_CENTER ] = { "TFC", "top front center" }, + [AV_CHAN_TOP_FRONT_RIGHT ] = { "TFR", "top front right" }, + [AV_CHAN_TOP_BACK_LEFT ] = { "TBL", "top back left" }, + [AV_CHAN_TOP_BACK_CENTER ] = { "TBC", "top back center" }, + [AV_CHAN_TOP_BACK_RIGHT ] = { "TBR", "top back right" }, + [AV_CHAN_STEREO_LEFT ] = { "DL", "downmix left" }, + [AV_CHAN_STEREO_RIGHT ] = { "DR", "downmix right" }, + [AV_CHAN_WIDE_LEFT ] = { "WL", "wide left" }, + [AV_CHAN_WIDE_RIGHT ] = { "WR", "wide right" }, + [AV_CHAN_SURROUND_DIRECT_LEFT ] = { "SDL", "surround direct left" }, + [AV_CHAN_SURROUND_DIRECT_RIGHT] = { "SDR", "surround direct right" }, + [AV_CHAN_LOW_FREQUENCY_2 ] = { "LFE2", "low frequency 2" }, + [AV_CHAN_TOP_SIDE_LEFT ] = { "TSL", "top side left" }, + [AV_CHAN_TOP_SIDE_RIGHT ] = { "TSR", "top side right" }, + [AV_CHAN_BOTTOM_FRONT_CENTER ] = { "BFC", "bottom front center" }, + [AV_CHAN_BOTTOM_FRONT_LEFT ] = { "BFL", "bottom front left" }, + [AV_CHAN_BOTTOM_FRONT_RIGHT ] = { "BFR", "bottom front right" }, +}; + +static const char *get_channel_name(enum AVChannel channel_id) +{ + if ((unsigned) channel_id >= FF_ARRAY_ELEMS(channel_names) || + !channel_names[channel_id].name) + return NULL; + return channel_names[channel_id].name; +} + +void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id) +{ + if (channel_id >= AV_CHAN_AMBISONIC_BASE && + channel_id <= AV_CHAN_AMBISONIC_END) + av_bprintf(bp, "AMBI%d", channel_id - AV_CHAN_AMBISONIC_BASE); + else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) && + channel_names[channel_id].name) + av_bprintf(bp, "%s", channel_names[channel_id].name); + else if (channel_id == AV_CHAN_NONE) + av_bprintf(bp, "NONE"); + else + av_bprintf(bp, "USR%d", channel_id); +} + +int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id) +{ + AVBPrint bp; + + if (!buf && buf_size) + return AVERROR(EINVAL); + + av_bprint_init_for_buffer(&bp, buf, buf_size); + av_channel_name_bprint(&bp, channel_id); + + return bp.len; +} + +void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id) +{ + if (channel_id >= AV_CHAN_AMBISONIC_BASE && + channel_id <= AV_CHAN_AMBISONIC_END) + av_bprintf(bp, "ambisonic ACN %d", channel_id - AV_CHAN_AMBISONIC_BASE); + else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) && + channel_names[channel_id].description) + av_bprintf(bp, "%s", channel_names[channel_id].description); + else if (channel_id == AV_CHAN_NONE) + av_bprintf(bp, "none"); + else + av_bprintf(bp, "user %d", channel_id); +} + +int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id) +{ + AVBPrint bp; + + if (!buf && buf_size) + return AVERROR(EINVAL); + + av_bprint_init_for_buffer(&bp, buf, buf_size); + av_channel_description_bprint(&bp, channel_id); + + return bp.len; +} + +enum AVChannel av_channel_from_string(const char *str) +{ + int i; + char *endptr = (char *)str; + enum AVChannel id = AV_CHAN_NONE; + + if (!strncmp(str, "AMBI", 4)) { + i = strtol(str + 4, NULL, 0); + if (i < 0 || i > AV_CHAN_AMBISONIC_END - AV_CHAN_AMBISONIC_BASE) + return AV_CHAN_NONE; + return AV_CHAN_AMBISONIC_BASE + i; + } + + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { + if (channel_names[i].name && !strcmp(str, channel_names[i].name)) + return i; + } + if (!strncmp(str, "USR", 3)) { + const char *p = str + 3; + id = strtol(p, &endptr, 0); + } + if (id >= 0 && !*endptr) + return id; + + return AV_CHAN_NONE; +} + +struct channel_layout_name { + const char *name; + AVChannelLayout layout; +}; + +static const struct channel_layout_name channel_layout_map[] = { + { "mono", AV_CHANNEL_LAYOUT_MONO }, + { "stereo", AV_CHANNEL_LAYOUT_STEREO }, + { "2.1", AV_CHANNEL_LAYOUT_2POINT1 }, + { "3.0", AV_CHANNEL_LAYOUT_SURROUND }, + { "3.0(back)", AV_CHANNEL_LAYOUT_2_1 }, + { "4.0", AV_CHANNEL_LAYOUT_4POINT0 }, + { "quad", AV_CHANNEL_LAYOUT_QUAD }, + { "quad(side)", AV_CHANNEL_LAYOUT_2_2 }, + { "3.1", AV_CHANNEL_LAYOUT_3POINT1 }, + { "5.0", AV_CHANNEL_LAYOUT_5POINT0_BACK }, + { "5.0(side)", AV_CHANNEL_LAYOUT_5POINT0 }, + { "4.1", AV_CHANNEL_LAYOUT_4POINT1 }, + { "5.1", AV_CHANNEL_LAYOUT_5POINT1_BACK }, + { "5.1(side)", AV_CHANNEL_LAYOUT_5POINT1 }, + { "6.0", AV_CHANNEL_LAYOUT_6POINT0 }, + { "6.0(front)", AV_CHANNEL_LAYOUT_6POINT0_FRONT }, + { "hexagonal", AV_CHANNEL_LAYOUT_HEXAGONAL }, + { "6.1", AV_CHANNEL_LAYOUT_6POINT1 }, + { "6.1(back)", AV_CHANNEL_LAYOUT_6POINT1_BACK }, + { "6.1(front)", AV_CHANNEL_LAYOUT_6POINT1_FRONT }, + { "7.0", AV_CHANNEL_LAYOUT_7POINT0 }, + { "7.0(front)", AV_CHANNEL_LAYOUT_7POINT0_FRONT }, + { "7.1", AV_CHANNEL_LAYOUT_7POINT1 }, + { "7.1(wide)", AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK }, + { "7.1(wide-side)", AV_CHANNEL_LAYOUT_7POINT1_WIDE }, + { "7.1(top)", AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK }, + { "octagonal", AV_CHANNEL_LAYOUT_OCTAGONAL }, + { "cube", AV_CHANNEL_LAYOUT_CUBE }, + { "hexadecagonal", AV_CHANNEL_LAYOUT_HEXADECAGONAL }, + { "downmix", AV_CHANNEL_LAYOUT_STEREO_DOWNMIX, }, + { "22.2", AV_CHANNEL_LAYOUT_22POINT2, }, +}; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS +static uint64_t get_channel_layout_single(const char *name, int name_len) +{ + int i; + char *end; + int64_t layout; + + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) { + if (strlen(channel_layout_map[i].name) == name_len && + !memcmp(channel_layout_map[i].name, name, name_len)) + return channel_layout_map[i].layout.u.mask; + } + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) + if (channel_names[i].name && + strlen(channel_names[i].name) == name_len && + !memcmp(channel_names[i].name, name, name_len)) + return (int64_t)1 << i; + + errno = 0; + i = strtol(name, &end, 10); + + if (!errno && (end + 1 - name == name_len && *end == 'c')) + return av_get_default_channel_layout(i); + + errno = 0; + layout = strtoll(name, &end, 0); + if (!errno && end - name == name_len) + return FFMAX(layout, 0); + return 0; +} + +uint64_t av_get_channel_layout(const char *name) +{ + const char *n, *e; + const char *name_end = name + strlen(name); + int64_t layout = 0, layout_single; + + for (n = name; n < name_end; n = e + 1) { + for (e = n; e < name_end && *e != '+' && *e != '|'; e++); + layout_single = get_channel_layout_single(n, e - n); + if (!layout_single) + return 0; + layout |= layout_single; + } + return layout; +} + +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels) +{ + int nb = 0; + char *end; + uint64_t layout = av_get_channel_layout(name); + + if (layout) { + *channel_layout = layout; + *nb_channels = av_get_channel_layout_nb_channels(layout); + return 0; + } + + nb = strtol(name, &end, 10); + if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) { + *channel_layout = 0; + *nb_channels = nb; + return 0; + } + + return AVERROR(EINVAL); +} + +void av_bprint_channel_layout(struct AVBPrint *bp, + int nb_channels, uint64_t channel_layout) +{ + int i; + + if (nb_channels <= 0) + nb_channels = av_get_channel_layout_nb_channels(channel_layout); + + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (nb_channels == channel_layout_map[i].layout.nb_channels && + channel_layout == channel_layout_map[i].layout.u.mask) { + av_bprintf(bp, "%s", channel_layout_map[i].name); + return; + } + + av_bprintf(bp, "%d channels", nb_channels); + if (channel_layout) { + int i, ch; + av_bprintf(bp, " ("); + for (i = 0, ch = 0; i < 64; i++) { + if ((channel_layout & (UINT64_C(1) << i))) { + const char *name = get_channel_name(i); + if (name) { + if (ch > 0) + av_bprintf(bp, "+"); + av_bprintf(bp, "%s", name); + } + ch++; + } + } + av_bprintf(bp, ")"); + } +} + +void av_get_channel_layout_string(char *buf, int buf_size, + int nb_channels, uint64_t channel_layout) +{ + AVBPrint bp; + + av_bprint_init_for_buffer(&bp, buf, buf_size); + av_bprint_channel_layout(&bp, nb_channels, channel_layout); +} + +int av_get_channel_layout_nb_channels(uint64_t channel_layout) +{ + return av_popcount64(channel_layout); +} + +int64_t av_get_default_channel_layout(int nb_channels) { + int i; + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (nb_channels == channel_layout_map[i].layout.nb_channels) + return channel_layout_map[i].layout.u.mask; + return 0; +} + +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel) +{ + if (!(channel_layout & channel) || + av_get_channel_layout_nb_channels(channel) != 1) + return AVERROR(EINVAL); + channel_layout &= channel - 1; + return av_get_channel_layout_nb_channels(channel_layout); +} + +const char *av_get_channel_name(uint64_t channel) +{ + int i; + if (av_get_channel_layout_nb_channels(channel) != 1) + return NULL; + for (i = 0; i < 64; i++) + if ((1ULL<= FF_ARRAY_ELEMS(channel_layout_map)) + return AVERROR_EOF; + if (layout) *layout = channel_layout_map[index].layout.u.mask; + if (name) *name = channel_layout_map[index].name; + return 0; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +int av_channel_layout_from_mask(AVChannelLayout *channel_layout, + uint64_t mask) +{ + if (!mask) + return AVERROR(EINVAL); + + channel_layout->order = AV_CHANNEL_ORDER_NATIVE; + channel_layout->nb_channels = av_popcount64(mask); + channel_layout->u.mask = mask; + + return 0; +} + +int av_channel_layout_from_string(AVChannelLayout *channel_layout, + const char *str) +{ + int i; + int channels = 0, nb_channels = 0, native = 1; + enum AVChannel highest_channel = AV_CHAN_NONE; + const char *dup; + char *chlist, *end; + uint64_t mask = 0; + + /* channel layout names */ + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) { + if (channel_layout_map[i].name && !strcmp(str, channel_layout_map[i].name)) { + *channel_layout = channel_layout_map[i].layout; + return 0; + } + } + + /* ambisonic */ + if (!strncmp(str, "ambisonic ", 10)) { + const char *p = str + 10; + char *endptr; + AVChannelLayout extra = {0}; + int order; + + order = strtol(p, &endptr, 0); + if (order < 0 || order + 1 > INT_MAX / (order + 1) || + (*endptr && *endptr != '+')) + return AVERROR(EINVAL); + + channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC; + channel_layout->nb_channels = (order + 1) * (order + 1); + + if (*endptr) { + int ret = av_channel_layout_from_string(&extra, endptr + 1); + if (ret < 0) + return ret; + if (extra.nb_channels >= INT_MAX - channel_layout->nb_channels) { + av_channel_layout_uninit(&extra); + return AVERROR(EINVAL); + } + + if (extra.order == AV_CHANNEL_ORDER_NATIVE) { + channel_layout->u.mask = extra.u.mask; + } else { + channel_layout->order = AV_CHANNEL_ORDER_CUSTOM; + channel_layout->u.map = + av_calloc(channel_layout->nb_channels + extra.nb_channels, + sizeof(*channel_layout->u.map)); + if (!channel_layout->u.map) { + av_channel_layout_uninit(&extra); + return AVERROR(ENOMEM); + } + + for (i = 0; i < channel_layout->nb_channels; i++) + channel_layout->u.map[i].id = AV_CHAN_AMBISONIC_BASE + i; + for (i = 0; i < extra.nb_channels; i++) { + enum AVChannel ch = av_channel_layout_channel_from_index(&extra, i); + if (CHAN_IS_AMBI(ch)) { + av_channel_layout_uninit(&extra); + return AVERROR(EINVAL); + } + channel_layout->u.map[channel_layout->nb_channels + i].id = ch; + if (extra.order == AV_CHANNEL_ORDER_CUSTOM && + extra.u.map[i].name[0]) + av_strlcpy(channel_layout->u.map[channel_layout->nb_channels + i].name, + extra.u.map[i].name, + sizeof(channel_layout->u.map[channel_layout->nb_channels + i].name)); + } + } + channel_layout->nb_channels += extra.nb_channels; + av_channel_layout_uninit(&extra); + } + + return 0; + } + + chlist = av_strdup(str); + if (!chlist) + return AVERROR(ENOMEM); + + /* channel names */ + av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist); + end = strchr(str, ')'); + + dup = chlist; + while (*dup) { + char *channel, *chname; + int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname); + if (ret < 0) { + av_free(chlist); + return ret; + } + if (*dup) + dup++; // skip separator + if (channel && !*channel) + av_freep(&channel); + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { + if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) { + if (channel || i < highest_channel || mask & (1ULL << i)) + native = 0; // Not a native layout, use a custom one + highest_channel = i; + mask |= 1ULL << i; + break; + } + } + + if (!channel && i >= FF_ARRAY_ELEMS(channel_names)) { + char *endptr = chname; + enum AVChannel id = AV_CHAN_NONE; + + if (!strncmp(chname, "USR", 3)) { + const char *p = chname + 3; + id = strtol(p, &endptr, 0); + } + if (id < 0 || *endptr) { + native = 0; // Unknown channel name + channels = 0; + mask = 0; + av_free(chname); + break; + } + if (id > 63) + native = 0; // Not a native layout, use a custom one + else { + if (id < highest_channel || mask & (1ULL << id)) + native = 0; // Not a native layout, use a custom one + highest_channel = id; + mask |= 1ULL << id; + } + } + channels++; + av_free(channel); + av_free(chname); + } + + if (mask && native) { + av_free(chlist); + if (nb_channels && ((nb_channels != channels) || (!end || *++end))) + return AVERROR(EINVAL); + av_channel_layout_from_mask(channel_layout, mask); + return 0; + } + + /* custom layout of channel names */ + if (channels && !native) { + int idx = 0; + + if (nb_channels && ((nb_channels != channels) || (!end || *++end))) { + av_free(chlist); + return AVERROR(EINVAL); + } + + channel_layout->u.map = av_calloc(channels, sizeof(*channel_layout->u.map)); + if (!channel_layout->u.map) { + av_free(chlist); + return AVERROR(ENOMEM); + } + + channel_layout->order = AV_CHANNEL_ORDER_CUSTOM; + channel_layout->nb_channels = channels; + + dup = chlist; + while (*dup) { + char *channel, *chname; + int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname); + if (ret < 0) { + av_freep(&channel_layout->u.map); + av_free(chlist); + return ret; + } + if (*dup) + dup++; // skip separator + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { + if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) { + channel_layout->u.map[idx].id = i; + if (channel) + av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name)); + idx++; + break; + } + } + if (i >= FF_ARRAY_ELEMS(channel_names)) { + const char *p = (channel ? channel : chname) + 3; + channel_layout->u.map[idx].id = strtol(p, NULL, 0); + if (channel) + av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name)); + idx++; + } + av_free(channel); + av_free(chname); + } + av_free(chlist); + + return 0; + } + av_freep(&chlist); + + errno = 0; + mask = strtoull(str, &end, 0); + + /* channel layout mask */ + if (!errno && !*end && !strchr(str, '-') && mask) { + av_channel_layout_from_mask(channel_layout, mask); + return 0; + } + + errno = 0; + channels = strtol(str, &end, 10); + + /* number of channels */ + if (!errno && !strcmp(end, "c") && channels > 0) { + av_channel_layout_default(channel_layout, channels); + if (channel_layout->order == AV_CHANNEL_ORDER_NATIVE) + return 0; + } + + /* number of unordered channels */ + if (!errno && (!strcmp(end, "C") || !strcmp(end, " channels")) + && channels > 0) { + channel_layout->order = AV_CHANNEL_ORDER_UNSPEC; + channel_layout->nb_channels = channels; + return 0; + } + + return AVERROR(EINVAL); +} + +void av_channel_layout_uninit(AVChannelLayout *channel_layout) +{ + if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) + av_freep(&channel_layout->u.map); + memset(channel_layout, 0, sizeof(*channel_layout)); +} + +int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src) +{ + av_channel_layout_uninit(dst); + *dst = *src; + if (src->order == AV_CHANNEL_ORDER_CUSTOM) { + dst->u.map = av_malloc_array(src->nb_channels, sizeof(*dst->u.map)); + if (!dst->u.map) + return AVERROR(ENOMEM); + memcpy(dst->u.map, src->u.map, src->nb_channels * sizeof(*src->u.map)); + } + return 0; +} + +/** + * If the layout is n-th order standard-order ambisonic, with optional + * extra non-diegetic channels at the end, return the order. + * Return a negative error code otherwise. + */ +static int ambisonic_order(const AVChannelLayout *channel_layout) +{ + int i, highest_ambi, order; + + highest_ambi = -1; + if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) + highest_ambi = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask) - 1; + else { + const AVChannelCustom *map = channel_layout->u.map; + av_assert0(channel_layout->order == AV_CHANNEL_ORDER_CUSTOM); + + for (i = 0; i < channel_layout->nb_channels; i++) { + int is_ambi = CHAN_IS_AMBI(map[i].id); + + /* ambisonic following non-ambisonic */ + if (i > 0 && is_ambi && !CHAN_IS_AMBI(map[i - 1].id)) + return AVERROR(EINVAL); + + /* non-default ordering */ + if (is_ambi && map[i].id - AV_CHAN_AMBISONIC_BASE != i) + return AVERROR(EINVAL); + + if (CHAN_IS_AMBI(map[i].id)) + highest_ambi = i; + } + } + /* no ambisonic channels*/ + if (highest_ambi < 0) + return AVERROR(EINVAL); + + order = floor(sqrt(highest_ambi)); + /* incomplete order - some harmonics are missing */ + if ((order + 1) * (order + 1) != highest_ambi + 1) + return AVERROR(EINVAL); + + return order; +} + +/** + * If the custom layout is n-th order standard-order ambisonic, with optional + * extra non-diegetic channels at the end, write its string description in bp. + * Return a negative error code otherwise. + */ +static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) +{ + int nb_ambi_channels; + int order = ambisonic_order(channel_layout); + if (order < 0) + return order; + + av_bprintf(bp, "ambisonic %d", order); + + /* extra channels present */ + nb_ambi_channels = (order + 1) * (order + 1); + if (nb_ambi_channels < channel_layout->nb_channels) { + AVChannelLayout extra = { 0 }; + + if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) { + extra.order = AV_CHANNEL_ORDER_NATIVE; + extra.nb_channels = av_popcount64(channel_layout->u.mask); + extra.u.mask = channel_layout->u.mask; + } else { + extra.order = AV_CHANNEL_ORDER_CUSTOM; + extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; + extra.u.map = channel_layout->u.map + nb_ambi_channels; + } + + av_bprint_chars(bp, '+', 1); + av_channel_layout_describe_bprint(&extra, bp); + /* Not calling uninit here on extra because we don't own the u.map pointer */ + } + + return 0; +} + +int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, + AVBPrint *bp) +{ + int i; + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_NATIVE: + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (channel_layout->u.mask == channel_layout_map[i].layout.u.mask) { + av_bprintf(bp, "%s", channel_layout_map[i].name); + return 0; + } + // fall-through + case AV_CHANNEL_ORDER_CUSTOM: + if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { + int res = try_describe_ambisonic(bp, channel_layout); + if (res >= 0) + return 0; + } + if (channel_layout->nb_channels) + av_bprintf(bp, "%d channels (", channel_layout->nb_channels); + for (i = 0; i < channel_layout->nb_channels; i++) { + enum AVChannel ch = av_channel_layout_channel_from_index(channel_layout, i); + + if (i) + av_bprintf(bp, "+"); + av_channel_name_bprint(bp, ch); + if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM && + channel_layout->u.map[i].name[0]) + av_bprintf(bp, "@%s", channel_layout->u.map[i].name); + } + if (channel_layout->nb_channels) { + av_bprintf(bp, ")"); + return 0; + } + // fall-through + case AV_CHANNEL_ORDER_UNSPEC: + av_bprintf(bp, "%d channels", channel_layout->nb_channels); + return 0; + case AV_CHANNEL_ORDER_AMBISONIC: + return try_describe_ambisonic(bp, channel_layout); + default: + return AVERROR(EINVAL); + } +} + +int av_channel_layout_describe(const AVChannelLayout *channel_layout, + char *buf, size_t buf_size) +{ + AVBPrint bp; + int ret; + + if (!buf && buf_size) + return AVERROR(EINVAL); + + av_bprint_init_for_buffer(&bp, buf, buf_size); + ret = av_channel_layout_describe_bprint(channel_layout, &bp); + if (ret < 0) + return ret; + + return bp.len; +} + +enum AVChannel +av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, + unsigned int idx) +{ + int i; + + if (idx >= channel_layout->nb_channels) + return AV_CHAN_NONE; + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_CUSTOM: + return channel_layout->u.map[idx].id; + case AV_CHANNEL_ORDER_AMBISONIC: { + int ambi_channels = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask); + if (idx < ambi_channels) + return AV_CHAN_AMBISONIC_BASE + idx; + idx -= ambi_channels; + } + // fall-through + case AV_CHANNEL_ORDER_NATIVE: + for (i = 0; i < 64; i++) { + if ((1ULL << i) & channel_layout->u.mask && !idx--) + return i; + } + default: + return AV_CHAN_NONE; + } +} + +enum AVChannel +av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout, + const char *str) +{ + int index = av_channel_layout_index_from_string(channel_layout, str); + + if (index < 0) + return AV_CHAN_NONE; + + return av_channel_layout_channel_from_index(channel_layout, index); +} + +int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, + enum AVChannel channel) +{ + int i; + + if (channel == AV_CHAN_NONE) + return AVERROR(EINVAL); + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_CUSTOM: + for (i = 0; i < channel_layout->nb_channels; i++) + if (channel_layout->u.map[i].id == channel) + return i; + return AVERROR(EINVAL); + case AV_CHANNEL_ORDER_AMBISONIC: + case AV_CHANNEL_ORDER_NATIVE: { + uint64_t mask = channel_layout->u.mask; + int ambi_channels = channel_layout->nb_channels - av_popcount64(mask); + if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC && + channel >= AV_CHAN_AMBISONIC_BASE) { + if (channel - AV_CHAN_AMBISONIC_BASE >= ambi_channels) + return AVERROR(EINVAL); + return channel - AV_CHAN_AMBISONIC_BASE; + } + if ((unsigned)channel > 63 || !(mask & (1ULL << channel))) + return AVERROR(EINVAL); + mask &= (1ULL << channel) - 1; + return av_popcount64(mask) + ambi_channels; + } + default: + return AVERROR(EINVAL); + } +} + +int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, + const char *str) +{ + char *chname; + enum AVChannel ch = AV_CHAN_NONE; + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_CUSTOM: + chname = strstr(str, "@"); + if (chname) { + char buf[16]; + chname++; + av_strlcpy(buf, str, FFMIN(sizeof(buf), chname - str)); + if (!*chname) + chname = NULL; + ch = av_channel_from_string(buf); + if (ch == AV_CHAN_NONE && *buf) + return AVERROR(EINVAL); + } + for (int i = 0; chname && i < channel_layout->nb_channels; i++) { + if (!strcmp(chname, channel_layout->u.map[i].name) && + (ch == AV_CHAN_NONE || ch == channel_layout->u.map[i].id)) + return i; + } + // fall-through + case AV_CHANNEL_ORDER_AMBISONIC: + case AV_CHANNEL_ORDER_NATIVE: + ch = av_channel_from_string(str); + if (ch == AV_CHAN_NONE) + return AVERROR(EINVAL); + return av_channel_layout_index_from_channel(channel_layout, ch); + } + + return AVERROR(EINVAL); +} + +int av_channel_layout_check(const AVChannelLayout *channel_layout) +{ + if (channel_layout->nb_channels <= 0) + return 0; + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_NATIVE: + return av_popcount64(channel_layout->u.mask) == channel_layout->nb_channels; + case AV_CHANNEL_ORDER_CUSTOM: + if (!channel_layout->u.map) + return 0; + for (int i = 0; i < channel_layout->nb_channels; i++) { + if (channel_layout->u.map[i].id == AV_CHAN_NONE) + return 0; + } + return 1; + case AV_CHANNEL_ORDER_AMBISONIC: + /* If non-diegetic channels are present, ensure they are taken into account */ + return av_popcount64(channel_layout->u.mask) < channel_layout->nb_channels; + case AV_CHANNEL_ORDER_UNSPEC: + return 1; + default: + return 0; + } +} + +int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1) +{ + int i; + + /* different channel counts -> not equal */ + if (chl->nb_channels != chl1->nb_channels) + return 1; + + /* if only one is unspecified -> not equal */ + if ((chl->order == AV_CHANNEL_ORDER_UNSPEC) != + (chl1->order == AV_CHANNEL_ORDER_UNSPEC)) + return 1; + /* both are unspecified -> equal */ + else if (chl->order == AV_CHANNEL_ORDER_UNSPEC) + return 0; + + /* can compare masks directly */ + if ((chl->order == AV_CHANNEL_ORDER_NATIVE || + chl->order == AV_CHANNEL_ORDER_AMBISONIC) && + chl->order == chl1->order) + return chl->u.mask != chl1->u.mask; + + /* compare channel by channel */ + for (i = 0; i < chl->nb_channels; i++) + if (av_channel_layout_channel_from_index(chl, i) != + av_channel_layout_channel_from_index(chl1, i)) + return 1; + return 0; +} + +void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (nb_channels == channel_layout_map[i].layout.nb_channels) { + *ch_layout = channel_layout_map[i].layout; + return; + } + + ch_layout->order = AV_CHANNEL_ORDER_UNSPEC; + ch_layout->nb_channels = nb_channels; +} + +const AVChannelLayout *av_channel_layout_standard(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVChannelLayout *ch_layout = NULL; + + if (i < FF_ARRAY_ELEMS(channel_layout_map)) { + ch_layout = &channel_layout_map[i].layout; + *opaque = (void*)(i + 1); + } + + return ch_layout; +} + +uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, + uint64_t mask) +{ + uint64_t ret = 0; + int i; + + switch (channel_layout->order) { + case AV_CHANNEL_ORDER_NATIVE: + case AV_CHANNEL_ORDER_AMBISONIC: + return channel_layout->u.mask & mask; + case AV_CHANNEL_ORDER_CUSTOM: + for (i = 0; i < 64; i++) + if (mask & (1ULL << i) && av_channel_layout_index_from_channel(channel_layout, i) >= 0) + ret |= (1ULL << i); + break; + } + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.h b/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.h new file mode 100644 index 00000000..f345415c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/channel_layout.h @@ -0,0 +1,783 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * Copyright (c) 2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CHANNEL_LAYOUT_H +#define AVUTIL_CHANNEL_LAYOUT_H + +#include +#include + +#include "version.h" +#include "attributes.h" + +/** + * @file + * @ingroup lavu_audio_channels + * Public libavutil channel layout APIs header. + */ + + +/** + * @defgroup lavu_audio_channels Audio channels + * @ingroup lavu_audio + * + * Audio channel layout utility functions + * + * @{ + */ + +enum AVChannel { + ///< Invalid channel index + AV_CHAN_NONE = -1, + AV_CHAN_FRONT_LEFT, + AV_CHAN_FRONT_RIGHT, + AV_CHAN_FRONT_CENTER, + AV_CHAN_LOW_FREQUENCY, + AV_CHAN_BACK_LEFT, + AV_CHAN_BACK_RIGHT, + AV_CHAN_FRONT_LEFT_OF_CENTER, + AV_CHAN_FRONT_RIGHT_OF_CENTER, + AV_CHAN_BACK_CENTER, + AV_CHAN_SIDE_LEFT, + AV_CHAN_SIDE_RIGHT, + AV_CHAN_TOP_CENTER, + AV_CHAN_TOP_FRONT_LEFT, + AV_CHAN_TOP_FRONT_CENTER, + AV_CHAN_TOP_FRONT_RIGHT, + AV_CHAN_TOP_BACK_LEFT, + AV_CHAN_TOP_BACK_CENTER, + AV_CHAN_TOP_BACK_RIGHT, + /** Stereo downmix. */ + AV_CHAN_STEREO_LEFT = 29, + /** See above. */ + AV_CHAN_STEREO_RIGHT, + AV_CHAN_WIDE_LEFT, + AV_CHAN_WIDE_RIGHT, + AV_CHAN_SURROUND_DIRECT_LEFT, + AV_CHAN_SURROUND_DIRECT_RIGHT, + AV_CHAN_LOW_FREQUENCY_2, + AV_CHAN_TOP_SIDE_LEFT, + AV_CHAN_TOP_SIDE_RIGHT, + AV_CHAN_BOTTOM_FRONT_CENTER, + AV_CHAN_BOTTOM_FRONT_LEFT, + AV_CHAN_BOTTOM_FRONT_RIGHT, + + /** Channel is empty can be safely skipped. */ + AV_CHAN_UNUSED = 0x200, + + /** Channel contains data, but its position is unknown. */ + AV_CHAN_UNKNOWN = 0x300, + + /** + * Range of channels between AV_CHAN_AMBISONIC_BASE and + * AV_CHAN_AMBISONIC_END represent Ambisonic components using the ACN system. + * + * Given a channel id `` between AV_CHAN_AMBISONIC_BASE and + * AV_CHAN_AMBISONIC_END (inclusive), the ACN index of the channel `` is + * ` = - AV_CHAN_AMBISONIC_BASE`. + * + * @note these values are only used for AV_CHANNEL_ORDER_CUSTOM channel + * orderings, the AV_CHANNEL_ORDER_AMBISONIC ordering orders the channels + * implicitly by their position in the stream. + */ + AV_CHAN_AMBISONIC_BASE = 0x400, + // leave space for 1024 ids, which correspond to maximum order-32 harmonics, + // which should be enough for the foreseeable use cases + AV_CHAN_AMBISONIC_END = 0x7ff, +}; + +enum AVChannelOrder { + /** + * Only the channel count is specified, without any further information + * about the channel order. + */ + AV_CHANNEL_ORDER_UNSPEC, + /** + * The native channel order, i.e. the channels are in the same order in + * which they are defined in the AVChannel enum. This supports up to 63 + * different channels. + */ + AV_CHANNEL_ORDER_NATIVE, + /** + * The channel order does not correspond to any other predefined order and + * is stored as an explicit map. For example, this could be used to support + * layouts with 64 or more channels, or with empty/skipped (AV_CHAN_SILENCE) + * channels at arbitrary positions. + */ + AV_CHANNEL_ORDER_CUSTOM, + /** + * The audio is represented as the decomposition of the sound field into + * spherical harmonics. Each channel corresponds to a single expansion + * component. Channels are ordered according to ACN (Ambisonic Channel + * Number). + * + * The channel with the index n in the stream contains the spherical + * harmonic of degree l and order m given by + * @code{.unparsed} + * l = floor(sqrt(n)), + * m = n - l * (l + 1). + * @endcode + * + * Conversely given a spherical harmonic of degree l and order m, the + * corresponding channel index n is given by + * @code{.unparsed} + * n = l * (l + 1) + m. + * @endcode + * + * Normalization is assumed to be SN3D (Schmidt Semi-Normalization) + * as defined in AmbiX format $ 2.1. + */ + AV_CHANNEL_ORDER_AMBISONIC, +}; + + +/** + * @defgroup channel_masks Audio channel masks + * + * A channel layout is a 64-bits integer with a bit set for every channel. + * The number of bits set must be equal to the number of channels. + * The value 0 means that the channel layout is not known. + * @note this data structure is not powerful enough to handle channels + * combinations that have the same channel multiple times, such as + * dual-mono. + * + * @{ + */ +#define AV_CH_FRONT_LEFT (1ULL << AV_CHAN_FRONT_LEFT ) +#define AV_CH_FRONT_RIGHT (1ULL << AV_CHAN_FRONT_RIGHT ) +#define AV_CH_FRONT_CENTER (1ULL << AV_CHAN_FRONT_CENTER ) +#define AV_CH_LOW_FREQUENCY (1ULL << AV_CHAN_LOW_FREQUENCY ) +#define AV_CH_BACK_LEFT (1ULL << AV_CHAN_BACK_LEFT ) +#define AV_CH_BACK_RIGHT (1ULL << AV_CHAN_BACK_RIGHT ) +#define AV_CH_FRONT_LEFT_OF_CENTER (1ULL << AV_CHAN_FRONT_LEFT_OF_CENTER ) +#define AV_CH_FRONT_RIGHT_OF_CENTER (1ULL << AV_CHAN_FRONT_RIGHT_OF_CENTER) +#define AV_CH_BACK_CENTER (1ULL << AV_CHAN_BACK_CENTER ) +#define AV_CH_SIDE_LEFT (1ULL << AV_CHAN_SIDE_LEFT ) +#define AV_CH_SIDE_RIGHT (1ULL << AV_CHAN_SIDE_RIGHT ) +#define AV_CH_TOP_CENTER (1ULL << AV_CHAN_TOP_CENTER ) +#define AV_CH_TOP_FRONT_LEFT (1ULL << AV_CHAN_TOP_FRONT_LEFT ) +#define AV_CH_TOP_FRONT_CENTER (1ULL << AV_CHAN_TOP_FRONT_CENTER ) +#define AV_CH_TOP_FRONT_RIGHT (1ULL << AV_CHAN_TOP_FRONT_RIGHT ) +#define AV_CH_TOP_BACK_LEFT (1ULL << AV_CHAN_TOP_BACK_LEFT ) +#define AV_CH_TOP_BACK_CENTER (1ULL << AV_CHAN_TOP_BACK_CENTER ) +#define AV_CH_TOP_BACK_RIGHT (1ULL << AV_CHAN_TOP_BACK_RIGHT ) +#define AV_CH_STEREO_LEFT (1ULL << AV_CHAN_STEREO_LEFT ) +#define AV_CH_STEREO_RIGHT (1ULL << AV_CHAN_STEREO_RIGHT ) +#define AV_CH_WIDE_LEFT (1ULL << AV_CHAN_WIDE_LEFT ) +#define AV_CH_WIDE_RIGHT (1ULL << AV_CHAN_WIDE_RIGHT ) +#define AV_CH_SURROUND_DIRECT_LEFT (1ULL << AV_CHAN_SURROUND_DIRECT_LEFT ) +#define AV_CH_SURROUND_DIRECT_RIGHT (1ULL << AV_CHAN_SURROUND_DIRECT_RIGHT) +#define AV_CH_LOW_FREQUENCY_2 (1ULL << AV_CHAN_LOW_FREQUENCY_2 ) +#define AV_CH_TOP_SIDE_LEFT (1ULL << AV_CHAN_TOP_SIDE_LEFT ) +#define AV_CH_TOP_SIDE_RIGHT (1ULL << AV_CHAN_TOP_SIDE_RIGHT ) +#define AV_CH_BOTTOM_FRONT_CENTER (1ULL << AV_CHAN_BOTTOM_FRONT_CENTER ) +#define AV_CH_BOTTOM_FRONT_LEFT (1ULL << AV_CHAN_BOTTOM_FRONT_LEFT ) +#define AV_CH_BOTTOM_FRONT_RIGHT (1ULL << AV_CHAN_BOTTOM_FRONT_RIGHT ) + +#if FF_API_OLD_CHANNEL_LAYOUT +/** Channel mask value used for AVCodecContext.request_channel_layout + to indicate that the user requests the channel order of the decoder output + to be the native codec channel order. + @deprecated channel order is now indicated in a special field in + AVChannelLayout + */ +#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL +#endif + +/** + * @} + * @defgroup channel_mask_c Audio channel layouts + * @{ + * */ +#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT) +#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_2 (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_QUAD (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_5POINT0_BACK (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT1_BACK (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT0_FRONT (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_FRONT (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_7POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT0_FRONT (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1_TOP_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) +#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_CUBE (AV_CH_LAYOUT_QUAD|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT) +#define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) +#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) +#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT) + +enum AVMatrixEncoding { + AV_MATRIX_ENCODING_NONE, + AV_MATRIX_ENCODING_DOLBY, + AV_MATRIX_ENCODING_DPLII, + AV_MATRIX_ENCODING_DPLIIX, + AV_MATRIX_ENCODING_DPLIIZ, + AV_MATRIX_ENCODING_DOLBYEX, + AV_MATRIX_ENCODING_DOLBYHEADPHONE, + AV_MATRIX_ENCODING_NB +}; + +/** + * @} + */ + +/** + * An AVChannelCustom defines a single channel within a custom order layout + * + * Unlike most structures in FFmpeg, sizeof(AVChannelCustom) is a part of the + * public ABI. + * + * No new fields may be added to it without a major version bump. + */ +typedef struct AVChannelCustom { + enum AVChannel id; + char name[16]; + void *opaque; +} AVChannelCustom; + +/** + * An AVChannelLayout holds information about the channel layout of audio data. + * + * A channel layout here is defined as a set of channels ordered in a specific + * way (unless the channel order is AV_CHANNEL_ORDER_UNSPEC, in which case an + * AVChannelLayout carries only the channel count). + * All orders may be treated as if they were AV_CHANNEL_ORDER_UNSPEC by + * ignoring everything but the channel count, as long as av_channel_layout_check() + * considers they are valid. + * + * Unlike most structures in FFmpeg, sizeof(AVChannelLayout) is a part of the + * public ABI and may be used by the caller. E.g. it may be allocated on stack + * or embedded in caller-defined structs. + * + * AVChannelLayout can be initialized as follows: + * - default initialization with {0}, followed by setting all used fields + * correctly; + * - by assigning one of the predefined AV_CHANNEL_LAYOUT_* initializers; + * - with a constructor function, such as av_channel_layout_default(), + * av_channel_layout_from_mask() or av_channel_layout_from_string(). + * + * The channel layout must be unitialized with av_channel_layout_uninit() + * + * Copying an AVChannelLayout via assigning is forbidden, + * av_channel_layout_copy() must be used instead (and its return value should + * be checked) + * + * No new fields may be added to it without a major version bump, except for + * new elements of the union fitting in sizeof(uint64_t). + */ +typedef struct AVChannelLayout { + /** + * Channel order used in this layout. + * This is a mandatory field. + */ + enum AVChannelOrder order; + + /** + * Number of channels in this layout. Mandatory field. + */ + int nb_channels; + + /** + * Details about which channels are present in this layout. + * For AV_CHANNEL_ORDER_UNSPEC, this field is undefined and must not be + * used. + */ + union { + /** + * This member must be used for AV_CHANNEL_ORDER_NATIVE, and may be used + * for AV_CHANNEL_ORDER_AMBISONIC to signal non-diegetic channels. + * It is a bitmask, where the position of each set bit means that the + * AVChannel with the corresponding value is present. + * + * I.e. when (mask & (1 << AV_CHAN_FOO)) is non-zero, then AV_CHAN_FOO + * is present in the layout. Otherwise it is not present. + * + * @note when a channel layout using a bitmask is constructed or + * modified manually (i.e. not using any of the av_channel_layout_* + * functions), the code doing it must ensure that the number of set bits + * is equal to nb_channels. + */ + uint64_t mask; + /** + * This member must be used when the channel order is + * AV_CHANNEL_ORDER_CUSTOM. It is a nb_channels-sized array, with each + * element signalling the presence of the AVChannel with the + * corresponding value in map[i].id. + * + * I.e. when map[i].id is equal to AV_CHAN_FOO, then AV_CH_FOO is the + * i-th channel in the audio data. + * + * When map[i].id is in the range between AV_CHAN_AMBISONIC_BASE and + * AV_CHAN_AMBISONIC_END (inclusive), the channel contains an ambisonic + * component with ACN index (as defined above) + * n = map[i].id - AV_CHAN_AMBISONIC_BASE. + * + * map[i].name may be filled with a 0-terminated string, in which case + * it will be used for the purpose of identifying the channel with the + * convenience functions below. Otherise it must be zeroed. + */ + AVChannelCustom *map; + } u; + + /** + * For some private data of the user. + */ + void *opaque; +} AVChannelLayout; + +#define AV_CHANNEL_LAYOUT_MASK(nb, m) \ + { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = (nb), .u = { .mask = (m) }} + +/** + * @name Common pre-defined channel layouts + * @{ + */ +#define AV_CHANNEL_LAYOUT_MONO AV_CHANNEL_LAYOUT_MASK(1, AV_CH_LAYOUT_MONO) +#define AV_CHANNEL_LAYOUT_STEREO AV_CHANNEL_LAYOUT_MASK(2, AV_CH_LAYOUT_STEREO) +#define AV_CHANNEL_LAYOUT_2POINT1 AV_CHANNEL_LAYOUT_MASK(3, AV_CH_LAYOUT_2POINT1) +#define AV_CHANNEL_LAYOUT_2_1 AV_CHANNEL_LAYOUT_MASK(3, AV_CH_LAYOUT_2_1) +#define AV_CHANNEL_LAYOUT_SURROUND AV_CHANNEL_LAYOUT_MASK(3, AV_CH_LAYOUT_SURROUND) +#define AV_CHANNEL_LAYOUT_3POINT1 AV_CHANNEL_LAYOUT_MASK(4, AV_CH_LAYOUT_3POINT1) +#define AV_CHANNEL_LAYOUT_4POINT0 AV_CHANNEL_LAYOUT_MASK(4, AV_CH_LAYOUT_4POINT0) +#define AV_CHANNEL_LAYOUT_4POINT1 AV_CHANNEL_LAYOUT_MASK(5, AV_CH_LAYOUT_4POINT1) +#define AV_CHANNEL_LAYOUT_2_2 AV_CHANNEL_LAYOUT_MASK(4, AV_CH_LAYOUT_2_2) +#define AV_CHANNEL_LAYOUT_QUAD AV_CHANNEL_LAYOUT_MASK(4, AV_CH_LAYOUT_QUAD) +#define AV_CHANNEL_LAYOUT_5POINT0 AV_CHANNEL_LAYOUT_MASK(5, AV_CH_LAYOUT_5POINT0) +#define AV_CHANNEL_LAYOUT_5POINT1 AV_CHANNEL_LAYOUT_MASK(6, AV_CH_LAYOUT_5POINT1) +#define AV_CHANNEL_LAYOUT_5POINT0_BACK AV_CHANNEL_LAYOUT_MASK(5, AV_CH_LAYOUT_5POINT0_BACK) +#define AV_CHANNEL_LAYOUT_5POINT1_BACK AV_CHANNEL_LAYOUT_MASK(6, AV_CH_LAYOUT_5POINT1_BACK) +#define AV_CHANNEL_LAYOUT_6POINT0 AV_CHANNEL_LAYOUT_MASK(6, AV_CH_LAYOUT_6POINT0) +#define AV_CHANNEL_LAYOUT_6POINT0_FRONT AV_CHANNEL_LAYOUT_MASK(6, AV_CH_LAYOUT_6POINT0_FRONT) +#define AV_CHANNEL_LAYOUT_HEXAGONAL AV_CHANNEL_LAYOUT_MASK(6, AV_CH_LAYOUT_HEXAGONAL) +#define AV_CHANNEL_LAYOUT_6POINT1 AV_CHANNEL_LAYOUT_MASK(7, AV_CH_LAYOUT_6POINT1) +#define AV_CHANNEL_LAYOUT_6POINT1_BACK AV_CHANNEL_LAYOUT_MASK(7, AV_CH_LAYOUT_6POINT1_BACK) +#define AV_CHANNEL_LAYOUT_6POINT1_FRONT AV_CHANNEL_LAYOUT_MASK(7, AV_CH_LAYOUT_6POINT1_FRONT) +#define AV_CHANNEL_LAYOUT_7POINT0 AV_CHANNEL_LAYOUT_MASK(7, AV_CH_LAYOUT_7POINT0) +#define AV_CHANNEL_LAYOUT_7POINT0_FRONT AV_CHANNEL_LAYOUT_MASK(7, AV_CH_LAYOUT_7POINT0_FRONT) +#define AV_CHANNEL_LAYOUT_7POINT1 AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1) +#define AV_CHANNEL_LAYOUT_7POINT1_WIDE AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1_WIDE) +#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1_WIDE_BACK) +#define AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1_TOP_BACK) +#define AV_CHANNEL_LAYOUT_OCTAGONAL AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_OCTAGONAL) +#define AV_CHANNEL_LAYOUT_CUBE AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_CUBE) +#define AV_CHANNEL_LAYOUT_HEXADECAGONAL AV_CHANNEL_LAYOUT_MASK(16, AV_CH_LAYOUT_HEXADECAGONAL) +#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX AV_CHANNEL_LAYOUT_MASK(2, AV_CH_LAYOUT_STEREO_DOWNMIX) +#define AV_CHANNEL_LAYOUT_22POINT2 AV_CHANNEL_LAYOUT_MASK(24, AV_CH_LAYOUT_22POINT2) +#define AV_CHANNEL_LAYOUT_AMBISONIC_FIRST_ORDER \ + { .order = AV_CHANNEL_ORDER_AMBISONIC, .nb_channels = 4, .u = { .mask = 0 }} +/** @} */ + +struct AVBPrint; + +#if FF_API_OLD_CHANNEL_LAYOUT +/** + * @name Deprecated Functions + * @{ + */ + +/** + * Return a channel layout id that matches name, or 0 if no match is found. + * + * name can be one or several of the following notations, + * separated by '+' or '|': + * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0, + * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix); + * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC, + * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR); + * - a number of channels, in decimal, followed by 'c', yielding + * the default channel layout for that number of channels (@see + * av_get_default_channel_layout); + * - a channel layout mask, in hexadecimal starting with "0x" (see the + * AV_CH_* macros). + * + * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" + * + * @deprecated use av_channel_layout_from_string() + */ +attribute_deprecated +uint64_t av_get_channel_layout(const char *name); + +/** + * Return a channel layout and the number of channels based on the specified name. + * + * This function is similar to (@see av_get_channel_layout), but can also parse + * unknown channel layout specifications. + * + * @param[in] name channel layout specification string + * @param[out] channel_layout parsed channel layout (0 if unknown) + * @param[out] nb_channels number of channels + * + * @return 0 on success, AVERROR(EINVAL) if the parsing fails. + * @deprecated use av_channel_layout_from_string() + */ +attribute_deprecated +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels); + +/** + * Return a description of a channel layout. + * If nb_channels is <= 0, it is guessed from the channel_layout. + * + * @param buf put here the string containing the channel layout + * @param buf_size size in bytes of the buffer + * @param nb_channels number of channels + * @param channel_layout channel layout bitset + * @deprecated use av_channel_layout_describe() + */ +attribute_deprecated +void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout); + +/** + * Append a description of a channel layout to a bprint buffer. + * @deprecated use av_channel_layout_describe() + */ +attribute_deprecated +void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout); + +/** + * Return the number of channels in the channel layout. + * @deprecated use AVChannelLayout.nb_channels + */ +attribute_deprecated +int av_get_channel_layout_nb_channels(uint64_t channel_layout); + +/** + * Return default channel layout for a given number of channels. + * + * @deprecated use av_channel_layout_default() + */ +attribute_deprecated +int64_t av_get_default_channel_layout(int nb_channels); + +/** + * Get the index of a channel in channel_layout. + * + * @param channel_layout channel layout bitset + * @param channel a channel layout describing exactly one channel which must be + * present in channel_layout. + * + * @return index of channel in channel_layout on success, a negative AVERROR + * on error. + * + * @deprecated use av_channel_layout_index_from_channel() + */ +attribute_deprecated +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel); + +/** + * Get the channel with the given index in channel_layout. + * @deprecated use av_channel_layout_channel_from_index() + */ +attribute_deprecated +uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index); + +/** + * Get the name of a given channel. + * + * @return channel name on success, NULL on error. + * + * @deprecated use av_channel_name() + */ +attribute_deprecated +const char *av_get_channel_name(uint64_t channel); + +/** + * Get the description of a given channel. + * + * @param channel a channel layout with a single channel + * @return channel description on success, NULL on error + * @deprecated use av_channel_description() + */ +attribute_deprecated +const char *av_get_channel_description(uint64_t channel); + +/** + * Get the value and name of a standard channel layout. + * + * @param[in] index index in an internal list, starting at 0 + * @param[out] layout channel layout mask + * @param[out] name name of the layout + * @return 0 if the layout exists, + * <0 if index is beyond the limits + * @deprecated use av_channel_layout_standard() + */ +attribute_deprecated +int av_get_standard_channel_layout(unsigned index, uint64_t *layout, + const char **name); +/** + * @} + */ +#endif + +/** + * Get a human readable string in an abbreviated form describing a given channel. + * This is the inverse function of @ref av_channel_from_string(). + * + * @param buf pre-allocated buffer where to put the generated string + * @param buf_size size in bytes of the buffer. + * @param channel the AVChannel whose name to get + * @return amount of bytes needed to hold the output string, or a negative AVERROR + * on failure. If the returned value is bigger than buf_size, then the + * string was truncated. + */ +int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel); + +/** + * bprint variant of av_channel_name(). + * + * @note the string will be appended to the bprint buffer. + */ +void av_channel_name_bprint(struct AVBPrint *bp, enum AVChannel channel_id); + +/** + * Get a human readable string describing a given channel. + * + * @param buf pre-allocated buffer where to put the generated string + * @param buf_size size in bytes of the buffer. + * @param channel the AVChannel whose description to get + * @return amount of bytes needed to hold the output string, or a negative AVERROR + * on failure. If the returned value is bigger than buf_size, then the + * string was truncated. + */ +int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel); + +/** + * bprint variant of av_channel_description(). + * + * @note the string will be appended to the bprint buffer. + */ +void av_channel_description_bprint(struct AVBPrint *bp, enum AVChannel channel_id); + +/** + * This is the inverse function of @ref av_channel_name(). + * + * @return the channel with the given name + * AV_CHAN_NONE when name does not identify a known channel + */ +enum AVChannel av_channel_from_string(const char *name); + +/** + * Initialize a native channel layout from a bitmask indicating which channels + * are present. + * + * @param channel_layout the layout structure to be initialized + * @param mask bitmask describing the channel layout + * + * @return 0 on success + * AVERROR(EINVAL) for invalid mask values + */ +int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask); + +/** + * Initialize a channel layout from a given string description. + * The input string can be represented by: + * - the formal channel layout name (returned by av_channel_layout_describe()) + * - single or multiple channel names (returned by av_channel_name(), eg. "FL", + * or concatenated with "+", each optionally containing a custom name after + * a "@", eg. "FL@Left+FR@Right+LFE") + * - a decimal or hexadecimal value of a native channel layout (eg. "4" or "0x4") + * - the number of channels with default layout (eg. "4c") + * - the number of unordered channels (eg. "4C" or "4 channels") + * - the ambisonic order followed by optional non-diegetic channels (eg. + * "ambisonic 2+stereo") + * + * @param channel_layout input channel layout + * @param str string describing the channel layout + * @return 0 channel layout was detected, AVERROR_INVALIDATATA otherwise + */ +int av_channel_layout_from_string(AVChannelLayout *channel_layout, + const char *str); + +/** + * Get the default channel layout for a given number of channels. + * + * @param ch_layout the layout structure to be initialized + * @param nb_channels number of channels + */ +void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels); + +/** + * Iterate over all standard channel layouts. + * + * @param opaque a pointer where libavutil will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the standard channel layout or NULL when the iteration is + * finished + */ +const AVChannelLayout *av_channel_layout_standard(void **opaque); + +/** + * Free any allocated data in the channel layout and reset the channel + * count to 0. + * + * @param channel_layout the layout structure to be uninitialized + */ +void av_channel_layout_uninit(AVChannelLayout *channel_layout); + +/** + * Make a copy of a channel layout. This differs from just assigning src to dst + * in that it allocates and copies the map for AV_CHANNEL_ORDER_CUSTOM. + * + * @note the destination channel_layout will be always uninitialized before copy. + * + * @param dst destination channel layout + * @param src source channel layout + * @return 0 on success, a negative AVERROR on error. + */ +int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src); + +/** + * Get a human-readable string describing the channel layout properties. + * The string will be in the same format that is accepted by + * @ref av_channel_layout_from_string(), allowing to rebuild the same + * channel layout, except for opaque pointers. + * + * @param channel_layout channel layout to be described + * @param buf pre-allocated buffer where to put the generated string + * @param buf_size size in bytes of the buffer. + * @return amount of bytes needed to hold the output string, or a negative AVERROR + * on failure. If the returned value is bigger than buf_size, then the + * string was truncated. + */ +int av_channel_layout_describe(const AVChannelLayout *channel_layout, + char *buf, size_t buf_size); + +/** + * bprint variant of av_channel_layout_describe(). + * + * @note the string will be appended to the bprint buffer. + * @return 0 on success, or a negative AVERROR value on failure. + */ +int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, + struct AVBPrint *bp); + +/** + * Get the channel with the given index in a channel layout. + * + * @param channel_layout input channel layout + * @param idx index of the channel + * @return channel with the index idx in channel_layout on success or + * AV_CHAN_NONE on failure (if idx is not valid or the channel order is + * unspecified) + */ +enum AVChannel +av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx); + +/** + * Get the index of a given channel in a channel layout. In case multiple + * channels are found, only the first match will be returned. + * + * @param channel_layout input channel layout + * @param channel the channel whose index to obtain + * @return index of channel in channel_layout on success or a negative number if + * channel is not present in channel_layout. + */ +int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, + enum AVChannel channel); + +/** + * Get the index in a channel layout of a channel described by the given string. + * In case multiple channels are found, only the first match will be returned. + * + * This function accepts channel names in the same format as + * @ref av_channel_from_string(). + * + * @param channel_layout input channel layout + * @param name string describing the channel whose index to obtain + * @return a channel index described by the given string, or a negative AVERROR + * value. + */ +int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, + const char *name); + +/** + * Get a channel described by the given string. + * + * This function accepts channel names in the same format as + * @ref av_channel_from_string(). + * + * @param channel_layout input channel layout + * @param name string describing the channel to obtain + * @return a channel described by the given string in channel_layout on success + * or AV_CHAN_NONE on failure (if the string is not valid or the channel + * order is unspecified) + */ +enum AVChannel +av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout, + const char *name); + +/** + * Find out what channels from a given set are present in a channel layout, + * without regard for their positions. + * + * @param channel_layout input channel layout + * @param mask a combination of AV_CH_* representing a set of channels + * @return a bitfield representing all the channels from mask that are present + * in channel_layout + */ +uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, + uint64_t mask); + +/** + * Check whether a channel layout is valid, i.e. can possibly describe audio + * data. + * + * @param channel_layout input channel layout + * @return 1 if channel_layout is valid, 0 otherwise. + */ +int av_channel_layout_check(const AVChannelLayout *channel_layout); + +/** + * Check whether two channel layouts are semantically the same, i.e. the same + * channels are present on the same positions in both. + * + * If one of the channel layouts is AV_CHANNEL_ORDER_UNSPEC, while the other is + * not, they are considered to be unequal. If both are AV_CHANNEL_ORDER_UNSPEC, + * they are considered equal iff the channel counts are the same in both. + * + * @param chl input channel layout + * @param chl1 input channel layout + * @return 0 if chl and chl1 are equal, 1 if they are not equal. A negative + * AVERROR code if one or both are invalid. + */ +int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1); + +/** + * @} + */ + +#endif /* AVUTIL_CHANNEL_LAYOUT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/color_utils.c b/arm/raspi/third_party/ffmpeg/libavutil/color_utils.c new file mode 100644 index 00000000..5e221fb7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/color_utils.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2015 Kevin Wheatley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/color_utils.h" +#include "libavutil/pixfmt.h" + +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc) +{ + double gamma; + switch (trc) { + case AVCOL_TRC_BT709: + case AVCOL_TRC_SMPTE170M: + case AVCOL_TRC_SMPTE240M: + case AVCOL_TRC_BT1361_ECG: + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: + /* these share a segmented TRC, but gamma 1.961 is a close + approximation, and also more correct for decoding content */ + gamma = 1.961; + break; + case AVCOL_TRC_GAMMA22: + case AVCOL_TRC_IEC61966_2_1: + gamma = 2.2; + break; + case AVCOL_TRC_GAMMA28: + gamma = 2.8; + break; + case AVCOL_TRC_LINEAR: + gamma = 1.0; + break; + default: + gamma = 0.0; // Unknown value representation + } + return gamma; +} + +#define BT709_alpha 1.099296826809442 +#define BT709_beta 0.018053968510807 + +static double avpriv_trc_bt709(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_gamma22(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2); +} + +static double avpriv_trc_gamma28(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8); +} + +static double avpriv_trc_smpte240M(double Lc) +{ + const double a = 1.1115; + const double b = 0.0228; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.000 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_linear(double Lc) +{ + return Lc; +} + +static double avpriv_trc_log(double Lc) +{ + return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0; +} + +static double avpriv_trc_log_sqrt(double Lc) +{ + // sqrt(10) / 1000 + return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5; +} + +static double avpriv_trc_iec61966_2_4(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0) + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_bt1361(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_iec61966_2_1(double Lc) +{ + const double a = 1.055; + const double b = 0.0031308; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 12.92 * Lc + : a * pow(Lc, 1.0 / 2.4) - (a - 1.0); +} + +static double avpriv_trc_smpte_st2084(double Lc) +{ + const double c1 = 3424.0 / 4096.0; // c3-c2 + 1 + const double c2 = 32.0 * 2413.0 / 4096.0; + const double c3 = 32.0 * 2392.0 / 4096.0; + const double m = 128.0 * 2523.0 / 4096.0; + const double n = 0.25 * 2610.0 / 4096.0; + const double L = Lc / 10000.0; + const double Ln = pow(L, n); + + return (0.0 > Lc) ? 0.0 + : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m); + +} + +static double avpriv_trc_smpte_st428_1(double Lc) +{ + return (0.0 > Lc) ? 0.0 + : pow(48.0 * Lc / 52.37, 1.0 / 2.6); +} + + +static double avpriv_trc_arib_std_b67(double Lc) { + // The function uses the definition from HEVC, which assumes that the peak + // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and + // using the definition from the ARIB STD-B67 spec) + const double a = 0.17883277; + const double b = 0.28466892; + const double c = 0.55991073; + return (0.0 > Lc) ? 0.0 : + (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c); +} + +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc) +{ + avpriv_trc_function func = NULL; + switch (trc) { + case AVCOL_TRC_BT709: + case AVCOL_TRC_SMPTE170M: + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: + func = avpriv_trc_bt709; + break; + + case AVCOL_TRC_GAMMA22: + func = avpriv_trc_gamma22; + break; + case AVCOL_TRC_GAMMA28: + func = avpriv_trc_gamma28; + break; + + case AVCOL_TRC_SMPTE240M: + func = avpriv_trc_smpte240M; + break; + + case AVCOL_TRC_LINEAR: + func = avpriv_trc_linear; + break; + + case AVCOL_TRC_LOG: + func = avpriv_trc_log; + break; + + case AVCOL_TRC_LOG_SQRT: + func = avpriv_trc_log_sqrt; + break; + + case AVCOL_TRC_IEC61966_2_4: + func = avpriv_trc_iec61966_2_4; + break; + + case AVCOL_TRC_BT1361_ECG: + func = avpriv_trc_bt1361; + break; + + case AVCOL_TRC_IEC61966_2_1: + func = avpriv_trc_iec61966_2_1; + break; + + case AVCOL_TRC_SMPTEST2084: + func = avpriv_trc_smpte_st2084; + break; + + case AVCOL_TRC_SMPTEST428_1: + func = avpriv_trc_smpte_st428_1; + break; + + case AVCOL_TRC_ARIB_STD_B67: + func = avpriv_trc_arib_std_b67; + break; + + case AVCOL_TRC_RESERVED0: + case AVCOL_TRC_UNSPECIFIED: + case AVCOL_TRC_RESERVED: + default: + break; + } + return func; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/color_utils.h b/arm/raspi/third_party/ffmpeg/libavutil/color_utils.h new file mode 100644 index 00000000..95290064 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/color_utils.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 Kevin Wheatley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_COLOR_UTILS_H +#define AVUTIL_COLOR_UTILS_H + + +#include "libavutil/pixfmt.h" + +/** + * Determine a suitable 'gamma' value to match the supplied + * AVColorTransferCharacteristic. + * + * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html) + * + * @return Will return an approximation to the simple gamma function matching + * the supplied Transfer Characteristic, Will return 0.0 for any + * we cannot reasonably match against. + */ +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc); + + +typedef double (*avpriv_trc_function)(double); + +/** + * Determine the function needed to apply the given + * AVColorTransferCharacteristic to linear input. + * + * The function returned should expect a nominal domain and range of [0.0-1.0] + * values outside of this range maybe valid depending on the chosen + * characteristic function. + * + * @return Will return pointer to the function matching the + * supplied Transfer Characteristic. If unspecified will + * return NULL: + */ +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc); + +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/colorspace.h b/arm/raspi/third_party/ffmpeg/libavutil/colorspace.h new file mode 100644 index 00000000..ef6f6107 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/colorspace.h @@ -0,0 +1,150 @@ +/* + * Colorspace conversion defines + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Various defines for YUV<->RGB conversion + */ + +#ifndef AVUTIL_COLORSPACE_H +#define AVUTIL_COLORSPACE_H + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define YUV_TO_RGB1(cb1, cr1)\ +{\ + cb = (cb1) - 128;\ + cr = (cr1) - 128;\ + r_add = FIX(1.40200) * cr + ONE_HALF;\ + g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\ + b_add = FIX(1.77200) * cb + ONE_HALF;\ +} + +#define YUV_TO_RGB2(r, g, b, y1)\ +{\ + y = (y1) << SCALEBITS;\ + r = cm[(y + r_add) >> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define Y_CCIR_TO_JPEG(y)\ + cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] + +#define Y_JPEG_TO_CCIR(y)\ + (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define C_CCIR_TO_JPEG(y)\ + cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS] + +/* NOTE: the clamp is really necessary! */ +static inline int C_JPEG_TO_CCIR(int y) { + y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS); + if (y < 16) + y = 16; + return y; +} + + +#define RGB_TO_Y_CCIR(r, g, b) \ +((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ + FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_Y_JPEG(r, g, b) \ +(FFMIN((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ + FIX(0.11400) * (b) + (ONE_HALF)) >> SCALEBITS, 255)) + +#define RGB_TO_U_JPEG(r1, g1, b1)\ +(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#define RGB_TO_V_JPEG(r1, g1, b1)\ +(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ + FIX(0.08131) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +// Conversion macros for 8-bit RGB to YUV +// Derived from ITU-R BT.709-6 (06/2015) Item 3.5 +// https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en + +#define RGB_TO_Y_BT709(r, g, b) \ +((FIX(0.21260*219.0/255.0) * (r) + FIX(0.71520*219.0/255.0) * (g) + \ + FIX(0.07220*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_BT709(r1, g1, b1, shift)\ +(((- FIX(0.11457*224.0/255.0) * r1 - FIX(0.38543*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_BT709(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.45415*224.0/255.0) * g1 - \ + FIX(0.04585*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_Y_BT709_FULL(r, g, b) \ +(FFMIN((FIX(0.21260) * (r) + FIX(0.71520) * (g) + \ + FIX(0.07220) * (b) + (ONE_HALF)) >> SCALEBITS, 255)) + +#define RGB_TO_U_BT709_FULL(r1, g1, b1)\ +(((- FIX(0.11457) * r1 - FIX(0.38543) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#define RGB_TO_V_BT709_FULL(r1, g1, b1)\ +(((FIX(0.50000) * r1 - FIX(0.45415) * g1 - \ + FIX(0.04585) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#endif /* AVUTIL_COLORSPACE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/common.h b/arm/raspi/third_party/ffmpeg/libavutil/common.h new file mode 100644 index 00000000..fd1404be --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/common.h @@ -0,0 +1,578 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) +#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "attributes.h" +#include "macros.h" + +//rounded division & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +/* Fast a/(1<=0 and b>=0 */ +#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ + : ((a) + (1<<(b)) - 1) >> (b)) +/* Backwards compat. */ +#define FF_CEIL_RSHIFT AV_CEIL_RSHIFT + +#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) +#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) + +/** + * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they + * are not representable as absolute values of their type. This is the same + * as with *abs() + * @see FFNABS() + */ +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +/** + * Negative Absolute value. + * this works for all integers of all types. + * As with many macros, this evaluates its argument twice, it thus must not have + * a sideeffect, that is FFNABS(x++) has undefined behavior. + */ +#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) + +/** + * Unsigned Absolute value. + * This takes the absolute value of a signed int and returns it as a unsigned. + * This also works with INT_MIN which would otherwise not be representable + * As with many macros, this evaluates its argument twice. + */ +#define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a)) +#define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a)) + +/* misc math functions */ + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "intmath.h" +#endif + +#ifndef av_ceil_log2 +# define av_ceil_log2 av_ceil_log2_c +#endif +#ifndef av_clip +# define av_clip av_clip_c +#endif +#ifndef av_clip64 +# define av_clip64 av_clip64_c +#endif +#ifndef av_clip_uint8 +# define av_clip_uint8 av_clip_uint8_c +#endif +#ifndef av_clip_int8 +# define av_clip_int8 av_clip_int8_c +#endif +#ifndef av_clip_uint16 +# define av_clip_uint16 av_clip_uint16_c +#endif +#ifndef av_clip_int16 +# define av_clip_int16 av_clip_int16_c +#endif +#ifndef av_clipl_int32 +# define av_clipl_int32 av_clipl_int32_c +#endif +#ifndef av_clip_intp2 +# define av_clip_intp2 av_clip_intp2_c +#endif +#ifndef av_clip_uintp2 +# define av_clip_uintp2 av_clip_uintp2_c +#endif +#ifndef av_mod_uintp2 +# define av_mod_uintp2 av_mod_uintp2_c +#endif +#ifndef av_sat_add32 +# define av_sat_add32 av_sat_add32_c +#endif +#ifndef av_sat_dadd32 +# define av_sat_dadd32 av_sat_dadd32_c +#endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif +#ifndef av_sat_add64 +# define av_sat_add64 av_sat_add64_c +#endif +#ifndef av_sat_sub64 +# define av_sat_sub64 av_sat_sub64_c +#endif +#ifndef av_clipf +# define av_clipf av_clipf_c +#endif +#ifndef av_clipd +# define av_clipd av_clipd_c +#endif +#ifndef av_popcount +# define av_popcount av_popcount_c +#endif +#ifndef av_popcount64 +# define av_popcount64 av_popcount64_c +#endif +#ifndef av_parity +# define av_parity av_parity_c +#endif + +#ifndef av_log2 +av_const int av_log2(unsigned v); +#endif + +#ifndef av_log2_16bit +av_const int av_log2_16bit(unsigned v); +#endif + +/** + * Clip a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int av_clip_c(int a, int amin, int amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed 64bit integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint8_t av_clip_uint8_c(int a) +{ + if (a&(~0xFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -128,127 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int8_t av_clip_int8_c(int a) +{ + if ((a+0x80U) & ~0xFF) return (a>>31) ^ 0x7F; + else return a; +} + +/** + * Clip a signed integer value into the 0-65535 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint16_t av_clip_uint16_c(int a) +{ + if (a&(~0xFFFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int16_t av_clip_int16_c(int a) +{ + if ((a+0x8000U) & ~0xFFFF) return (a>>31) ^ 0x7FFF; + else return a; +} + +/** + * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) +{ + if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF); + else return (int32_t)a; +} + +/** + * Clip a signed integer into the -(2^p),(2^p-1) range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const int av_clip_intp2_c(int a, int p) +{ + if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) + return (a >> 31) ^ ((1 << p) - 1); + else + return a; +} + +/** + * Clip a signed integer to an unsigned power of two range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) +{ + if (a & ~((1<> 31 & ((1<= 0) + return INT64_MAX ^ (b >> 63); + return s; +#endif +} + +/** + * Subtract two signed 64-bit values with saturation. + * + * @param a one value + * @param b another value + * @return difference with signed saturation + */ +static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow) + int64_t tmp; + return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); +#else + if (b <= 0 && a >= INT64_MAX + b) + return INT64_MAX; + if (b >= 0 && a <= INT64_MIN + b) + return INT64_MIN; + return a - b; +#endif +} + +/** + * Clip a float value into the amin-amax range. + * If a is nan or -inf amin will be returned. + * If a is +inf amax will be returned. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const float av_clipf_c(float a, float amin, float amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + return FFMIN(FFMAX(a, amin), amax); +} + +/** + * Clip a double value into the amin-amax range. + * If a is nan or -inf amin will be returned. + * If a is +inf amax will be returned. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const double av_clipd_c(double a, double amin, double amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + return FFMIN(FFMAX(a, amin), amax); +} + +/** Compute ceil(log2(x)). + * @param x value used to compute ceil(log2(x)) + * @return computed ceiling of log2(x) + */ +static av_always_inline av_const int av_ceil_log2_c(int x) +{ + return av_log2((x - 1U) << 1); +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount_c(uint32_t x) +{ + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + x += x >> 8; + return (x + (x >> 16)) & 0x3F; +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount64_c(uint64_t x) +{ + return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); +} + +static av_always_inline av_const int av_parity_c(uint32_t v) +{ + return av_popcount(v) & 1; +} + +/** + * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_BYTE Expression reading one byte from the input. + * Evaluated up to 7 times (4 for the currently + * assigned Unicode range). With a memory buffer + * input, this could be *ptr++, or if you want to make sure + * that *ptr stops at the end of a NULL terminated string then + * *ptr ? *ptr++ : 0 + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + * + * @warning ERROR should not contain a loop control statement which + * could interact with the internal while loop, and should force an + * exit from the macro code (e.g. through a goto or a return) in order + * to prevent undefined results. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= (GET_BYTE);\ + {\ + uint32_t top = (val & 128) >> 1;\ + if ((val & 0xc0) == 0x80 || val >= 0xFE)\ + {ERROR}\ + while (val & top) {\ + unsigned int tmp = (GET_BYTE) - 128;\ + if(tmp>>6)\ + {ERROR}\ + val= (val<<6) + tmp;\ + top <<= 5;\ + }\ + val &= (top << 1) - 1;\ + } + +/** + * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_16BIT Expression returning two bytes of UTF-16 data converted + * to native byte order. Evaluated one or two times. + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + */ +#define GET_UTF16(val, GET_16BIT, ERROR)\ + val = (GET_16BIT);\ + {\ + unsigned int hi = val - 0xD800;\ + if (hi < 0x800) {\ + val = (GET_16BIT) - 0xDC00;\ + if (val > 0x3FFU || hi > 0x3FFU)\ + {ERROR}\ + val += (hi<<10) + 0x10000;\ + }\ + }\ + +/** + * @def PUT_UTF8(val, tmp, PUT_BYTE) + * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +/** + * @def PUT_UTF16(val, tmp, PUT_16BIT) + * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint16_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_16BIT. + * @param PUT_16BIT writes the converted UTF-16 data to any proper destination + * in desired endianness. It could be a function or a statement, and uses tmp + * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" + * PUT_BYTE will be executed 1 or 2 times depending on input character. + */ +#define PUT_UTF16(val, tmp, PUT_16BIT)\ + {\ + uint32_t in = val;\ + if (in < 0x10000) {\ + tmp = in;\ + PUT_16BIT\ + } else {\ + tmp = 0xD800 | ((in - 0x10000) >> 10);\ + PUT_16BIT\ + tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ + PUT_16BIT\ + }\ + }\ + + + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/cpu.c new file mode 100644 index 00000000..2c5f7f49 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cpu.c @@ -0,0 +1,282 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if HAVE_SCHED_GETAFFINITY +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#endif + +#include +#include +#include + +#include "attributes.h" +#include "cpu.h" +#include "cpu_internal.h" +#include "opt.h" +#include "common.h" + +#if HAVE_GETPROCESSAFFINITYMASK || HAVE_WINRT +#include +#endif +#if HAVE_SYSCTL +#if HAVE_SYS_PARAM_H +#include +#endif +#include +#include +#endif +#if HAVE_UNISTD_H +#include +#endif + +static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); +static atomic_int cpu_count = ATOMIC_VAR_INIT(-1); + +static int get_cpu_flags(void) +{ +#if ARCH_MIPS + return ff_get_cpu_flags_mips(); +#elif ARCH_AARCH64 + return ff_get_cpu_flags_aarch64(); +#elif ARCH_ARM + return ff_get_cpu_flags_arm(); +#elif ARCH_PPC + return ff_get_cpu_flags_ppc(); +#elif ARCH_RISCV + return ff_get_cpu_flags_riscv(); +#elif ARCH_X86 + return ff_get_cpu_flags_x86(); +#elif ARCH_LOONGARCH + return ff_get_cpu_flags_loongarch(); +#endif + return 0; +} + +void av_force_cpu_flags(int arg){ + if (ARCH_X86 && + (arg & ( AV_CPU_FLAG_3DNOW | + AV_CPU_FLAG_3DNOWEXT | + AV_CPU_FLAG_MMXEXT | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE2SLOW | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_AVXSLOW | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX512 )) + && !(arg & AV_CPU_FLAG_MMX)) { + av_log(NULL, AV_LOG_WARNING, "MMX implied by specified flags\n"); + arg |= AV_CPU_FLAG_MMX; + } + + atomic_store_explicit(&cpu_flags, arg, memory_order_relaxed); +} + +int av_get_cpu_flags(void) +{ + int flags = atomic_load_explicit(&cpu_flags, memory_order_relaxed); + if (flags == -1) { + flags = get_cpu_flags(); + atomic_store_explicit(&cpu_flags, flags, memory_order_relaxed); + } + return flags; +} + +int av_parse_cpu_caps(unsigned *flags, const char *s) +{ + static const AVOption cpuflags_opts[] = { + { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, +#if ARCH_PPC + { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC }, .unit = "flags" }, +#elif ARCH_X86 + { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" }, + { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" }, + { "mmxext" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" }, + { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE }, .unit = "flags" }, + { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2 }, .unit = "flags" }, + { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2SLOW }, .unit = "flags" }, + { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3 }, .unit = "flags" }, + { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3SLOW }, .unit = "flags" }, + { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSSE3 }, .unit = "flags" }, + { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM }, .unit = "flags" }, + { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE4 }, .unit = "flags" }, + { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE42 }, .unit = "flags" }, + { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX }, .unit = "flags" }, + { "avxslow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVXSLOW }, .unit = "flags" }, + { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA3 }, .unit = "flags" }, + { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA4 }, .unit = "flags" }, + { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI2 }, .unit = "flags" }, + { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOW }, .unit = "flags" }, + { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" }, + { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, + { "aesni", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AESNI }, .unit = "flags" }, + { "avx512" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX512 }, .unit = "flags" }, + { "avx512icl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX512ICL }, .unit = "flags" }, + { "slowgather", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SLOW_GATHER }, .unit = "flags" }, + +#define CPU_FLAG_P2 AV_CPU_FLAG_CMOV | AV_CPU_FLAG_MMX +#define CPU_FLAG_P3 CPU_FLAG_P2 | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE +#define CPU_FLAG_P4 CPU_FLAG_P3| AV_CPU_FLAG_SSE2 + { "pentium2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P2 }, .unit = "flags" }, + { "pentium3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P3 }, .unit = "flags" }, + { "pentium4", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P4 }, .unit = "flags" }, + +#define CPU_FLAG_K62 AV_CPU_FLAG_MMX | AV_CPU_FLAG_3DNOW +#define CPU_FLAG_ATHLON CPU_FLAG_K62 | AV_CPU_FLAG_CMOV | AV_CPU_FLAG_3DNOWEXT | AV_CPU_FLAG_MMX2 +#define CPU_FLAG_ATHLONXP CPU_FLAG_ATHLON | AV_CPU_FLAG_SSE +#define CPU_FLAG_K8 CPU_FLAG_ATHLONXP | AV_CPU_FLAG_SSE2 + { "k6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" }, + { "k62", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_K62 }, .unit = "flags" }, + { "athlon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_ATHLON }, .unit = "flags" }, + { "athlonxp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_ATHLONXP }, .unit = "flags" }, + { "k8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_K8 }, .unit = "flags" }, +#elif ARCH_ARM + { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" }, + { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, + { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, + { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" }, + { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "setend", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SETEND }, .unit = "flags" }, +#elif ARCH_AARCH64 + { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, +#elif ARCH_MIPS + { "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" }, + { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" }, +#elif ARCH_LOONGARCH + { "lsx", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_LSX }, .unit = "flags" }, + { "lasx", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_LASX }, .unit = "flags" }, +#elif ARCH_RISCV + { "rvi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVI }, .unit = "flags" }, + { "rvf", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVF }, .unit = "flags" }, + { "rvd", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVD }, .unit = "flags" }, + { "rvv-i32", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_I32 }, .unit = "flags" }, + { "rvv-f32", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F32 }, .unit = "flags" }, + { "rvv-i64", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_I64 }, .unit = "flags" }, + { "rvv", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F64 }, .unit = "flags" }, + { "rvb-basic",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVB_BASIC }, .unit = "flags" }, +#endif + { NULL }, + }; + static const AVClass class = { + .class_name = "cpuflags", + .item_name = av_default_item_name, + .option = cpuflags_opts, + .version = LIBAVUTIL_VERSION_INT, + }; + const AVClass *pclass = &class; + + return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags); +} + +int av_cpu_count(void) +{ + static atomic_int printed = ATOMIC_VAR_INIT(0); + + int nb_cpus = 1; + int count = 0; +#if HAVE_WINRT + SYSTEM_INFO sysinfo; +#endif +#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT) + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + + if (!sched_getaffinity(0, sizeof(cpuset), &cpuset)) + nb_cpus = CPU_COUNT(&cpuset); +#elif HAVE_GETPROCESSAFFINITYMASK + DWORD_PTR proc_aff, sys_aff; + if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff)) + nb_cpus = av_popcount64(proc_aff); +#elif HAVE_SYSCTL && defined(HW_NCPUONLINE) + int mib[2] = { CTL_HW, HW_NCPUONLINE }; + size_t len = sizeof(nb_cpus); + + if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1) + nb_cpus = 0; +#elif HAVE_SYSCTL && defined(HW_NCPU) + int mib[2] = { CTL_HW, HW_NCPU }; + size_t len = sizeof(nb_cpus); + + if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1) + nb_cpus = 0; +#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN) + nb_cpus = sysconf(_SC_NPROC_ONLN); +#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) + nb_cpus = sysconf(_SC_NPROCESSORS_ONLN); +#elif HAVE_WINRT + GetNativeSystemInfo(&sysinfo); + nb_cpus = sysinfo.dwNumberOfProcessors; +#endif + + if (!atomic_exchange_explicit(&printed, 1, memory_order_relaxed)) + av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); + + count = atomic_load_explicit(&cpu_count, memory_order_relaxed); + + if (count > 0) { + nb_cpus = count; + av_log(NULL, AV_LOG_DEBUG, "overriding to %d logical cores\n", nb_cpus); + } + + return nb_cpus; +} + +void av_cpu_force_count(int count) +{ + atomic_store_explicit(&cpu_count, count, memory_order_relaxed); +} + +size_t av_cpu_max_align(void) +{ +#if ARCH_MIPS + return ff_get_cpu_max_align_mips(); +#elif ARCH_AARCH64 + return ff_get_cpu_max_align_aarch64(); +#elif ARCH_ARM + return ff_get_cpu_max_align_arm(); +#elif ARCH_PPC + return ff_get_cpu_max_align_ppc(); +#elif ARCH_X86 + return ff_get_cpu_max_align_x86(); +#elif ARCH_LOONGARCH + return ff_get_cpu_max_align_loongarch(); +#endif + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/cpu.h new file mode 100644 index 00000000..8fa5ea91 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cpu.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CPU_H +#define AVUTIL_CPU_H + +#include + +#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ + + /* lower 16 bits - CPU features */ +#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX +#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW +#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions +#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions +#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions +#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define AV_CPU_FLAG_SSSE3SLOW 0x4000000 ///< SSSE3 supported, but usually not faster +#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower +#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions +#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions +#define AV_CPU_FLAG_AESNI 0x80000 ///< Advanced Encryption Standard functions +#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_AVXSLOW 0x8000000 ///< AVX supported, but slow when using YMM registers (e.g. Bulldozer) +#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions +#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions +#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction +#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions +#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 +#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 +#define AV_CPU_FLAG_AVX512 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used +#define AV_CPU_FLAG_AVX512ICL 0x200000 ///< F/CD/BW/DQ/VL/VNNI/IFMA/VBMI/VBMI2/VPOPCNTDQ/BITALG/GFNI/VAES/VPCLMULQDQ +#define AV_CPU_FLAG_SLOW_GATHER 0x2000000 ///< CPU has slow gathers. + +#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard +#define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 +#define AV_CPU_FLAG_POWER8 0x0004 ///< ISA 2.07 + +#define AV_CPU_FLAG_ARMV5TE (1 << 0) +#define AV_CPU_FLAG_ARMV6 (1 << 1) +#define AV_CPU_FLAG_ARMV6T2 (1 << 2) +#define AV_CPU_FLAG_VFP (1 << 3) +#define AV_CPU_FLAG_VFPV3 (1 << 4) +#define AV_CPU_FLAG_NEON (1 << 5) +#define AV_CPU_FLAG_ARMV8 (1 << 6) +#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations +#define AV_CPU_FLAG_SETEND (1 <<16) + +#define AV_CPU_FLAG_MMI (1 << 0) +#define AV_CPU_FLAG_MSA (1 << 1) + +//Loongarch SIMD extension. +#define AV_CPU_FLAG_LSX (1 << 0) +#define AV_CPU_FLAG_LASX (1 << 1) + +// RISC-V extensions +#define AV_CPU_FLAG_RVI (1 << 0) ///< I (full GPR bank) +#define AV_CPU_FLAG_RVF (1 << 1) ///< F (single precision FP) +#define AV_CPU_FLAG_RVD (1 << 2) ///< D (double precision FP) +#define AV_CPU_FLAG_RVV_I32 (1 << 3) ///< Vectors of 8/16/32-bit int's */ +#define AV_CPU_FLAG_RVV_F32 (1 << 4) ///< Vectors of float's */ +#define AV_CPU_FLAG_RVV_I64 (1 << 5) ///< Vectors of 64-bit int's */ +#define AV_CPU_FLAG_RVV_F64 (1 << 6) ///< Vectors of double's +#define AV_CPU_FLAG_RVB_BASIC (1 << 7) ///< Basic bit-manipulations + +/** + * Return the flags which specify extensions supported by the CPU. + * The returned value is affected by av_force_cpu_flags() if that was used + * before. So av_get_cpu_flags() can easily be used in an application to + * detect the enabled cpu flags. + */ +int av_get_cpu_flags(void); + +/** + * Disables cpu detection and forces the specified flags. + * -1 is a special case that disables forcing of specific flags. + */ +void av_force_cpu_flags(int flags); + +/** + * Parse CPU caps from a string and update the given AV_CPU_* flags based on that. + * + * @return negative on error. + */ +int av_parse_cpu_caps(unsigned *flags, const char *s); + +/** + * @return the number of logical CPU cores present. + */ +int av_cpu_count(void); + +/** + * Overrides cpu count detection and forces the specified count. + * Count < 1 disables forcing of specific count. + */ +void av_cpu_force_count(int count); + +/** + * Get the maximum data alignment that may be required by FFmpeg. + * + * Note that this is affected by the build configuration and the CPU flags mask, + * so e.g. if the CPU supports AVX, but libavutil has been built with + * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through + * av_set_cpu_flags_mask(), then this function will behave as if AVX is not + * present. + */ +size_t av_cpu_max_align(void); + +#endif /* AVUTIL_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cpu_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/cpu_internal.h new file mode 100644 index 00000000..634f28ba --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cpu_internal.h @@ -0,0 +1,62 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CPU_INTERNAL_H +#define AVUTIL_CPU_INTERNAL_H + +#include "config.h" + +#include "cpu.h" + +#define CPUEXT_SUFFIX(flags, suffix, cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext)) + +#define CPUEXT_SUFFIX_FAST2(flags, suffix, cpuext, slow_cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext) && \ + !((flags) & AV_CPU_FLAG_ ## slow_cpuext ## SLOW)) + +#define CPUEXT_SUFFIX_SLOW(flags, suffix, cpuext) \ + (HAVE_ ## cpuext ## suffix && \ + ((flags) & (AV_CPU_FLAG_ ## cpuext | AV_CPU_FLAG_ ## cpuext ## SLOW))) + +#define CPUEXT_SUFFIX_SLOW2(flags, suffix, cpuext, slow_cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext) && \ + ((flags) & (AV_CPU_FLAG_ ## slow_cpuext | AV_CPU_FLAG_ ## slow_cpuext ## SLOW))) + +#define CPUEXT_SUFFIX_FAST(flags, suffix, cpuext) CPUEXT_SUFFIX_FAST2(flags, suffix, cpuext, cpuext) + +#define CPUEXT(flags, cpuext) CPUEXT_SUFFIX(flags, , cpuext) +#define CPUEXT_FAST(flags, cpuext) CPUEXT_SUFFIX_FAST(flags, , cpuext) +#define CPUEXT_SLOW(flags, cpuext) CPUEXT_SUFFIX_SLOW(flags, , cpuext) + +int ff_get_cpu_flags_mips(void); +int ff_get_cpu_flags_aarch64(void); +int ff_get_cpu_flags_arm(void); +int ff_get_cpu_flags_ppc(void); +int ff_get_cpu_flags_riscv(void); +int ff_get_cpu_flags_x86(void); +int ff_get_cpu_flags_loongarch(void); + +size_t ff_get_cpu_max_align_mips(void); +size_t ff_get_cpu_max_align_aarch64(void); +size_t ff_get_cpu_max_align_arm(void); +size_t ff_get_cpu_max_align_ppc(void); +size_t ff_get_cpu_max_align_x86(void); +size_t ff_get_cpu_max_align_loongarch(void); + +#endif /* AVUTIL_CPU_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/crc.c b/arm/raspi/third_party/ffmpeg/libavutil/crc.c new file mode 100644 index 00000000..703b56f4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/crc.c @@ -0,0 +1,415 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "thread.h" +#include "avassert.h" +#include "bswap.h" +#include "crc.h" +#include "error.h" + +#if CONFIG_HARDCODED_TABLES +static const AVCRC av_crc_table[AV_CRC_MAX][257] = { + [AV_CRC_8_ATM] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, + 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, + 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, + 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, + 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, + 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, + 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, + 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, + 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, + 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, + 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, + 0xFA, 0xFD, 0xF4, 0xF3, 0x01 + }, + [AV_CRC_8_EBU] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, + 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, + 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, + 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, + 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, + 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, + 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, + 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, + 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, + 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, + 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, + 0xE3, 0xFE, 0xD9, 0xC4, 0x01 + }, + [AV_CRC_16_ANSI] = { + 0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180, + 0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200, + 0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200, + 0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180, + 0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200, + 0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180, + 0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180, + 0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200, + 0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201, + 0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181, + 0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181, + 0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201, + 0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181, + 0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201, + 0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201, + 0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181, + 0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203, + 0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183, + 0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183, + 0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203, + 0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183, + 0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203, + 0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203, + 0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183, + 0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182, + 0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202, + 0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202, + 0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182, + 0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202, + 0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182, + 0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182, + 0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202, + 0x0001 + }, + [AV_CRC_16_CCITT] = { + 0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770, + 0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1, + 0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662, + 0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3, + 0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554, + 0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5, + 0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446, + 0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7, + 0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338, + 0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9, + 0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A, + 0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB, + 0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C, + 0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D, + 0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E, + 0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F, + 0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1, + 0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760, + 0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3, + 0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672, + 0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5, + 0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544, + 0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7, + 0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456, + 0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9, + 0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328, + 0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB, + 0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A, + 0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D, + 0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C, + 0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F, + 0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E, + 0x0001 + }, + [AV_CRC_24_IEEE] = { + 0x000000, 0xFB4C86, 0x0DD58A, 0xF6990C, 0xE1E693, 0x1AAA15, 0xEC3319, + 0x177F9F, 0x3981A1, 0xC2CD27, 0x34542B, 0xCF18AD, 0xD86732, 0x232BB4, + 0xD5B2B8, 0x2EFE3E, 0x894EC5, 0x720243, 0x849B4F, 0x7FD7C9, 0x68A856, + 0x93E4D0, 0x657DDC, 0x9E315A, 0xB0CF64, 0x4B83E2, 0xBD1AEE, 0x465668, + 0x5129F7, 0xAA6571, 0x5CFC7D, 0xA7B0FB, 0xE9D10C, 0x129D8A, 0xE40486, + 0x1F4800, 0x08379F, 0xF37B19, 0x05E215, 0xFEAE93, 0xD050AD, 0x2B1C2B, + 0xDD8527, 0x26C9A1, 0x31B63E, 0xCAFAB8, 0x3C63B4, 0xC72F32, 0x609FC9, + 0x9BD34F, 0x6D4A43, 0x9606C5, 0x81795A, 0x7A35DC, 0x8CACD0, 0x77E056, + 0x591E68, 0xA252EE, 0x54CBE2, 0xAF8764, 0xB8F8FB, 0x43B47D, 0xB52D71, + 0x4E61F7, 0xD2A319, 0x29EF9F, 0xDF7693, 0x243A15, 0x33458A, 0xC8090C, + 0x3E9000, 0xC5DC86, 0xEB22B8, 0x106E3E, 0xE6F732, 0x1DBBB4, 0x0AC42B, + 0xF188AD, 0x0711A1, 0xFC5D27, 0x5BEDDC, 0xA0A15A, 0x563856, 0xAD74D0, + 0xBA0B4F, 0x4147C9, 0xB7DEC5, 0x4C9243, 0x626C7D, 0x9920FB, 0x6FB9F7, + 0x94F571, 0x838AEE, 0x78C668, 0x8E5F64, 0x7513E2, 0x3B7215, 0xC03E93, + 0x36A79F, 0xCDEB19, 0xDA9486, 0x21D800, 0xD7410C, 0x2C0D8A, 0x02F3B4, + 0xF9BF32, 0x0F263E, 0xF46AB8, 0xE31527, 0x1859A1, 0xEEC0AD, 0x158C2B, + 0xB23CD0, 0x497056, 0xBFE95A, 0x44A5DC, 0x53DA43, 0xA896C5, 0x5E0FC9, + 0xA5434F, 0x8BBD71, 0x70F1F7, 0x8668FB, 0x7D247D, 0x6A5BE2, 0x911764, + 0x678E68, 0x9CC2EE, 0xA44733, 0x5F0BB5, 0xA992B9, 0x52DE3F, 0x45A1A0, + 0xBEED26, 0x48742A, 0xB338AC, 0x9DC692, 0x668A14, 0x901318, 0x6B5F9E, + 0x7C2001, 0x876C87, 0x71F58B, 0x8AB90D, 0x2D09F6, 0xD64570, 0x20DC7C, + 0xDB90FA, 0xCCEF65, 0x37A3E3, 0xC13AEF, 0x3A7669, 0x148857, 0xEFC4D1, + 0x195DDD, 0xE2115B, 0xF56EC4, 0x0E2242, 0xF8BB4E, 0x03F7C8, 0x4D963F, + 0xB6DAB9, 0x4043B5, 0xBB0F33, 0xAC70AC, 0x573C2A, 0xA1A526, 0x5AE9A0, + 0x74179E, 0x8F5B18, 0x79C214, 0x828E92, 0x95F10D, 0x6EBD8B, 0x982487, + 0x636801, 0xC4D8FA, 0x3F947C, 0xC90D70, 0x3241F6, 0x253E69, 0xDE72EF, + 0x28EBE3, 0xD3A765, 0xFD595B, 0x0615DD, 0xF08CD1, 0x0BC057, 0x1CBFC8, + 0xE7F34E, 0x116A42, 0xEA26C4, 0x76E42A, 0x8DA8AC, 0x7B31A0, 0x807D26, + 0x9702B9, 0x6C4E3F, 0x9AD733, 0x619BB5, 0x4F658B, 0xB4290D, 0x42B001, + 0xB9FC87, 0xAE8318, 0x55CF9E, 0xA35692, 0x581A14, 0xFFAAEF, 0x04E669, + 0xF27F65, 0x0933E3, 0x1E4C7C, 0xE500FA, 0x1399F6, 0xE8D570, 0xC62B4E, + 0x3D67C8, 0xCBFEC4, 0x30B242, 0x27CDDD, 0xDC815B, 0x2A1857, 0xD154D1, + 0x9F3526, 0x6479A0, 0x92E0AC, 0x69AC2A, 0x7ED3B5, 0x859F33, 0x73063F, + 0x884AB9, 0xA6B487, 0x5DF801, 0xAB610D, 0x502D8B, 0x475214, 0xBC1E92, + 0x4A879E, 0xB1CB18, 0x167BE3, 0xED3765, 0x1BAE69, 0xE0E2EF, 0xF79D70, + 0x0CD1F6, 0xFA48FA, 0x01047C, 0x2FFA42, 0xD4B6C4, 0x222FC8, 0xD9634E, + 0xCE1CD1, 0x355057, 0xC3C95B, 0x3885DD, 0x000001, + }, + [AV_CRC_32_IEEE] = { + 0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517, + 0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B, + 0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048, + 0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652, + 0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D, + 0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095, + 0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA, + 0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0, + 0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3, + 0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF, + 0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730, + 0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A, + 0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05, + 0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475, + 0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A, + 0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840, + 0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB, + 0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87, + 0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4, + 0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE, + 0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1, + 0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64, + 0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B, + 0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351, + 0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832, + 0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E, + 0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5, + 0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF, + 0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0, + 0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0, + 0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F, + 0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185, + 0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A, + 0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176, + 0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15, + 0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F, + 0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620, + 0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8, + 0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7, + 0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD, + 0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E, + 0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2, + 0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001 + }, + [AV_CRC_32_IEEE_LE] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001 + }, + [AV_CRC_16_ANSI_LE] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, + 0x0001 + }, +}; +#else +#if CONFIG_SMALL +#define CRC_TABLE_SIZE 257 +#else +#define CRC_TABLE_SIZE 1024 +#endif +static AVCRC av_crc_table[AV_CRC_MAX][CRC_TABLE_SIZE]; + +#define DECLARE_CRC_INIT_TABLE_ONCE(id, le, bits, poly) \ +static AVOnce id ## _once_control = AV_ONCE_INIT; \ +static void id ## _init_table_once(void) \ +{ \ + av_assert0(av_crc_init(av_crc_table[id], le, bits, poly, sizeof(av_crc_table[id])) >= 0); \ +} + +#define CRC_INIT_TABLE_ONCE(id) ff_thread_once(&id ## _once_control, id ## _init_table_once) + +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM, 0, 8, 0x07) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU, 0, 8, 0x1D) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI, 0, 16, 0x8005) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT, 0, 16, 0x1021) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE, 0, 24, 0x864CFB) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE, 0, 32, 0x04C11DB7) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE, 1, 32, 0xEDB88320) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE, 1, 16, 0xA001) +#endif + +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) +{ + unsigned i, j; + uint32_t c; + + if (bits < 8 || bits > 32 || poly >= (1LL << bits)) + return AVERROR(EINVAL); + if (ctx_size != sizeof(AVCRC) * 257 && ctx_size != sizeof(AVCRC) * 1024) + return AVERROR(EINVAL); + + for (i = 0; i < 256; i++) { + if (le) { + for (c = i, j = 0; j < 8; j++) + c = (c >> 1) ^ (poly & (-(c & 1))); + ctx[i] = c; + } else { + for (c = i << 24, j = 0; j < 8; j++) + c = (c << 1) ^ ((poly << (32 - bits)) & (((int32_t) c) >> 31)); + ctx[i] = av_bswap32(c); + } + } + ctx[256] = 1; +#if !CONFIG_SMALL + if (ctx_size >= sizeof(AVCRC) * 1024) + for (i = 0; i < 256; i++) + for (j = 0; j < 3; j++) + ctx[256 * (j + 1) + i] = + (ctx[256 * j + i] >> 8) ^ ctx[ctx[256 * j + i] & 0xFF]; +#endif + + return 0; +} + +const AVCRC *av_crc_get_table(AVCRCId crc_id) +{ +#if !CONFIG_HARDCODED_TABLES + switch (crc_id) { + case AV_CRC_8_ATM: CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM); break; + case AV_CRC_8_EBU: CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU); break; + case AV_CRC_16_ANSI: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI); break; + case AV_CRC_16_CCITT: CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT); break; + case AV_CRC_24_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE); break; + case AV_CRC_32_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE); break; + case AV_CRC_32_IEEE_LE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE); break; + case AV_CRC_16_ANSI_LE: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE); break; + default: av_assert0(0); + } +#endif + return av_crc_table[crc_id]; +} + +uint32_t av_crc(const AVCRC *ctx, uint32_t crc, + const uint8_t *buffer, size_t length) +{ + const uint8_t *end = buffer + length; + +#if !CONFIG_SMALL + if (!ctx[256]) { + while (((intptr_t) buffer & 3) && buffer < end) + crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8); + + while (buffer < end - 3) { + crc ^= av_le2ne32(*(const uint32_t *) buffer); buffer += 4; + crc = ctx[3 * 256 + ( crc & 0xFF)] ^ + ctx[2 * 256 + ((crc >> 8 ) & 0xFF)] ^ + ctx[1 * 256 + ((crc >> 16) & 0xFF)] ^ + ctx[0 * 256 + ((crc >> 24) )]; + } + } +#endif + while (buffer < end) + crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8); + + return crc; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/crc.h b/arm/raspi/third_party/ffmpeg/libavutil/crc.h new file mode 100644 index 00000000..7f59812a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/crc.h @@ -0,0 +1,102 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_crc32 + * Public header for CRC hash function implementation. + */ + +#ifndef AVUTIL_CRC_H +#define AVUTIL_CRC_H + +#include +#include +#include "attributes.h" + +/** + * @defgroup lavu_crc32 CRC + * @ingroup lavu_hash + * CRC (Cyclic Redundancy Check) hash function implementation. + * + * This module supports numerous CRC polynomials, in addition to the most + * widely used CRC-32-IEEE. See @ref AVCRCId for a list of available + * polynomials. + * + * @{ + */ + +typedef uint32_t AVCRC; + +typedef enum { + AV_CRC_8_ATM, + AV_CRC_16_ANSI, + AV_CRC_16_CCITT, + AV_CRC_32_IEEE, + AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ + AV_CRC_16_ANSI_LE, /*< reversed bitorder version of AV_CRC_16_ANSI */ + AV_CRC_24_IEEE, + AV_CRC_8_EBU, + AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ +}AVCRCId; + +/** + * Initialize a CRC table. + * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 + * @param le If 1, the lowest bit represents the coefficient for the highest + * exponent of the corresponding polynomial (both for poly and + * actual CRC). + * If 0, you must swap the CRC parameter and the result of av_crc + * if you need the standard representation (can be simplified in + * most cases to e.g. bswap16): + * av_bswap32(crc << (32-bits)) + * @param bits number of bits for the CRC + * @param poly generator polynomial without the x**bits coefficient, in the + * representation as specified by le + * @param ctx_size size of ctx in bytes + * @return <0 on failure + */ +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); + +/** + * Get an initialized standard CRC table. + * @param crc_id ID of a standard CRC + * @return a pointer to the CRC table or NULL on failure + */ +const AVCRC *av_crc_get_table(AVCRCId crc_id); + +/** + * Calculate the CRC of a block. + * @param ctx initialized AVCRC array (see av_crc_init()) + * @param crc CRC of previous blocks if any or initial value for CRC + * @param buffer buffer whose CRC to calculate + * @param length length of the buffer + * @return CRC updated with the data from the given block + * + * @see av_crc_init() "le" parameter + */ +uint32_t av_crc(const AVCRC *ctx, uint32_t crc, + const uint8_t *buffer, size_t length) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_CRC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/csp.c b/arm/raspi/third_party/ffmpeg/libavutil/csp.c new file mode 100644 index 00000000..98fc83c1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/csp.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 Ronald S. Bultje + * 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 Colorspace functions for libavutil + * @author Ronald S. Bultje + * @author Leo Izen + */ + +#include + +#include "attributes.h" +#include "csp.h" +#include "pixfmt.h" +#include "rational.h" + +#define AVR(d) { (int)(d * 100000 + 0.5), 100000 } + +/* + * All constants explained in e.g. https://linuxtv.org/downloads/v4l-dvb-apis/ch02s06.html + * The older ones (bt470bg/m) are also explained in their respective ITU docs + * (e.g. https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.470-5-199802-S!!PDF-E.pdf) + * whereas the newer ones can typically be copied directly from wikipedia :) + */ +static const struct AVLumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { + [AVCOL_SPC_FCC] = { AVR(0.30), AVR(0.59), AVR(0.11) }, + [AVCOL_SPC_BT470BG] = { AVR(0.299), AVR(0.587), AVR(0.114) }, + [AVCOL_SPC_SMPTE170M] = { AVR(0.299), AVR(0.587), AVR(0.114) }, + [AVCOL_SPC_BT709] = { AVR(0.2126), AVR(0.7152), AVR(0.0722) }, + [AVCOL_SPC_SMPTE240M] = { AVR(0.212), AVR(0.701), AVR(0.087) }, + [AVCOL_SPC_YCOCG] = { AVR(0.25), AVR(0.5), AVR(0.25) }, + [AVCOL_SPC_RGB] = { AVR(1), AVR(1), AVR(1) }, + [AVCOL_SPC_BT2020_NCL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) }, + [AVCOL_SPC_BT2020_CL] = { AVR(0.2627), AVR(0.6780), AVR(0.0593) }, +}; + +const struct AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp) +{ + const AVLumaCoefficients *coeffs; + + if (csp >= AVCOL_SPC_NB) + return NULL; + coeffs = &luma_coefficients[csp]; + if (!coeffs->cr.num) + return NULL; + + return coeffs; +} + +#define WP_D65 { AVR(0.3127), AVR(0.3290) } +#define WP_C { AVR(0.3100), AVR(0.3160) } +#define WP_DCI { AVR(0.3140), AVR(0.3510) } +#define WP_E { {1, 3}, {1, 3} } + +static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB] = { + [AVCOL_PRI_BT709] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.300), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_BT470M] = { WP_C, { { AVR(0.670), AVR(0.330) }, { AVR(0.210), AVR(0.710) }, { AVR(0.140), AVR(0.080) } } }, + [AVCOL_PRI_BT470BG] = { WP_D65, { { AVR(0.640), AVR(0.330) }, { AVR(0.290), AVR(0.600) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_SMPTE170M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } }, + [AVCOL_PRI_SMPTE240M] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.310), AVR(0.595) }, { AVR(0.155), AVR(0.070) } } }, + [AVCOL_PRI_SMPTE428] = { WP_E, { { AVR(0.735), AVR(0.265) }, { AVR(0.274), AVR(0.718) }, { AVR(0.167), AVR(0.009) } } }, + [AVCOL_PRI_SMPTE431] = { WP_DCI, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_SMPTE432] = { WP_D65, { { AVR(0.680), AVR(0.320) }, { AVR(0.265), AVR(0.690) }, { AVR(0.150), AVR(0.060) } } }, + [AVCOL_PRI_FILM] = { WP_C, { { AVR(0.681), AVR(0.319) }, { AVR(0.243), AVR(0.692) }, { AVR(0.145), AVR(0.049) } } }, + [AVCOL_PRI_BT2020] = { WP_D65, { { AVR(0.708), AVR(0.292) }, { AVR(0.170), AVR(0.797) }, { AVR(0.131), AVR(0.046) } } }, + [AVCOL_PRI_JEDEC_P22] = { WP_D65, { { AVR(0.630), AVR(0.340) }, { AVR(0.295), AVR(0.605) }, { AVR(0.155), AVR(0.077) } } }, +}; + +const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm) +{ + const AVColorPrimariesDesc *p; + + if (prm >= AVCOL_PRI_NB) + return NULL; + p = &color_primaries[prm]; + if (!p->prim.r.x.num) + return NULL; + + return p; +} + +static av_always_inline AVRational abs_sub_q(AVRational r1, AVRational r2) +{ + AVRational diff = av_sub_q(r1, r2); + /* denominator assumed to be positive */ + return av_make_q(abs(diff.num), diff.den); +} + +enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm) +{ + AVRational delta; + + for (enum AVColorPrimaries p = 0; p < AVCOL_PRI_NB; p++) { + const AVColorPrimariesDesc *ref = &color_primaries[p]; + if (!ref->prim.r.x.num) + continue; + + delta = abs_sub_q(prm->prim.r.x, ref->prim.r.x); + delta = av_add_q(delta, abs_sub_q(prm->prim.r.y, ref->prim.r.y)); + delta = av_add_q(delta, abs_sub_q(prm->prim.g.x, ref->prim.g.x)); + delta = av_add_q(delta, abs_sub_q(prm->prim.g.y, ref->prim.g.y)); + delta = av_add_q(delta, abs_sub_q(prm->prim.b.x, ref->prim.b.x)); + delta = av_add_q(delta, abs_sub_q(prm->prim.b.y, ref->prim.b.y)); + delta = av_add_q(delta, abs_sub_q(prm->wp.x, ref->wp.x)); + delta = av_add_q(delta, abs_sub_q(prm->wp.y, ref->wp.y)); + + if (av_cmp_q(delta, av_make_q(1, 1000)) < 0) + return p; + } + + return AVCOL_PRI_UNSPECIFIED; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/csp.h b/arm/raspi/third_party/ffmpeg/libavutil/csp.h new file mode 100644 index 00000000..18ef208a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/csp.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016 Ronald S. Bultje + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CSP_H +#define AVUTIL_CSP_H + +#include "pixfmt.h" +#include "rational.h" + +/** + * @file + * Colorspace value utility functions for libavutil. + * @ingroup lavu_math_csp + * @author Ronald S. Bultje + * @author Leo Izen + */ + +/** + * @defgroup lavu_math_csp Colorspace Utility + * @ingroup lavu_math + * @{ + */ + +/** + * Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar + * calculations. + */ +typedef struct AVLumaCoefficients { + AVRational cr, cg, cb; +} AVLumaCoefficients; + +/** + * Struct containing chromaticity x and y values for the standard CIE 1931 + * chromaticity definition. + */ +typedef struct AVCIExy { + AVRational x, y; +} AVCIExy; + +/** + * Struct defining the red, green, and blue primary locations in terms of CIE + * 1931 chromaticity x and y. + */ +typedef struct AVPrimaryCoefficients { + AVCIExy r, g, b; +} AVPrimaryCoefficients; + +/** + * Struct defining white point location in terms of CIE 1931 chromaticity x + * and y. + */ +typedef AVCIExy AVWhitepointCoefficients; + +/** + * Struct that contains both white point location and primaries location, providing + * the complete description of a color gamut. + */ +typedef struct AVColorPrimariesDesc { + AVWhitepointCoefficients wp; + AVPrimaryCoefficients prim; +} AVColorPrimariesDesc; + +/** + * Retrieves the Luma coefficients necessary to construct a conversion matrix + * from an enum constant describing the colorspace. + * @param csp An enum constant indicating YUV or similar colorspace. + * @return The Luma coefficients associated with that colorspace, or NULL + * if the constant is unknown to libavutil. + */ +const AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp); + +/** + * Retrieves a complete gamut description from an enum constant describing the + * color primaries. + * @param prm An enum constant indicating primaries + * @return A description of the colorspace gamut associated with that enum + * constant, or NULL if the constant is unknown to libavutil. + */ +const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm); + +/** + * Detects which enum AVColorPrimaries constant corresponds to the given complete + * gamut description. + * @see enum AVColorPrimaries + * @param prm A description of the colorspace gamut + * @return The enum constant associated with this gamut, or + * AVCOL_PRI_UNSPECIFIED if no clear match can be idenitified. + */ +enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm); + +/** + * @} + */ + +#endif /* AVUTIL_CSP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/cuda_check.h b/arm/raspi/third_party/ffmpeg/libavutil/cuda_check.h new file mode 100644 index 00000000..f5a9234e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/cuda_check.h @@ -0,0 +1,67 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_CUDA_CHECK_H +#define AVUTIL_CUDA_CHECK_H + +#include "compat/cuda/dynlink_loader.h" +#include "error.h" + +typedef CUresult CUDAAPI cuda_check_GetErrorName(CUresult error, const char** pstr); +typedef CUresult CUDAAPI cuda_check_GetErrorString(CUresult error, const char** pstr); + +/** + * Wrap a CUDA function call and print error information if it fails. + */ +static inline int ff_cuda_check(void *avctx, + void *cuGetErrorName_fn, void *cuGetErrorString_fn, + CUresult err, const char *func) +{ + const char *err_name; + const char *err_string; + + av_log(avctx, AV_LOG_TRACE, "Calling %s\n", func); + + if (err == CUDA_SUCCESS) + return 0; + + ((cuda_check_GetErrorName *)cuGetErrorName_fn)(err, &err_name); + ((cuda_check_GetErrorString *)cuGetErrorString_fn)(err, &err_string); + + av_log(avctx, AV_LOG_ERROR, "%s failed", func); + if (err_name && err_string) + av_log(avctx, AV_LOG_ERROR, " -> %s: %s", err_name, err_string); + av_log(avctx, AV_LOG_ERROR, "\n"); + + return AVERROR_EXTERNAL; +} + +/** + * Convenience wrapper for ff_cuda_check when directly linking libcuda. + */ + +#define FF_CUDA_CHECK(avclass, x) ff_cuda_check(avclass, cuGetErrorName, cuGetErrorString, (x), #x) + +/** + * Convenience wrapper for ff_cuda_check when dynamically loading cuda symbols. + */ + +#define FF_CUDA_CHECK_DL(avclass, cudl, x) ff_cuda_check(avclass, cudl->cuGetErrorName, cudl->cuGetErrorString, (x), #x) + +#endif /* AVUTIL_CUDA_CHECK_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/des.c b/arm/raspi/third_party/ffmpeg/libavutil/des.c new file mode 100644 index 00000000..e0e9a866 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/des.c @@ -0,0 +1,333 @@ +/* + * DES encryption/decryption + * Copyright (c) 2007 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include "attributes.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" +#include "des.h" + +#define T(a, b, c, d, e, f, g, h) 64 - a, 64 - b, 64 - c, 64 - d, 64 - e, 64 - f, 64 - g, 64 - h +static const uint8_t IP_shuffle[] = { + T(58, 50, 42, 34, 26, 18, 10, 2), + T(60, 52, 44, 36, 28, 20, 12, 4), + T(62, 54, 46, 38, 30, 22, 14, 6), + T(64, 56, 48, 40, 32, 24, 16, 8), + T(57, 49, 41, 33, 25, 17, 9, 1), + T(59, 51, 43, 35, 27, 19, 11, 3), + T(61, 53, 45, 37, 29, 21, 13, 5), + T(63, 55, 47, 39, 31, 23, 15, 7) +}; +#undef T + +#if CONFIG_SMALL || defined(GENTABLES) +#define T(a, b, c, d) 32 - a, 32 - b, 32 - c, 32 - d +static const uint8_t P_shuffle[] = { + T(16, 7, 20, 21), + T(29, 12, 28, 17), + T( 1, 15, 23, 26), + T( 5, 18, 31, 10), + T( 2, 8, 24, 14), + T(32, 27, 3, 9), + T(19, 13, 30, 6), + T(22, 11, 4, 25) +}; +#undef T +#endif + +#define T(a, b, c, d, e, f, g) 64 - a, 64 - b, 64 - c, 64 - d, 64 - e, 64 - f, 64 - g +static const uint8_t PC1_shuffle[] = { + T(57, 49, 41, 33, 25, 17, 9), + T( 1, 58, 50, 42, 34, 26, 18), + T(10, 2, 59, 51, 43, 35, 27), + T(19, 11, 3, 60, 52, 44, 36), + T(63, 55, 47, 39, 31, 23, 15), + T( 7, 62, 54, 46, 38, 30, 22), + T(14, 6, 61, 53, 45, 37, 29), + T(21, 13, 5, 28, 20, 12, 4) +}; +#undef T + +#define T(a, b, c, d, e, f) 56 - a, 56 - b, 56 - c, 56 - d, 56 - e, 56 - f +static const uint8_t PC2_shuffle[] = { + T(14, 17, 11, 24, 1, 5), + T( 3, 28, 15, 6, 21, 10), + T(23, 19, 12, 4, 26, 8), + T(16, 7, 27, 20, 13, 2), + T(41, 52, 31, 37, 47, 55), + T(30, 40, 51, 45, 33, 48), + T(44, 49, 39, 56, 34, 53), + T(46, 42, 50, 36, 29, 32) +}; +#undef T + +#if CONFIG_SMALL +static const uint8_t S_boxes[8][32] = { + { 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87, + 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0, }, + { 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a, + 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f, }, + { 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18, + 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7, }, + { 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f, + 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4, }, + { 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69, + 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e, }, + { 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b, + 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6, }, + { 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61, + 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2, }, + { 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27, + 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8, + } +}; +#else +/** + * This table contains the results of applying both the S-box and P-shuffle. + * It can be regenerated by compiling tests/des.c with "-DCONFIG_SMALL -DGENTABLES". + */ +static const uint32_t S_boxes_P_shuffle[8][64] = { + { 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002, }, + { 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000, }, + { 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100, }, + { 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040, }, + { 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080, }, + { 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008, }, + { 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001, }, + { 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800, }, +}; +#endif + +static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) +{ + int i; + uint64_t res = 0; + for (i = 0; i < shuffle_len; i++) + res += res + ((in >> *shuffle++) & 1); + return res; +} + +static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) +{ + int i; + uint64_t res = 0; + shuffle += shuffle_len - 1; + for (i = 0; i < shuffle_len; i++) { + res |= (in & 1) << *shuffle--; + in >>= 1; + } + return res; +} + +static uint32_t f_func(uint32_t r, uint64_t k) +{ + int i; + uint32_t out = 0; + // rotate to get first part of E-shuffle in the lowest 6 bits + r = (r << 1) | (r >> 31); + // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits + for (i = 7; i >= 0; i--) { + uint8_t tmp = (r ^ k) & 0x3f; +#if CONFIG_SMALL + uint8_t v = S_boxes[i][tmp >> 1]; + if (tmp & 1) + v >>= 4; + out = (out >> 4) | (v << 28); +#else + out |= S_boxes_P_shuffle[i][tmp]; +#endif + // get next 6 bits of E-shuffle and round key k into the lowest bits + r = (r >> 4) | (r << 28); + k >>= 6; + } +#if CONFIG_SMALL + out = shuffle(out, P_shuffle, sizeof(P_shuffle)); +#endif + return out; +} + +/** + * @brief rotate the two halves of the expanded 56 bit key each 1 bit left + * + * Note: the specification calls this "shift", so I kept it although + * it is confusing. + */ +static uint64_t key_shift_left(uint64_t CDn) +{ + uint64_t carries = (CDn >> 27) & 0x10000001; + CDn <<= 1; + CDn &= ~0x10000001; + CDn |= carries; + return CDn; +} + +static void gen_roundkeys(uint64_t K[16], uint64_t key) +{ + int i; + // discard parity bits from key and shuffle it into C and D parts + uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); + // generate round keys + for (i = 0; i < 16; i++) { + CDn = key_shift_left(CDn); + if (i > 1 && i != 8 && i != 15) + CDn = key_shift_left(CDn); + K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle)); + } +} + +static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) +{ + int i; + // used to apply round keys in reverse order for decryption + decrypt = decrypt ? 15 : 0; + // shuffle irrelevant to security but to ease hardware implementations + in = shuffle(in, IP_shuffle, sizeof(IP_shuffle)); + for (i = 0; i < 16; i++) { + uint32_t f_res; + f_res = f_func(in, K[decrypt ^ i]); + in = (in << 32) | (in >> 32); + in ^= f_res; + } + in = (in << 32) | (in >> 32); + // reverse shuffle used to ease hardware implementations + in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle)); + return in; +} + +AVDES *av_des_alloc(void) +{ + return av_mallocz(sizeof(struct AVDES)); +} + +int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt) { + if (key_bits != 64 && key_bits != 192) + return AVERROR(EINVAL); + d->triple_des = key_bits > 64; + gen_roundkeys(d->round_keys[0], AV_RB64(key)); + if (d->triple_des) { + gen_roundkeys(d->round_keys[1], AV_RB64(key + 8)); + gen_roundkeys(d->round_keys[2], AV_RB64(key + 16)); + } + return 0; +} + +static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt, int mac) +{ + uint64_t iv_val = iv ? AV_RB64(iv) : 0; + while (count-- > 0) { + uint64_t dst_val; + uint64_t src_val = src ? AV_RB64(src) : 0; + if (decrypt) { + uint64_t tmp = src_val; + if (d->triple_des) { + src_val = des_encdec(src_val, d->round_keys[2], 1); + src_val = des_encdec(src_val, d->round_keys[1], 0); + } + dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val; + iv_val = iv ? tmp : 0; + } else { + dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0); + if (d->triple_des) { + dst_val = des_encdec(dst_val, d->round_keys[1], 1); + dst_val = des_encdec(dst_val, d->round_keys[2], 0); + } + iv_val = iv ? dst_val : 0; + } + AV_WB64(dst, dst_val); + src += 8; + if (!mac) + dst += 8; + } + if (iv) + AV_WB64(iv, iv_val); +} + +void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0); +} + +void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) +{ + av_des_crypt_mac(d, dst, src, count, (uint8_t[8]) { 0 }, 0, 1); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/des.h b/arm/raspi/third_party/ffmpeg/libavutil/des.h new file mode 100644 index 00000000..3a3e6fa4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/des.h @@ -0,0 +1,81 @@ +/* + * DES encryption/decryption + * Copyright (c) 2007 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DES_H +#define AVUTIL_DES_H + +#include + +/** + * @defgroup lavu_des DES + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVDES { + uint64_t round_keys[3][16]; + int triple_des; +} AVDES; + +/** + * Allocate an AVDES context. + */ +AVDES *av_des_alloc(void); + +/** + * @brief Initializes an AVDES context. + * + * @param d pointer to a AVDES structure to initialize + * @param key pointer to the key to use + * @param key_bits must be 64 or 192 + * @param decrypt 0 for encryption/CBC-MAC, 1 for decryption + * @return zero on success, negative value otherwise + */ +int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the DES algorithm. + * + * @param d pointer to the AVDES structure + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used, + * must be 8-byte aligned + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @brief Calculates CBC-MAC using the DES algorithm. + * + * @param d pointer to the AVDES structure + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + * @param count number of 8 byte blocks + */ +void av_des_mac(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count); + +/** + * @} + */ + +#endif /* AVUTIL_DES_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.c b/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.c new file mode 100644 index 00000000..bae8f064 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.c @@ -0,0 +1,72 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "detection_bbox.h" + +AVDetectionBBoxHeader *av_detection_bbox_alloc(uint32_t nb_bboxes, size_t *out_size) +{ + size_t size; + struct BBoxContext { + AVDetectionBBoxHeader header; + AVDetectionBBox boxes; + }; + const size_t bboxes_offset = offsetof(struct BBoxContext, boxes); + const size_t bbox_size = sizeof(AVDetectionBBox); + AVDetectionBBoxHeader *header; + + size = bboxes_offset; + if (nb_bboxes > (SIZE_MAX - size) / bbox_size) + return NULL; + size += bbox_size * nb_bboxes; + + header = av_mallocz(size); + if (!header) + return NULL; + + header->nb_bboxes = nb_bboxes; + header->bbox_size = bbox_size; + header->bboxes_offset = bboxes_offset; + + if (out_size) + *out_size = size; + + return header; +} + +AVDetectionBBoxHeader *av_detection_bbox_create_side_data(AVFrame *frame, uint32_t nb_bboxes) +{ + AVBufferRef *buf; + AVDetectionBBoxHeader *header; + size_t size; + + header = av_detection_bbox_alloc(nb_bboxes, &size); + if (!header) + return NULL; + buf = av_buffer_create((uint8_t *)header, size, NULL, NULL, 0); + if (!buf) { + av_freep(&header); + return NULL; + } + + if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DETECTION_BBOXES, buf)) { + av_buffer_unref(&buf); + return NULL; + } + + return header; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.h b/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.h new file mode 100644 index 00000000..01198805 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/detection_bbox.h @@ -0,0 +1,108 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DETECTION_BBOX_H +#define AVUTIL_DETECTION_BBOX_H + +#include "rational.h" +#include "avassert.h" +#include "frame.h" + +typedef struct AVDetectionBBox { + /** + * Distance in pixels from the left/top edge of the frame, + * together with width and height, defining the bounding box. + */ + int x; + int y; + int w; + int h; + +#define AV_DETECTION_BBOX_LABEL_NAME_MAX_SIZE 64 + + /** + * Detect result with confidence + */ + char detect_label[AV_DETECTION_BBOX_LABEL_NAME_MAX_SIZE]; + AVRational detect_confidence; + + /** + * At most 4 classifications based on the detected bounding box. + * For example, we can get max 4 different attributes with 4 different + * DNN models on one bounding box. + * classify_count is zero if no classification. + */ +#define AV_NUM_DETECTION_BBOX_CLASSIFY 4 + uint32_t classify_count; + char classify_labels[AV_NUM_DETECTION_BBOX_CLASSIFY][AV_DETECTION_BBOX_LABEL_NAME_MAX_SIZE]; + AVRational classify_confidences[AV_NUM_DETECTION_BBOX_CLASSIFY]; +} AVDetectionBBox; + +typedef struct AVDetectionBBoxHeader { + /** + * Information about how the bounding box is generated. + * for example, the DNN model name. + */ + char source[256]; + + /** + * Number of bounding boxes in the array. + */ + uint32_t nb_bboxes; + + /** + * Offset in bytes from the beginning of this structure at which + * the array of bounding boxes starts. + */ + size_t bboxes_offset; + + /** + * Size of each bounding box in bytes. + */ + size_t bbox_size; +} AVDetectionBBoxHeader; + +/* + * Get the bounding box at the specified {@code idx}. Must be between 0 and nb_bboxes. + */ +static av_always_inline AVDetectionBBox * +av_get_detection_bbox(const AVDetectionBBoxHeader *header, unsigned int idx) +{ + av_assert0(idx < header->nb_bboxes); + return (AVDetectionBBox *)((uint8_t *)header + header->bboxes_offset + + idx * header->bbox_size); +} + +/** + * Allocates memory for AVDetectionBBoxHeader, plus an array of {@code nb_bboxes} + * AVDetectionBBox, and initializes the variables. + * Can be freed with a normal av_free() call. + * + * @param nb_bboxes number of AVDetectionBBox structures to allocate + * @param out_size if non-NULL, the size in bytes of the resulting data array is + * written here. + */ +AVDetectionBBoxHeader *av_detection_bbox_alloc(uint32_t nb_bboxes, size_t *out_size); + +/** + * Allocates memory for AVDetectionBBoxHeader, plus an array of {@code nb_bboxes} + * AVDetectionBBox, in the given AVFrame {@code frame} as AVFrameSideData of type + * AV_FRAME_DATA_DETECTION_BBOXES and initializes the variables. + */ +AVDetectionBBoxHeader *av_detection_bbox_create_side_data(AVFrame *frame, uint32_t nb_bboxes); +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dict.c b/arm/raspi/third_party/ffmpeg/libavutil/dict.c new file mode 100644 index 00000000..f673977a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dict.c @@ -0,0 +1,292 @@ +/* + * copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avassert.h" +#include "avstring.h" +#include "dict.h" +#include "dict_internal.h" +#include "internal.h" +#include "mem.h" +#include "time_internal.h" +#include "bprint.h" + +struct AVDictionary { + int count; + AVDictionaryEntry *elems; +}; + +int av_dict_count(const AVDictionary *m) +{ + return m ? m->count : 0; +} + +const AVDictionaryEntry *av_dict_iterate(const AVDictionary *m, + const AVDictionaryEntry *prev) +{ + int i = 0; + + if (!m) + return NULL; + + if (prev) + i = prev - m->elems + 1; + + av_assert2(i >= 0); + if (i >= m->count) + return NULL; + + return &m->elems[i]; +} + +AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, + const AVDictionaryEntry *prev, int flags) +{ + const AVDictionaryEntry *entry = prev; + unsigned int j; + + if (!key) + return NULL; + + while ((entry = av_dict_iterate(m, entry))) { + const char *s = entry->key; + if (flags & AV_DICT_MATCH_CASE) + for (j = 0; s[j] == key[j] && key[j]; j++) + ; + else + for (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++) + ; + if (key[j]) + continue; + if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX)) + continue; + return (AVDictionaryEntry *)entry; + } + return NULL; +} + +int av_dict_set(AVDictionary **pm, const char *key, const char *value, + int flags) +{ + AVDictionary *m = *pm; + AVDictionaryEntry *tag = NULL; + char *copy_key = NULL, *copy_value = NULL; + int err; + + if (flags & AV_DICT_DONT_STRDUP_VAL) + copy_value = (void *)value; + else if (value) + copy_value = av_strdup(value); + if (!key) { + err = AVERROR(EINVAL); + goto err_out; + } + if (!(flags & AV_DICT_MULTIKEY)) { + tag = av_dict_get(m, key, NULL, flags); + } + if (flags & AV_DICT_DONT_STRDUP_KEY) + copy_key = (void *)key; + else + copy_key = av_strdup(key); + if (!m) + m = *pm = av_mallocz(sizeof(*m)); + if (!m || !copy_key || (value && !copy_value)) + goto enomem; + + if (tag) { + if (flags & AV_DICT_DONT_OVERWRITE) { + av_free(copy_key); + av_free(copy_value); + return 0; + } + if (copy_value && flags & AV_DICT_APPEND) { + size_t oldlen = strlen(tag->value); + size_t new_part_len = strlen(copy_value); + size_t len = oldlen + new_part_len + 1; + char *newval = av_realloc(tag->value, len); + if (!newval) + goto enomem; + memcpy(newval + oldlen, copy_value, new_part_len + 1); + av_freep(©_value); + copy_value = newval; + } else + av_free(tag->value); + av_free(tag->key); + *tag = m->elems[--m->count]; + } else if (copy_value) { + AVDictionaryEntry *tmp = av_realloc_array(m->elems, + m->count + 1, sizeof(*m->elems)); + if (!tmp) + goto enomem; + m->elems = tmp; + } + if (copy_value) { + m->elems[m->count].key = copy_key; + m->elems[m->count].value = copy_value; + m->count++; + } else { + if (!m->count) { + av_freep(&m->elems); + av_freep(pm); + } + av_freep(©_key); + } + + return 0; + +enomem: + err = AVERROR(ENOMEM); +err_out: + if (m && !m->count) { + av_freep(&m->elems); + av_freep(pm); + } + av_free(copy_key); + av_free(copy_value); + return err; +} + +int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, + int flags) +{ + char valuestr[22]; + snprintf(valuestr, sizeof(valuestr), "%"PRId64, value); + flags &= ~AV_DICT_DONT_STRDUP_VAL; + return av_dict_set(pm, key, valuestr, flags); +} + +static int parse_key_value_pair(AVDictionary **pm, const char **buf, + const char *key_val_sep, const char *pairs_sep, + int flags) +{ + char *key = av_get_token(buf, key_val_sep); + char *val = NULL; + int ret; + + if (key && *key && strspn(*buf, key_val_sep)) { + (*buf)++; + val = av_get_token(buf, pairs_sep); + } + + if (key && *key && val && *val) + ret = av_dict_set(pm, key, val, flags); + else + ret = AVERROR(EINVAL); + + av_freep(&key); + av_freep(&val); + + return ret; +} + +int av_dict_parse_string(AVDictionary **pm, const char *str, + const char *key_val_sep, const char *pairs_sep, + int flags) +{ + int ret; + + if (!str) + return 0; + + /* ignore STRDUP flags */ + flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + + while (*str) { + if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0) + return ret; + + if (*str) + str++; + } + + return 0; +} + +void av_dict_free(AVDictionary **pm) +{ + AVDictionary *m = *pm; + + if (m) { + while (m->count--) { + av_freep(&m->elems[m->count].key); + av_freep(&m->elems[m->count].value); + } + av_freep(&m->elems); + } + av_freep(pm); +} + +int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags) +{ + const AVDictionaryEntry *t = NULL; + + while ((t = av_dict_iterate(src, t))) { + int ret = av_dict_set(dst, t->key, t->value, flags); + if (ret < 0) + return ret; + } + + return 0; +} + +int av_dict_get_string(const AVDictionary *m, char **buffer, + const char key_val_sep, const char pairs_sep) +{ + const AVDictionaryEntry *t = NULL; + AVBPrint bprint; + int cnt = 0; + char special_chars[] = {pairs_sep, key_val_sep, '\0'}; + + if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || + pairs_sep == '\\' || key_val_sep == '\\') + return AVERROR(EINVAL); + + if (!av_dict_count(m)) { + *buffer = av_strdup(""); + return *buffer ? 0 : AVERROR(ENOMEM); + } + + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + while ((t = av_dict_iterate(m, t))) { + if (cnt++) + av_bprint_append_data(&bprint, &pairs_sep, 1); + av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_bprint_append_data(&bprint, &key_val_sep, 1); + av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + } + return av_bprint_finalize(&bprint, buffer); +} + +int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp) +{ + time_t seconds = timestamp / 1000000; + struct tm *ptm, tmbuf; + ptm = gmtime_r(&seconds, &tmbuf); + if (ptm) { + char buf[32]; + if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm)) + return AVERROR_EXTERNAL; + av_strlcatf(buf, sizeof(buf), ".%06dZ", (int)(timestamp % 1000000)); + return av_dict_set(dict, key, buf, 0); + } else { + return AVERROR_EXTERNAL; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dict.h b/arm/raspi/third_party/ffmpeg/libavutil/dict.h new file mode 100644 index 00000000..713c9e36 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dict.h @@ -0,0 +1,241 @@ +/* + * 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 + * Public dictionary API. + * @deprecated + * AVDictionary is provided for compatibility with libav. It is both in + * implementation as well as API inefficient. It does not scale and is + * extremely slow with large dictionaries. + * It is recommended that new code uses our tree container from tree.c/h + * where applicable, which uses AVL trees to achieve O(log n) performance. + */ + +#ifndef AVUTIL_DICT_H +#define AVUTIL_DICT_H + +#include + +/** + * @addtogroup lavu_dict AVDictionary + * @ingroup lavu_data + * + * @brief Simple key:value store + * + * @{ + * Dictionaries are used for storing key-value pairs. + * + * - To **create an AVDictionary**, simply pass an address of a NULL + * pointer to av_dict_set(). NULL can be used as an empty dictionary + * wherever a pointer to an AVDictionary is required. + * - To **insert an entry**, use av_dict_set(). + * - Use av_dict_get() to **retrieve an entry**. + * - To **iterate over all entries**, use av_dict_iterate(). + * - In order to **free the dictionary and all its contents**, use av_dict_free(). + * + @code + AVDictionary *d = NULL; // "create" an empty dictionary + AVDictionaryEntry *t = NULL; + + av_dict_set(&d, "foo", "bar", 0); // add an entry + + char *k = av_strdup("key"); // if your strings are already allocated, + char *v = av_strdup("value"); // you can avoid copying them like this + av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + + while ((t = av_dict_iterate(d, t))) { + <....> // iterate over all entries in d + } + av_dict_free(&d); + @endcode + */ + +/** + * @name AVDictionary Flags + * Flags that influence behavior of the matching of keys or insertion to the dictionary. + * @{ + */ +#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */ +#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key, + ignoring the suffix of the found key string. Only relevant in av_dict_get(). */ +#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_OVERWRITE 16 /**< Don't overwrite existing entries. */ +#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no + delimiter is added, the strings are simply concatenated. */ +#define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */ +/** + * @} + */ + +typedef struct AVDictionaryEntry { + char *key; + char *value; +} AVDictionaryEntry; + +typedef struct AVDictionary AVDictionary; + +/** + * Get a dictionary entry with matching key. + * + * The returned entry key or value must not be changed, or it will + * cause undefined behavior. + * + * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. + * @param key Matching key + * @param flags A collection of AV_DICT_* flags controlling how the + * entry is retrieved + * + * @return Found entry or NULL in case no matching entry was found in the dictionary + */ +AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, + const AVDictionaryEntry *prev, int flags); + +/** + * Iterate over a dictionary + * + * Iterates through all entries in the dictionary. + * + * @warning The returned AVDictionaryEntry key/value must not be changed. + * + * @warning As av_dict_set() invalidates all previous entries returned + * by this function, it must not be called while iterating over the dict. + * + * Typical usage: + * @code + * const AVDictionaryEntry *e = NULL; + * while ((e = av_dict_iterate(m, e))) { + * // ... + * } + * @endcode + * + * @param m The dictionary to iterate over + * @param prev Pointer to the previous AVDictionaryEntry, NULL initially + * + * @retval AVDictionaryEntry* The next element in the dictionary + * @retval NULL No more elements in the dictionary + */ +const AVDictionaryEntry *av_dict_iterate(const AVDictionary *m, + const AVDictionaryEntry *prev); + +/** + * Get number of entries in dictionary. + * + * @param m dictionary + * @return number of entries in dictionary + */ +int av_dict_count(const AVDictionary *m); + +/** + * Set the given entry in *pm, overwriting an existing entry. + * + * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, + * these arguments will be freed on error. + * + * @warning Adding a new entry to a dictionary invalidates all existing entries + * previously returned with av_dict_get() or av_dict_iterate(). + * + * @param pm Pointer to a pointer to a dictionary struct. If *pm is NULL + * a dictionary struct is allocated and put in *pm. + * @param key Entry key to add to *pm (will either be av_strduped or added as a new key depending on flags) + * @param value Entry value to add to *pm (will be av_strduped or added as a new key depending on flags). + * Passing a NULL value will cause an existing entry to be deleted. + * + * @return >= 0 on success otherwise an error code <0 + */ +int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); + +/** + * Convenience wrapper for av_dict_set() that converts the value to a string + * and stores it. + * + * Note: If ::AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error. + */ +int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags); + +/** + * Parse the key/value pairs list and add the parsed entries to a dictionary. + * + * In case of failure, all the successfully set entries are stored in + * *pm. You may need to manually free the created dictionary. + * + * @param key_val_sep A 0-terminated list of characters used to separate + * key from value + * @param pairs_sep A 0-terminated list of characters used to separate + * two pairs from each other + * @param flags Flags to use when adding to the dictionary. + * ::AV_DICT_DONT_STRDUP_KEY and ::AV_DICT_DONT_STRDUP_VAL + * are ignored since the key/value tokens will always + * be duplicated. + * + * @return 0 on success, negative AVERROR code on failure + */ +int av_dict_parse_string(AVDictionary **pm, const char *str, + const char *key_val_sep, const char *pairs_sep, + int flags); + +/** + * Copy entries from one AVDictionary struct into another. + * + * @note Metadata is read using the ::AV_DICT_IGNORE_SUFFIX flag + * + * @param dst Pointer to a pointer to a AVDictionary struct to copy into. If *dst is NULL, + * this function will allocate a struct for you and put it in *dst + * @param src Pointer to the source AVDictionary struct to copy items from. + * @param flags Flags to use when setting entries in *dst + * + * @return 0 on success, negative AVERROR code on failure. If dst was allocated + * by this function, callers should free the associated memory. + */ +int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags); + +/** + * Free all the memory allocated for an AVDictionary struct + * and all keys and values. + */ +void av_dict_free(AVDictionary **m); + +/** + * Get dictionary entries as a string. + * + * Create a string containing dictionary's entries. + * Such string may be passed back to av_dict_parse_string(). + * @note String is escaped with backslashes ('\'). + * + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + * + * @param[in] m The dictionary + * @param[out] buffer Pointer to buffer that will be allocated with string containg entries. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep Character used to separate key from value + * @param[in] pairs_sep Character used to separate two pairs from each other + * + * @return >= 0 on success, negative on error + */ +int av_dict_get_string(const AVDictionary *m, char **buffer, + const char key_val_sep, const char pairs_sep); + +/** + * @} + */ + +#endif /* AVUTIL_DICT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dict_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/dict_internal.h new file mode 100644 index 00000000..6d5b0dc2 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dict_internal.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DICT_INTERNAL_H +#define AVUTIL_DICT_INTERNAL_H + +#include + +#include "dict.h" + +/** + * Set a dictionary value to an ISO-8601 compliant timestamp string. + * + * @param dict pointer to a pointer to a dictionary struct. If *dict is NULL + * a dictionary struct is allocated and put in *dict. + * @param key metadata key + * @param timestamp unix timestamp in microseconds + * @return <0 on error + */ +int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp); + +#endif /* AVUTIL_DICT_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/display.c b/arm/raspi/third_party/ffmpeg/libavutil/display.c new file mode 100644 index 00000000..d3106128 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/display.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "display.h" +#include "libm.h" +#include "mathematics.h" + +// fixed point to double +#define CONV_FP(x) ((double) (x)) / (1 << 16) + +// double to fixed point +#define CONV_DB(x) (int32_t) ((x) * (1 << 16)) + +double av_display_rotation_get(const int32_t matrix[9]) +{ + double rotation, scale[2]; + + scale[0] = hypot(CONV_FP(matrix[0]), CONV_FP(matrix[3])); + scale[1] = hypot(CONV_FP(matrix[1]), CONV_FP(matrix[4])); + + if (scale[0] == 0.0 || scale[1] == 0.0) + return NAN; + + rotation = atan2(CONV_FP(matrix[1]) / scale[1], + CONV_FP(matrix[0]) / scale[0]) * 180 / M_PI; + + return -rotation; +} + +void av_display_rotation_set(int32_t matrix[9], double angle) +{ + double radians = -angle * M_PI / 180.0f; + double c = cos(radians); + double s = sin(radians); + + memset(matrix, 0, 9 * sizeof(int32_t)); + + matrix[0] = CONV_DB(c); + matrix[1] = CONV_DB(-s); + matrix[3] = CONV_DB(s); + matrix[4] = CONV_DB(c); + matrix[8] = 1 << 30; +} + +void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip) +{ + int i; + const int flip[] = { 1 - 2 * (!!hflip), 1 - 2 * (!!vflip), 1 }; + + if (hflip || vflip) + for (i = 0; i < 9; i++) + matrix[i] *= flip[i % 3]; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/display.h b/arm/raspi/third_party/ffmpeg/libavutil/display.h new file mode 100644 index 00000000..50f2b44c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/display.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_video_display + * Display matrix + */ + +#ifndef AVUTIL_DISPLAY_H +#define AVUTIL_DISPLAY_H + +#include + +/** + * @defgroup lavu_video_display Display transformation matrix functions + * @ingroup lavu_video + * + * The display transformation matrix specifies an affine transformation that + * should be applied to video frames for correct presentation. It is compatible + * with the matrices stored in the ISO/IEC 14496-12 container format. + * + * The data is a 3x3 matrix represented as a 9-element array: + * + * @code{.unparsed} + * | a b u | + * (a, b, u, c, d, v, x, y, w) -> | c d v | + * | x y w | + * @endcode + * + * All numbers are stored in native endianness, as 16.16 fixed-point values, + * except for u, v and w, which are stored as 2.30 fixed-point values. + * + * The transformation maps a point (p, q) in the source (pre-transformation) + * frame to the point (p', q') in the destination (post-transformation) frame as + * follows: + * + * @code{.unparsed} + * | a b u | + * (p, q, 1) . | c d v | = z * (p', q', 1) + * | x y w | + * @endcode + * + * The transformation can also be more explicitly written in components as + * follows: + * + * @code{.unparsed} + * p' = (a * p + c * q + x) / z; + * q' = (b * p + d * q + y) / z; + * z = u * p + v * q + w + * @endcode + * + * @{ + */ + +/** + * Extract the rotation component of the transformation matrix. + * + * @param matrix the transformation matrix + * @return the angle (in degrees) by which the transformation rotates the frame + * counterclockwise. The angle will be in range [-180.0, 180.0], + * or NaN if the matrix is singular. + * + * @note floating point numbers are inherently inexact, so callers are + * recommended to round the return value to nearest integer before use. + */ +double av_display_rotation_get(const int32_t matrix[9]); + +/** + * Initialize a transformation matrix describing a pure clockwise + * rotation by the specified angle (in degrees). + * + * @param[out] matrix a transformation matrix (will be fully overwritten + * by this function) + * @param angle rotation angle in degrees. + */ +void av_display_rotation_set(int32_t matrix[9], double angle); + +/** + * Flip the input matrix horizontally and/or vertically. + * + * @param[in,out] matrix a transformation matrix + * @param hflip whether the matrix should be flipped horizontally + * @param vflip whether the matrix should be flipped vertically + */ +void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip); + +/** + * @} + */ + +#endif /* AVUTIL_DISPLAY_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.c b/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.c new file mode 100644 index 00000000..9c50da56 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 Jun Zhao + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "dovi_meta.h" +#include "mem.h" + +AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size) +{ + AVDOVIDecoderConfigurationRecord *dovi = + av_mallocz(sizeof(AVDOVIDecoderConfigurationRecord)); + if (!dovi) + return NULL; + + if (size) + *size = sizeof(*dovi); + + return dovi; +} + +typedef struct AVDOVIMetadataInternal { + AVDOVIMetadata metadata; + AVDOVIRpuDataHeader header; + AVDOVIDataMapping mapping; + AVDOVIColorMetadata color; +} AVDOVIMetadataInternal; + +AVDOVIMetadata *av_dovi_metadata_alloc(size_t *size) +{ + AVDOVIMetadataInternal *dovi = av_mallocz(sizeof(AVDOVIMetadataInternal)); + if (!dovi) + return NULL; + + if (size) + *size = sizeof(*dovi); + + dovi->metadata = (struct AVDOVIMetadata) { + .header_offset = offsetof(AVDOVIMetadataInternal, header), + .mapping_offset = offsetof(AVDOVIMetadataInternal, mapping), + .color_offset = offsetof(AVDOVIMetadataInternal, color), + }; + + return &dovi->metadata; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.h b/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.h new file mode 100644 index 00000000..3d11e02b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dovi_meta.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2020 Vacing Fang + * + * 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 + * DOVI configuration + */ + + +#ifndef AVUTIL_DOVI_META_H +#define AVUTIL_DOVI_META_H + +#include +#include +#include "rational.h" + +/* + * DOVI configuration + * ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.1.2 + dolby-vision-bitstreams-in-mpeg-2-transport-stream-multiplex-v1.2 + * @code + * uint8_t dv_version_major, the major version number that the stream complies with + * uint8_t dv_version_minor, the minor version number that the stream complies with + * uint8_t dv_profile, the Dolby Vision profile + * uint8_t dv_level, the Dolby Vision level + * uint8_t rpu_present_flag + * uint8_t el_present_flag + * uint8_t bl_present_flag + * uint8_t dv_bl_signal_compatibility_id + * @endcode + * + * @note The struct must be allocated with av_dovi_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVDOVIDecoderConfigurationRecord { + uint8_t dv_version_major; + uint8_t dv_version_minor; + uint8_t dv_profile; + uint8_t dv_level; + uint8_t rpu_present_flag; + uint8_t el_present_flag; + uint8_t bl_present_flag; + uint8_t dv_bl_signal_compatibility_id; +} AVDOVIDecoderConfigurationRecord; + +/** + * Allocate a AVDOVIDecoderConfigurationRecord structure and initialize its + * fields to default values. + * + * @return the newly allocated struct or NULL on failure + */ +AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size); + +/** + * Dolby Vision RPU data header. + * + * @note sizeof(AVDOVIRpuDataHeader) is not part of the public ABI. + */ +typedef struct AVDOVIRpuDataHeader { + uint8_t rpu_type; + uint16_t rpu_format; + uint8_t vdr_rpu_profile; + uint8_t vdr_rpu_level; + uint8_t chroma_resampling_explicit_filter_flag; + uint8_t coef_data_type; /* informative, lavc always converts to fixed */ + uint8_t coef_log2_denom; + uint8_t vdr_rpu_normalized_idc; + uint8_t bl_video_full_range_flag; + uint8_t bl_bit_depth; /* [8, 16] */ + uint8_t el_bit_depth; /* [8, 16] */ + uint8_t vdr_bit_depth; /* [8, 16] */ + uint8_t spatial_resampling_filter_flag; + uint8_t el_spatial_resampling_filter_flag; + uint8_t disable_residual_flag; +} AVDOVIRpuDataHeader; + +enum AVDOVIMappingMethod { + AV_DOVI_MAPPING_POLYNOMIAL = 0, + AV_DOVI_MAPPING_MMR = 1, +}; + +/** + * Coefficients of a piece-wise function. The pieces of the function span the + * value ranges between two adjacent pivot values. + */ +#define AV_DOVI_MAX_PIECES 8 +typedef struct AVDOVIReshapingCurve { + uint8_t num_pivots; /* [2, 9] */ + uint16_t pivots[AV_DOVI_MAX_PIECES + 1]; /* sorted ascending */ + enum AVDOVIMappingMethod mapping_idc[AV_DOVI_MAX_PIECES]; + /* AV_DOVI_MAPPING_POLYNOMIAL */ + uint8_t poly_order[AV_DOVI_MAX_PIECES]; /* [1, 2] */ + int64_t poly_coef[AV_DOVI_MAX_PIECES][3]; /* x^0, x^1, x^2 */ + /* AV_DOVI_MAPPING_MMR */ + uint8_t mmr_order[AV_DOVI_MAX_PIECES]; /* [1, 3] */ + int64_t mmr_constant[AV_DOVI_MAX_PIECES]; + int64_t mmr_coef[AV_DOVI_MAX_PIECES][3/* order - 1 */][7]; +} AVDOVIReshapingCurve; + +enum AVDOVINLQMethod { + AV_DOVI_NLQ_NONE = -1, + AV_DOVI_NLQ_LINEAR_DZ = 0, +}; + +/** + * Coefficients of the non-linear inverse quantization. For the interpretation + * of these, see ETSI GS CCM 001. + */ +typedef struct AVDOVINLQParams { + uint16_t nlq_offset; + uint64_t vdr_in_max; + /* AV_DOVI_NLQ_LINEAR_DZ */ + uint64_t linear_deadzone_slope; + uint64_t linear_deadzone_threshold; +} AVDOVINLQParams; + +/** + * Dolby Vision RPU data mapping parameters. + * + * @note sizeof(AVDOVIDataMapping) is not part of the public ABI. + */ +typedef struct AVDOVIDataMapping { + uint8_t vdr_rpu_id; + uint8_t mapping_color_space; + uint8_t mapping_chroma_format_idc; + AVDOVIReshapingCurve curves[3]; /* per component */ + + /* Non-linear inverse quantization */ + enum AVDOVINLQMethod nlq_method_idc; + uint32_t num_x_partitions; + uint32_t num_y_partitions; + AVDOVINLQParams nlq[3]; /* per component */ +} AVDOVIDataMapping; + +/** + * Dolby Vision RPU colorspace metadata parameters. + * + * @note sizeof(AVDOVIColorMetadata) is not part of the public ABI. + */ +typedef struct AVDOVIColorMetadata { + uint8_t dm_metadata_id; + uint8_t scene_refresh_flag; + + /** + * Coefficients of the custom Dolby Vision IPT-PQ matrices. These are to be + * used instead of the matrices indicated by the frame's colorspace tags. + * The output of rgb_to_lms_matrix is to be fed into a BT.2020 LMS->RGB + * matrix based on a Hunt-Pointer-Estevez transform, but without any + * crosstalk. (See the definition of the ICtCp colorspace for more + * information.) + */ + AVRational ycc_to_rgb_matrix[9]; /* before PQ linearization */ + AVRational ycc_to_rgb_offset[3]; /* input offset of neutral value */ + AVRational rgb_to_lms_matrix[9]; /* after PQ linearization */ + + /** + * Extra signal metadata (see Dolby patents for more info). + */ + uint16_t signal_eotf; + uint16_t signal_eotf_param0; + uint16_t signal_eotf_param1; + uint32_t signal_eotf_param2; + uint8_t signal_bit_depth; + uint8_t signal_color_space; + uint8_t signal_chroma_format; + uint8_t signal_full_range_flag; /* [0, 3] */ + uint16_t source_min_pq; + uint16_t source_max_pq; + uint16_t source_diagonal; +} AVDOVIColorMetadata; + +/** + * Combined struct representing a combination of header, mapping and color + * metadata, for attaching to frames as side data. + * + * @note The struct must be allocated with av_dovi_metadata_alloc() and + * its size is not a part of the public ABI. + */ + +typedef struct AVDOVIMetadata { + /** + * Offset in bytes from the beginning of this structure at which the + * respective structs start. + */ + size_t header_offset; /* AVDOVIRpuDataHeader */ + size_t mapping_offset; /* AVDOVIDataMapping */ + size_t color_offset; /* AVDOVIColorMetadata */ +} AVDOVIMetadata; + +static av_always_inline AVDOVIRpuDataHeader * +av_dovi_get_header(const AVDOVIMetadata *data) +{ + return (AVDOVIRpuDataHeader *)((uint8_t *) data + data->header_offset); +} + +static av_always_inline AVDOVIDataMapping * +av_dovi_get_mapping(const AVDOVIMetadata *data) +{ + return (AVDOVIDataMapping *)((uint8_t *) data + data->mapping_offset); +} + +static av_always_inline AVDOVIColorMetadata * +av_dovi_get_color(const AVDOVIMetadata *data) +{ + return (AVDOVIColorMetadata *)((uint8_t *) data + data->color_offset); +} + +/** + * Allocate an AVDOVIMetadata structure and initialize its + * fields to default values. + * + * @param size If this parameter is non-NULL, the size in bytes of the + * allocated struct will be written here on success + * + * @return the newly allocated struct or NULL on failure + */ +AVDOVIMetadata *av_dovi_metadata_alloc(size_t *size); + +#endif /* AVUTIL_DOVI_META_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.c b/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.c new file mode 100644 index 00000000..c634c6a7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "downmix_info.h" +#include "frame.h" + +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data; + + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO); + + if (!side_data) + side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO, + sizeof(AVDownmixInfo)); + + if (!side_data) + return NULL; + + return (AVDownmixInfo*)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.h b/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.h new file mode 100644 index 00000000..221cf5bf --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/downmix_info.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DOWNMIX_INFO_H +#define AVUTIL_DOWNMIX_INFO_H + +#include "frame.h" + +/** + * @file + * audio downmix medatata + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup downmix_info Audio downmix metadata + * @{ + */ + +/** + * Possible downmix types. + */ +enum AVDownmixType { + AV_DOWNMIX_TYPE_UNKNOWN, /**< Not indicated. */ + AV_DOWNMIX_TYPE_LORO, /**< Lo/Ro 2-channel downmix (Stereo). */ + AV_DOWNMIX_TYPE_LTRT, /**< Lt/Rt 2-channel downmix, Dolby Surround compatible. */ + AV_DOWNMIX_TYPE_DPLII, /**< Lt/Rt 2-channel downmix, Dolby Pro Logic II compatible. */ + AV_DOWNMIX_TYPE_NB /**< Number of downmix types. Not part of ABI. */ +}; + +/** + * This structure describes optional metadata relevant to a downmix procedure. + * + * All fields are set by the decoder to the value indicated in the audio + * bitstream (if present), or to a "sane" default otherwise. + */ +typedef struct AVDownmixInfo { + /** + * Type of downmix preferred by the mastering engineer. + */ + enum AVDownmixType preferred_downmix_type; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during a regular downmix. + */ + double center_mix_level; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during an Lt/Rt compatible downmix. + */ + double center_mix_level_ltrt; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during a regular downmix. + */ + double surround_mix_level; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during an Lt/Rt compatible downmix. + */ + double surround_mix_level_ltrt; + + /** + * Absolute scale factor representing the level at which the LFE data is + * mixed into L/R channels during downmixing. + */ + double lfe_mix_level; +} AVDownmixInfo; + +/** + * Get a frame's AV_FRAME_DATA_DOWNMIX_INFO side data for editing. + * + * If the side data is absent, it is created and added to the frame. + * + * @param frame the frame for which the side data is to be obtained or created + * + * @return the AVDownmixInfo structure to be edited by the caller, or NULL if + * the structure cannot be allocated. + */ +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame); + +/** + * @} + */ + +/** + * @} + */ + +#endif /* AVUTIL_DOWNMIX_INFO_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/dynarray.h b/arm/raspi/third_party/ffmpeg/libavutil/dynarray.h new file mode 100644 index 00000000..3a7e1464 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/dynarray.h @@ -0,0 +1,70 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DYNARRAY_H +#define AVUTIL_DYNARRAY_H + +#include "log.h" +#include "mem.h" + +/** + * Add an element to a dynamic array. + * + * The array is reallocated when its number of elements reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the size is incremented. + * + * @param av_size_max maximum size of the array, usually the MAX macro of + * the type of the size + * @param av_elt_size size of the elements in the array, in bytes + * @param av_array pointer to the array, must be a lvalue + * @param av_size size of the array, must be an integer lvalue + * @param av_success statement to execute on success; at this point, the + * size variable is not yet incremented + * @param av_failure statement to execute on failure; if this happens, the + * array and size are not changed; the statement can end + * with a return or a goto + */ +#define FF_DYNARRAY_ADD(av_size_max, av_elt_size, av_array, av_size, \ + av_success, av_failure) \ + do { \ + size_t av_size_new = (av_size); \ + if (!((av_size) & ((av_size) - 1))) { \ + av_size_new = (av_size) ? (av_size) << 1 : 1; \ + if (av_size_new > (av_size_max) / (av_elt_size)) { \ + av_size_new = 0; \ + } else { \ + void *av_array_new = \ + av_realloc((av_array), av_size_new * (av_elt_size)); \ + if (!av_array_new) \ + av_size_new = 0; \ + else \ + (av_array) = av_array_new; \ + } \ + } \ + if (av_size_new) { \ + { av_success } \ + (av_size)++; \ + } else { \ + av_failure \ + } \ + } while (0) + +#endif /* AVUTIL_DYNARRAY_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.c b/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.c new file mode 100644 index 00000000..be7ce38e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.c @@ -0,0 +1,344 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "encryption_info.h" +#include "mem.h" +#include "intreadwrite.h" + +#define FF_ENCRYPTION_INFO_EXTRA 24 + +// The format of the AVEncryptionInfo side data: +// u32be scheme +// u32be crypt_byte_block +// u32be skip_byte_block +// u32be key_id_size +// u32be iv_size +// u32be subsample_count +// u8[key_id_size] key_id +// u8[iv_size] iv +// { +// u32be bytes_of_clear_data +// u32be bytes_of_protected_data +// }[subsample_count] + +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size) +{ + AVEncryptionInfo *info; + + info = av_mallocz(sizeof(*info)); + if (!info) + return NULL; + + info->key_id = av_mallocz(key_id_size); + info->key_id_size = key_id_size; + info->iv = av_mallocz(iv_size); + info->iv_size = iv_size; + info->subsamples = av_calloc(subsample_count, sizeof(*info->subsamples)); + info->subsample_count = subsample_count; + + // Allow info->subsamples to be NULL if there are no subsamples. + if (!info->key_id || !info->iv || (!info->subsamples && subsample_count)) { + av_encryption_info_free(info); + return NULL; + } + + return info; +} + +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info) +{ + AVEncryptionInfo *ret; + + if (!info) + return NULL; + + ret = av_encryption_info_alloc(info->subsample_count, info->key_id_size, info->iv_size); + if (!ret) + return NULL; + + ret->scheme = info->scheme; + ret->crypt_byte_block = info->crypt_byte_block; + ret->skip_byte_block = info->skip_byte_block; + memcpy(ret->iv, info->iv, info->iv_size); + memcpy(ret->key_id, info->key_id, info->key_id_size); + memcpy(ret->subsamples, info->subsamples, sizeof(*info->subsamples) * info->subsample_count); + return ret; +} + +void av_encryption_info_free(AVEncryptionInfo *info) +{ + if (info) { + av_free(info->key_id); + av_free(info->iv); + av_free(info->subsamples); + av_free(info); + } +} + +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t* buffer, size_t size) +{ + AVEncryptionInfo *info; + uint64_t key_id_size, iv_size, subsample_count, i; + + if (!buffer || size < FF_ENCRYPTION_INFO_EXTRA) + return NULL; + + key_id_size = AV_RB32(buffer + 12); + iv_size = AV_RB32(buffer + 16); + subsample_count = AV_RB32(buffer + 20); + + if (size < FF_ENCRYPTION_INFO_EXTRA + key_id_size + iv_size + subsample_count * 8) + return NULL; + + info = av_encryption_info_alloc(subsample_count, key_id_size, iv_size); + if (!info) + return NULL; + + info->scheme = AV_RB32(buffer); + info->crypt_byte_block = AV_RB32(buffer + 4); + info->skip_byte_block = AV_RB32(buffer + 8); + memcpy(info->key_id, buffer + 24, key_id_size); + memcpy(info->iv, buffer + key_id_size + 24, iv_size); + + buffer += key_id_size + iv_size + 24; + for (i = 0; i < subsample_count; i++) { + info->subsamples[i].bytes_of_clear_data = AV_RB32(buffer); + info->subsamples[i].bytes_of_protected_data = AV_RB32(buffer + 4); + buffer += 8; + } + + return info; +} + +uint8_t *av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size) +{ + uint8_t *buffer, *cur_buffer; + uint32_t i; + + if (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA < info->key_id_size || + UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size < info->iv_size || + (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size - info->iv_size) / 8 < info->subsample_count) { + return NULL; + } + + *size = FF_ENCRYPTION_INFO_EXTRA + info->key_id_size + info->iv_size + + (info->subsample_count * 8); + cur_buffer = buffer = av_malloc(*size); + if (!buffer) + return NULL; + + AV_WB32(cur_buffer, info->scheme); + AV_WB32(cur_buffer + 4, info->crypt_byte_block); + AV_WB32(cur_buffer + 8, info->skip_byte_block); + AV_WB32(cur_buffer + 12, info->key_id_size); + AV_WB32(cur_buffer + 16, info->iv_size); + AV_WB32(cur_buffer + 20, info->subsample_count); + cur_buffer += 24; + memcpy(cur_buffer, info->key_id, info->key_id_size); + cur_buffer += info->key_id_size; + memcpy(cur_buffer, info->iv, info->iv_size); + cur_buffer += info->iv_size; + for (i = 0; i < info->subsample_count; i++) { + AV_WB32(cur_buffer, info->subsamples[i].bytes_of_clear_data); + AV_WB32(cur_buffer + 4, info->subsamples[i].bytes_of_protected_data); + cur_buffer += 8; + } + + return buffer; +} + +// The format of the AVEncryptionInitInfo side data: +// u32be init_info_count +// { +// u32be system_id_size +// u32be num_key_ids +// u32be key_id_size +// u32be data_size +// u8[system_id_size] system_id +// u8[key_id_size][num_key_id] key_ids +// u8[data_size] data +// }[init_info_count] + +#define FF_ENCRYPTION_INIT_INFO_EXTRA 16 + +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size) +{ + AVEncryptionInitInfo *info; + uint32_t i; + + info = av_mallocz(sizeof(*info)); + if (!info) + return NULL; + + info->system_id = av_mallocz(system_id_size); + info->system_id_size = system_id_size; + info->key_ids = key_id_size ? av_calloc(num_key_ids, sizeof(*info->key_ids)) : NULL; + info->num_key_ids = num_key_ids; + info->key_id_size = key_id_size; + info->data = av_mallocz(data_size); + info->data_size = data_size; + + // Allow pointers to be NULL if the size is 0. + if ((!info->system_id && system_id_size) || (!info->data && data_size) || + (!info->key_ids && num_key_ids && key_id_size)) { + av_encryption_init_info_free(info); + return NULL; + } + + if (key_id_size) { + for (i = 0; i < num_key_ids; i++) { + info->key_ids[i] = av_mallocz(key_id_size); + if (!info->key_ids[i]) { + av_encryption_init_info_free(info); + return NULL; + } + } + } + + return info; +} + +void av_encryption_init_info_free(AVEncryptionInitInfo *info) +{ + uint32_t i; + if (info) { + for (i = 0; i < info->num_key_ids; i++) { + av_free(info->key_ids[i]); + } + av_encryption_init_info_free(info->next); + av_free(info->system_id); + av_free(info->key_ids); + av_free(info->data); + av_free(info); + } +} + +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t *side_data, size_t side_data_size) +{ + // |ret| tracks the front of the list, |info| tracks the back. + AVEncryptionInitInfo *ret = NULL, *info, *temp_info; + uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j; + uint64_t init_info_count; + + if (!side_data || side_data_size < 4) + return NULL; + + init_info_count = AV_RB32(side_data); + side_data += 4; + side_data_size -= 4; + for (i = 0; i < init_info_count; i++) { + if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) { + av_encryption_init_info_free(ret); + return NULL; + } + + system_id_size = AV_RB32(side_data); + num_key_ids = AV_RB32(side_data + 4); + key_id_size = AV_RB32(side_data + 8); + data_size = AV_RB32(side_data + 12); + + // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX + if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) { + av_encryption_init_info_free(ret); + return NULL; + } + side_data += FF_ENCRYPTION_INIT_INFO_EXTRA; + side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA; + + temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size); + if (!temp_info) { + av_encryption_init_info_free(ret); + return NULL; + } + if (i == 0) { + info = ret = temp_info; + } else { + info->next = temp_info; + info = temp_info; + } + + memcpy(info->system_id, side_data, system_id_size); + side_data += system_id_size; + side_data_size -= system_id_size; + for (j = 0; j < num_key_ids; j++) { + memcpy(info->key_ids[j], side_data, key_id_size); + side_data += key_id_size; + side_data_size -= key_id_size; + } + memcpy(info->data, side_data, data_size); + side_data += data_size; + side_data_size -= data_size; + } + + return ret; +} + +uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size) +{ + const AVEncryptionInitInfo *cur_info; + uint8_t *buffer, *cur_buffer; + uint32_t i, init_info_count; + uint64_t temp_side_data_size; + + temp_side_data_size = 4; + init_info_count = 0; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + cur_info->system_id_size + cur_info->data_size; + if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) { + return NULL; + } + init_info_count++; + + if (cur_info->num_key_ids) { + temp_side_data_size += (uint64_t)cur_info->num_key_ids * cur_info->key_id_size; + if (temp_side_data_size > UINT32_MAX) { + return NULL; + } + } + } + *side_data_size = temp_side_data_size; + + cur_buffer = buffer = av_malloc(*side_data_size); + if (!buffer) + return NULL; + + AV_WB32(cur_buffer, init_info_count); + cur_buffer += 4; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + AV_WB32(cur_buffer, cur_info->system_id_size); + AV_WB32(cur_buffer + 4, cur_info->num_key_ids); + AV_WB32(cur_buffer + 8, cur_info->key_id_size); + AV_WB32(cur_buffer + 12, cur_info->data_size); + cur_buffer += 16; + + memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size); + cur_buffer += cur_info->system_id_size; + for (i = 0; i < cur_info->num_key_ids; i++) { + memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size); + cur_buffer += cur_info->key_id_size; + } + if (cur_info->data_size > 0) { + memcpy(cur_buffer, cur_info->data, cur_info->data_size); + cur_buffer += cur_info->data_size; + } + } + + return buffer; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.h b/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.h new file mode 100644 index 00000000..8fe7ebfe --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/encryption_info.h @@ -0,0 +1,205 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ENCRYPTION_INFO_H +#define AVUTIL_ENCRYPTION_INFO_H + +#include +#include + +typedef struct AVSubsampleEncryptionInfo { + /** The number of bytes that are clear. */ + unsigned int bytes_of_clear_data; + + /** + * The number of bytes that are protected. If using pattern encryption, + * the pattern applies to only the protected bytes; if not using pattern + * encryption, all these bytes are encrypted. + */ + unsigned int bytes_of_protected_data; +} AVSubsampleEncryptionInfo; + +/** + * This describes encryption info for a packet. This contains frame-specific + * info for how to decrypt the packet before passing it to the decoder. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInfo { + /** The fourcc encryption scheme, in big-endian byte order. */ + uint32_t scheme; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are encrypted. + */ + uint32_t crypt_byte_block; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are clear. + */ + uint32_t skip_byte_block; + + /** + * The ID of the key used to encrypt the packet. This should always be + * 16 bytes long, but may be changed in the future. + */ + uint8_t *key_id; + uint32_t key_id_size; + + /** + * The initialization vector. This may have been zero-filled to be the + * correct block size. This should always be 16 bytes long, but may be + * changed in the future. + */ + uint8_t *iv; + uint32_t iv_size; + + /** + * An array of subsample encryption info specifying how parts of the sample + * are encrypted. If there are no subsamples, then the whole sample is + * encrypted. + */ + AVSubsampleEncryptionInfo *subsamples; + uint32_t subsample_count; +} AVEncryptionInfo; + +/** + * This describes info used to initialize an encryption key system. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInitInfo { + /** + * A unique identifier for the key system this is for, can be NULL if it + * is not known. This should always be 16 bytes, but may change in the + * future. + */ + uint8_t* system_id; + uint32_t system_id_size; + + /** + * An array of key IDs this initialization data is for. All IDs are the + * same length. Can be NULL if there are no known key IDs. + */ + uint8_t** key_ids; + /** The number of key IDs. */ + uint32_t num_key_ids; + /** + * The number of bytes in each key ID. This should always be 16, but may + * change in the future. + */ + uint32_t key_id_size; + + /** + * Key-system specific initialization data. This data is copied directly + * from the file and the format depends on the specific key system. This + * can be NULL if there is no initialization data; in that case, there + * will be at least one key ID. + */ + uint8_t* data; + uint32_t data_size; + + /** + * An optional pointer to the next initialization info in the list. + */ + struct AVEncryptionInitInfo *next; +} AVEncryptionInitInfo; + +/** + * Allocates an AVEncryptionInfo structure and sub-pointers to hold the given + * number of subsamples. This will allocate pointers for the key ID, IV, + * and subsample entries, set the size members, and zero-initialize the rest. + * + * @param subsample_count The number of subsamples. + * @param key_id_size The number of bytes in the key ID, should be 16. + * @param iv_size The number of bytes in the IV, should be 16. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size); + +/** + * Allocates an AVEncryptionInfo structure with a copy of the given data. + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info); + +/** + * Frees the given encryption info object. This MUST NOT be used to free the + * side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_info_free(AVEncryptionInfo *info); + +/** + * Creates a copy of the AVEncryptionInfo that is contained in the given side + * data. The resulting object should be passed to av_encryption_info_free() + * when done. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t *side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * info. The resulting pointer should be either freed using av_free or given + * to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_info_add_side_data( + const AVEncryptionInfo *info, size_t *side_data_size); + + +/** + * Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the + * given sizes. This will allocate pointers and set all the fields. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size); + +/** + * Frees the given encryption init info object. This MUST NOT be used to free + * the side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_init_info_free(AVEncryptionInitInfo* info); + +/** + * Creates a copy of the AVEncryptionInitInfo that is contained in the given + * side data. The resulting object should be passed to + * av_encryption_init_info_free() when done. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t* side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * init info. The resulting pointer should be either freed using av_free or + * given to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_init_info_add_side_data( + const AVEncryptionInitInfo *info, size_t *side_data_size); + +#endif /* AVUTIL_ENCRYPTION_INFO_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/error.c b/arm/raspi/third_party/ffmpeg/libavutil/error.c new file mode 100644 index 00000000..938a8bc0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/error.c @@ -0,0 +1,132 @@ +/* + * 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 + */ + +#undef _GNU_SOURCE +#define _XOPEN_SOURCE 600 /* XSI-compliant version of strerror_r */ +#include +#include +#include "config.h" +#include "avstring.h" +#include "error.h" +#include "macros.h" + +struct error_entry { + int num; + const char *tag; + const char *str; +}; + +#define ERROR_TAG(tag) AVERROR_##tag, #tag +#define EERROR_TAG(tag) AVERROR(tag), #tag +#define AVERROR_INPUT_AND_OUTPUT_CHANGED (AVERROR_INPUT_CHANGED | AVERROR_OUTPUT_CHANGED) +static const struct error_entry error_entries[] = { + { ERROR_TAG(BSF_NOT_FOUND), "Bitstream filter not found" }, + { ERROR_TAG(BUG), "Internal bug, should not have happened" }, + { ERROR_TAG(BUG2), "Internal bug, should not have happened" }, + { ERROR_TAG(BUFFER_TOO_SMALL), "Buffer too small" }, + { ERROR_TAG(DECODER_NOT_FOUND), "Decoder not found" }, + { ERROR_TAG(DEMUXER_NOT_FOUND), "Demuxer not found" }, + { ERROR_TAG(ENCODER_NOT_FOUND), "Encoder not found" }, + { ERROR_TAG(EOF), "End of file" }, + { ERROR_TAG(EXIT), "Immediate exit requested" }, + { ERROR_TAG(EXTERNAL), "Generic error in an external library" }, + { ERROR_TAG(FILTER_NOT_FOUND), "Filter not found" }, + { ERROR_TAG(INPUT_CHANGED), "Input changed" }, + { ERROR_TAG(INVALIDDATA), "Invalid data found when processing input" }, + { ERROR_TAG(MUXER_NOT_FOUND), "Muxer not found" }, + { ERROR_TAG(OPTION_NOT_FOUND), "Option not found" }, + { ERROR_TAG(OUTPUT_CHANGED), "Output changed" }, + { ERROR_TAG(PATCHWELCOME), "Not yet implemented in FFmpeg, patches welcome" }, + { ERROR_TAG(PROTOCOL_NOT_FOUND), "Protocol not found" }, + { ERROR_TAG(STREAM_NOT_FOUND), "Stream not found" }, + { ERROR_TAG(UNKNOWN), "Unknown error occurred" }, + { ERROR_TAG(EXPERIMENTAL), "Experimental feature" }, + { ERROR_TAG(INPUT_AND_OUTPUT_CHANGED), "Input and output changed" }, + { ERROR_TAG(HTTP_BAD_REQUEST), "Server returned 400 Bad Request" }, + { ERROR_TAG(HTTP_UNAUTHORIZED), "Server returned 401 Unauthorized (authorization failed)" }, + { ERROR_TAG(HTTP_FORBIDDEN), "Server returned 403 Forbidden (access denied)" }, + { ERROR_TAG(HTTP_NOT_FOUND), "Server returned 404 Not Found" }, + { ERROR_TAG(HTTP_OTHER_4XX), "Server returned 4XX Client Error, but not one of 40{0,1,3,4}" }, + { ERROR_TAG(HTTP_SERVER_ERROR), "Server returned 5XX Server Error reply" }, +#if !HAVE_STRERROR_R + { EERROR_TAG(E2BIG), "Argument list too long" }, + { EERROR_TAG(EACCES), "Permission denied" }, + { EERROR_TAG(EAGAIN), "Resource temporarily unavailable" }, + { EERROR_TAG(EBADF), "Bad file descriptor" }, + { EERROR_TAG(EBUSY), "Device or resource busy" }, + { EERROR_TAG(ECHILD), "No child processes" }, + { EERROR_TAG(EDEADLK), "Resource deadlock avoided" }, + { EERROR_TAG(EDOM), "Numerical argument out of domain" }, + { EERROR_TAG(EEXIST), "File exists" }, + { EERROR_TAG(EFAULT), "Bad address" }, + { EERROR_TAG(EFBIG), "File too large" }, + { EERROR_TAG(EILSEQ), "Illegal byte sequence" }, + { EERROR_TAG(EINTR), "Interrupted system call" }, + { EERROR_TAG(EINVAL), "Invalid argument" }, + { EERROR_TAG(EIO), "I/O error" }, + { EERROR_TAG(EISDIR), "Is a directory" }, + { EERROR_TAG(EMFILE), "Too many open files" }, + { EERROR_TAG(EMLINK), "Too many links" }, + { EERROR_TAG(ENAMETOOLONG), "File name too long" }, + { EERROR_TAG(ENFILE), "Too many open files in system" }, + { EERROR_TAG(ENODEV), "No such device" }, + { EERROR_TAG(ENOENT), "No such file or directory" }, + { EERROR_TAG(ENOEXEC), "Exec format error" }, + { EERROR_TAG(ENOLCK), "No locks available" }, + { EERROR_TAG(ENOMEM), "Cannot allocate memory" }, + { EERROR_TAG(ENOSPC), "No space left on device" }, + { EERROR_TAG(ENOSYS), "Function not implemented" }, + { EERROR_TAG(ENOTDIR), "Not a directory" }, + { EERROR_TAG(ENOTEMPTY), "Directory not empty" }, + { EERROR_TAG(ENOTTY), "Inappropriate I/O control operation" }, + { EERROR_TAG(ENXIO), "No such device or address" }, + { EERROR_TAG(EPERM), "Operation not permitted" }, + { EERROR_TAG(EPIPE), "Broken pipe" }, + { EERROR_TAG(ERANGE), "Result too large" }, + { EERROR_TAG(EROFS), "Read-only file system" }, + { EERROR_TAG(ESPIPE), "Illegal seek" }, + { EERROR_TAG(ESRCH), "No such process" }, + { EERROR_TAG(EXDEV), "Cross-device link" }, +#endif +}; + +int av_strerror(int errnum, char *errbuf, size_t errbuf_size) +{ + int ret = 0, i; + const struct error_entry *entry = NULL; + + for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) { + if (errnum == error_entries[i].num) { + entry = &error_entries[i]; + break; + } + } + if (entry) { + av_strlcpy(errbuf, entry->str, errbuf_size); + } else { +#if HAVE_STRERROR_R + ret = AVERROR(strerror_r(AVUNERROR(errnum), errbuf, errbuf_size)); +#else + ret = -1; +#endif + if (ret < 0) + snprintf(errbuf, errbuf_size, "Error number %d occurred", errnum); + } + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/error.h b/arm/raspi/third_party/ffmpeg/libavutil/error.h new file mode 100644 index 00000000..0d3269aa --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/error.h @@ -0,0 +1,128 @@ +/* + * 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 + * error code definitions + */ + +#ifndef AVUTIL_ERROR_H +#define AVUTIL_ERROR_H + +#include +#include + +#include "macros.h" + +/** + * @addtogroup lavu_error + * + * @{ + */ + + +/* error handling */ +#if EDOM > 0 +#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. +#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif + +#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) + +#define AVERROR_BSF_NOT_FOUND FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found +#define AVERROR_BUG FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2 +#define AVERROR_BUFFER_TOO_SMALL FFERRTAG( 'B','U','F','S') ///< Buffer too small +#define AVERROR_DECODER_NOT_FOUND FFERRTAG(0xF8,'D','E','C') ///< Decoder not found +#define AVERROR_DEMUXER_NOT_FOUND FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found +#define AVERROR_ENCODER_NOT_FOUND FFERRTAG(0xF8,'E','N','C') ///< Encoder not found +#define AVERROR_EOF FFERRTAG( 'E','O','F',' ') ///< End of file +#define AVERROR_EXIT FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted +#define AVERROR_EXTERNAL FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library +#define AVERROR_FILTER_NOT_FOUND FFERRTAG(0xF8,'F','I','L') ///< Filter not found +#define AVERROR_INVALIDDATA FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input +#define AVERROR_MUXER_NOT_FOUND FFERRTAG(0xF8,'M','U','X') ///< Muxer not found +#define AVERROR_OPTION_NOT_FOUND FFERRTAG(0xF8,'O','P','T') ///< Option not found +#define AVERROR_PATCHWELCOME FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome +#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found + +#define AVERROR_STREAM_NOT_FOUND FFERRTAG(0xF8,'S','T','R') ///< Stream not found +/** + * This is semantically identical to AVERROR_BUG + * it has been introduced in Libav after our AVERROR_BUG and with a modified value. + */ +#define AVERROR_BUG2 FFERRTAG( 'B','U','G',' ') +#define AVERROR_UNKNOWN FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library +#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. +#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) +#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) +/* HTTP & RTSP errors */ +#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0') +#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') +#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') +#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') +#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') + +#define AV_ERROR_MAX_STRING_SIZE 64 + +/** + * Put a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. Even in case of failure av_strerror() will print a generic + * error message indicating the errnum provided to errbuf. + * + * @param errnum error code to describe + * @param errbuf buffer to which description is written + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value if a description for errnum + * cannot be found + */ +int av_strerror(int errnum, char *errbuf, size_t errbuf_size); + +/** + * Fill the provided buffer with a string containing an error string + * corresponding to the AVERROR code errnum. + * + * @param errbuf a buffer + * @param errbuf_size size in bytes of errbuf + * @param errnum error code to describe + * @return the buffer in input, filled with the error description + * @see av_strerror() + */ +static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum) +{ + av_strerror(errnum, errbuf, errbuf_size); + return errbuf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_err2str(errnum) \ + av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum) + +/** + * @} + */ + +#endif /* AVUTIL_ERROR_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/eval.c b/arm/raspi/third_party/ffmpeg/libavutil/eval.c new file mode 100644 index 00000000..d0bada9b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/eval.c @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2002-2006 Michael Niedermayer + * Copyright (c) 2006 Oded Shimon + * + * 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 arithmetic expression evaluator. + * + * see http://joe.hotchkiss.com/programming/eval/eval.html + */ + +#include +#include "attributes.h" +#include "avutil.h" +#include "common.h" +#include "eval.h" +#include "ffmath.h" +#include "internal.h" +#include "log.h" +#include "mathematics.h" +#include "time.h" +#include "avstring.h" +#include "timer.h" +#include "reverse.h" + +typedef struct Parser { + const AVClass *class; + int stack_index; + char *s; + const double *const_values; + const char * const *const_names; // NULL terminated + double (* const *funcs1)(void *, double a); // NULL terminated + const char * const *func1_names; // NULL terminated + double (* const *funcs2)(void *, double a, double b); // NULL terminated + const char * const *func2_names; // NULL terminated + void *opaque; + int log_offset; + void *log_ctx; +#define VARS 10 + double *var; +} Parser; + +static const AVClass eval_class = { + .class_name = "Eval", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(Parser, log_offset), + .parent_log_context_offset = offsetof(Parser, log_ctx), +}; + +static const struct { + double bin_val; + double dec_val; + int8_t exp; +} si_prefixes['z' - 'E' + 1] = { + ['y'-'E']= { 8.271806125530276749e-25, 1e-24, -24 }, + ['z'-'E']= { 8.4703294725430034e-22, 1e-21, -21 }, + ['a'-'E']= { 8.6736173798840355e-19, 1e-18, -18 }, + ['f'-'E']= { 8.8817841970012523e-16, 1e-15, -15 }, + ['p'-'E']= { 9.0949470177292824e-13, 1e-12, -12 }, + ['n'-'E']= { 9.3132257461547852e-10, 1e-9, -9 }, + ['u'-'E']= { 9.5367431640625e-7, 1e-6, -6 }, + ['m'-'E']= { 9.765625e-4, 1e-3, -3 }, + ['c'-'E']= { 9.8431332023036951e-3, 1e-2, -2 }, + ['d'-'E']= { 9.921256574801246e-2, 1e-1, -1 }, + ['h'-'E']= { 1.0159366732596479e2, 1e2, 2 }, + ['k'-'E']= { 1.024e3, 1e3, 3 }, + ['K'-'E']= { 1.024e3, 1e3, 3 }, + ['M'-'E']= { 1.048576e6, 1e6, 6 }, + ['G'-'E']= { 1.073741824e9, 1e9, 9 }, + ['T'-'E']= { 1.099511627776e12, 1e12, 12 }, + ['P'-'E']= { 1.125899906842624e15, 1e15, 15 }, + ['E'-'E']= { 1.152921504606847e18, 1e18, 18 }, + ['Z'-'E']= { 1.1805916207174113e21, 1e21, 21 }, + ['Y'-'E']= { 1.2089258196146292e24, 1e24, 24 }, +}; + +static const struct { + const char *name; + double value; +} constants[] = { + { "E", M_E }, + { "PI", M_PI }, + { "PHI", M_PHI }, + { "QP2LAMBDA", FF_QP2LAMBDA }, +}; + +double av_strtod(const char *numstr, char **tail) +{ + double d; + char *next; + if(numstr[0]=='0' && (numstr[1]|0x20)=='x') { + d = strtoul(numstr, &next, 16); + } else + d = strtod(numstr, &next); + /* if parsing succeeded, check for and interpret postfixes */ + if (next!=numstr) { + if (next[0] == 'd' && next[1] == 'B') { + /* treat dB as decibels instead of decibytes */ + d = ff_exp10(d / 20); + next += 2; + } else if (*next >= 'E' && *next <= 'z') { + int e= si_prefixes[*next - 'E'].exp; + if (e) { + if (next[1] == 'i') { + d*= si_prefixes[*next - 'E'].bin_val; + next+=2; + } else { + d*= si_prefixes[*next - 'E'].dec_val; + next++; + } + } + } + + if (*next=='B') { + d*=8; + next++; + } + } + /* if requested, fill in tail with the position after the last parsed + character */ + if (tail) + *tail = next; + return d; +} + +#define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_') + +static int strmatch(const char *s, const char *prefix) +{ + int i; + for (i=0; prefix[i]; i++) { + if (prefix[i] != s[i]) return 0; + } + /* return 1 only if the s identifier is terminated */ + return !IS_IDENTIFIER_CHAR(s[i]); +} + +struct AVExpr { + enum { + e_value, e_const, e_func0, e_func1, e_func2, + e_squish, e_gauss, e_ld, e_isnan, e_isinf, + e_mod, e_max, e_min, e_eq, e_gt, e_gte, e_lte, e_lt, + e_pow, e_mul, e_div, e_add, + e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round, + e_sqrt, e_not, e_random, e_hypot, e_gcd, + e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp, + e_sgn, + } type; + double value; // is sign in other types + int const_index; + union { + double (*func0)(double); + double (*func1)(void *, double); + double (*func2)(void *, double, double); + } a; + struct AVExpr *param[3]; + double *var; +}; + +static double etime(double v) +{ + return av_gettime() * 0.000001; +} + +static double eval_expr(Parser *p, AVExpr *e) +{ + switch (e->type) { + case e_value: return e->value; + case e_const: return e->value * p->const_values[e->const_index]; + case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); + case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); + case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); + case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); + case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } + case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; + case e_isnan: return e->value * !!isnan(eval_expr(p, e->param[0])); + case e_isinf: return e->value * !!isinf(eval_expr(p, e->param[0])); + case e_floor: return e->value * floor(eval_expr(p, e->param[0])); + case e_ceil : return e->value * ceil (eval_expr(p, e->param[0])); + case e_trunc: return e->value * trunc(eval_expr(p, e->param[0])); + case e_round: return e->value * round(eval_expr(p, e->param[0])); + case e_sgn: return e->value * FFDIFFSIGN(eval_expr(p, e->param[0]), 0); + case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0])); + case e_not: return e->value * (eval_expr(p, e->param[0]) == 0); + case e_if: return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : + e->param[2] ? eval_expr(p, e->param[2]) : 0); + case e_ifnot: return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : + e->param[2] ? eval_expr(p, e->param[2]) : 0); + case e_clip: { + double x = eval_expr(p, e->param[0]); + double min = eval_expr(p, e->param[1]), max = eval_expr(p, e->param[2]); + if (isnan(min) || isnan(max) || isnan(x) || min > max) + return NAN; + return e->value * av_clipd(eval_expr(p, e->param[0]), min, max); + } + case e_between: { + double d = eval_expr(p, e->param[0]); + return e->value * (d >= eval_expr(p, e->param[1]) && + d <= eval_expr(p, e->param[2])); + } + case e_lerp: { + double v0 = eval_expr(p, e->param[0]); + double v1 = eval_expr(p, e->param[1]); + double f = eval_expr(p, e->param[2]); + return v0 + (v1 - v0) * f; + } + case e_print: { + double x = eval_expr(p, e->param[0]); + int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO; + av_log(p, level, "%f\n", x); + return x; + } + case e_random:{ + int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1); + uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx]; + r= r*1664525+1013904223; + p->var[idx]= r; + return e->value * (r * (1.0/UINT64_MAX)); + } + case e_while: { + double d = NAN; + while (eval_expr(p, e->param[0])) + d=eval_expr(p, e->param[1]); + return d; + } + case e_taylor: { + double t = 1, d = 0, v; + double x = eval_expr(p, e->param[1]); + int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0; + int i; + double var0 = p->var[id]; + for(i=0; i<1000; i++) { + double ld = d; + p->var[id] = i; + v = eval_expr(p, e->param[0]); + d += t*v; + if(ld==d && v) + break; + t *= x / (i+1); + } + p->var[id] = var0; + return d; + } + case e_root: { + int i, j; + double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX; + double var0 = p->var[0]; + double x_max = eval_expr(p, e->param[1]); + for(i=-1; i<1024; i++) { + if(i<255) { + p->var[0] = ff_reverse[i&255]*x_max/255; + } else { + p->var[0] = x_max*pow(0.9, i-255); + if (i&1) p->var[0] *= -1; + if (i&2) p->var[0] += low; + else p->var[0] += high; + } + v = eval_expr(p, e->param[0]); + if (v<=0 && v>low_v) { + low = p->var[0]; + low_v = v; + } + if (v>=0 && vvar[0]; + high_v = v; + } + if (low>=0 && high>=0){ + for (j=0; j<1000; j++) { + p->var[0] = (low+high)*0.5; + if (low == p->var[0] || high == p->var[0]) + break; + v = eval_expr(p, e->param[0]); + if (v<=0) low = p->var[0]; + if (v>=0) high= p->var[0]; + if (isnan(v)) { + low = high = v; + break; + } + } + break; + } + } + p->var[0] = var0; + return -low_vparam[0]); + double d2 = eval_expr(p, e->param[1]); + switch (e->type) { + case e_mod: return e->value * (d - floor(d2 ? d / d2 : d * INFINITY) * d2); + case e_gcd: return e->value * av_gcd(d,d2); + case e_max: return e->value * (d > d2 ? d : d2); + case e_min: return e->value * (d < d2 ? d : d2); + case e_eq: return e->value * (d == d2 ? 1.0 : 0.0); + case e_gt: return e->value * (d > d2 ? 1.0 : 0.0); + case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0); + case e_lt: return e->value * (d < d2 ? 1.0 : 0.0); + case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0); + case e_pow: return e->value * pow(d, d2); + case e_mul: return e->value * (d * d2); + case e_div: return e->value * (d2 ? (d / d2) : d * INFINITY); + case e_add: return e->value * (d + d2); + case e_last:return e->value * d2; + case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); + case e_hypot:return e->value * hypot(d, d2); + case e_atan2:return e->value * atan2(d, d2); + case e_bitand: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d & (long int)d2); + case e_bitor: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d | (long int)d2); + } + } + } + return NAN; +} + +static int parse_expr(AVExpr **e, Parser *p); + +void av_expr_free(AVExpr *e) +{ + if (!e) return; + av_expr_free(e->param[0]); + av_expr_free(e->param[1]); + av_expr_free(e->param[2]); + av_freep(&e->var); + av_freep(&e); +} + +static int parse_primary(AVExpr **e, Parser *p) +{ + AVExpr *d = av_mallocz(sizeof(AVExpr)); + char *next = p->s, *s0 = p->s; + int ret, i; + + if (!d) + return AVERROR(ENOMEM); + + /* number */ + d->value = av_strtod(p->s, &next); + if (next != p->s) { + d->type = e_value; + p->s= next; + *e = d; + return 0; + } + d->value = 1; + + /* named constants */ + for (i=0; p->const_names && p->const_names[i]; i++) { + if (strmatch(p->s, p->const_names[i])) { + p->s+= strlen(p->const_names[i]); + d->type = e_const; + d->const_index = i; + *e = d; + return 0; + } + } + for (i = 0; i < FF_ARRAY_ELEMS(constants); i++) { + if (strmatch(p->s, constants[i].name)) { + p->s += strlen(constants[i].name); + d->type = e_value; + d->value = constants[i].value; + *e = d; + return 0; + } + } + + p->s= strchr(p->s, '('); + if (!p->s) { + av_log(p, AV_LOG_ERROR, "Undefined constant or missing '(' in '%s'\n", s0); + p->s= next; + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // "(" + if (*next == '(') { // special case do-nothing + av_freep(&d); + if ((ret = parse_expr(&d, p)) < 0) + return ret; + if (p->s[0] != ')') { + av_log(p, AV_LOG_ERROR, "Missing ')' in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // ")" + *e = d; + return 0; + } + if ((ret = parse_expr(&(d->param[0]), p)) < 0) { + av_expr_free(d); + return ret; + } + if (p->s[0]== ',') { + p->s++; // "," + parse_expr(&d->param[1], p); + } + if (p->s[0]== ',') { + p->s++; // "," + parse_expr(&d->param[2], p); + } + if (p->s[0] != ')') { + av_log(p, AV_LOG_ERROR, "Missing ')' or too many args in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // ")" + + d->type = e_func0; + if (strmatch(next, "sinh" )) d->a.func0 = sinh; + else if (strmatch(next, "cosh" )) d->a.func0 = cosh; + else if (strmatch(next, "tanh" )) d->a.func0 = tanh; + else if (strmatch(next, "sin" )) d->a.func0 = sin; + else if (strmatch(next, "cos" )) d->a.func0 = cos; + else if (strmatch(next, "tan" )) d->a.func0 = tan; + else if (strmatch(next, "atan" )) d->a.func0 = atan; + else if (strmatch(next, "asin" )) d->a.func0 = asin; + else if (strmatch(next, "acos" )) d->a.func0 = acos; + else if (strmatch(next, "exp" )) d->a.func0 = exp; + else if (strmatch(next, "log" )) d->a.func0 = log; + else if (strmatch(next, "abs" )) d->a.func0 = fabs; + else if (strmatch(next, "time" )) d->a.func0 = etime; + else if (strmatch(next, "squish")) d->type = e_squish; + else if (strmatch(next, "gauss" )) d->type = e_gauss; + else if (strmatch(next, "mod" )) d->type = e_mod; + else if (strmatch(next, "max" )) d->type = e_max; + else if (strmatch(next, "min" )) d->type = e_min; + else if (strmatch(next, "eq" )) d->type = e_eq; + else if (strmatch(next, "gte" )) d->type = e_gte; + else if (strmatch(next, "gt" )) d->type = e_gt; + else if (strmatch(next, "lte" )) d->type = e_lte; + else if (strmatch(next, "lt" )) d->type = e_lt; + else if (strmatch(next, "ld" )) d->type = e_ld; + else if (strmatch(next, "isnan" )) d->type = e_isnan; + else if (strmatch(next, "isinf" )) d->type = e_isinf; + else if (strmatch(next, "st" )) d->type = e_st; + else if (strmatch(next, "while" )) d->type = e_while; + else if (strmatch(next, "taylor")) d->type = e_taylor; + else if (strmatch(next, "root" )) d->type = e_root; + else if (strmatch(next, "floor" )) d->type = e_floor; + else if (strmatch(next, "ceil" )) d->type = e_ceil; + else if (strmatch(next, "trunc" )) d->type = e_trunc; + else if (strmatch(next, "round" )) d->type = e_round; + else if (strmatch(next, "sqrt" )) d->type = e_sqrt; + else if (strmatch(next, "not" )) d->type = e_not; + else if (strmatch(next, "pow" )) d->type = e_pow; + else if (strmatch(next, "print" )) d->type = e_print; + else if (strmatch(next, "random")) d->type = e_random; + else if (strmatch(next, "hypot" )) d->type = e_hypot; + else if (strmatch(next, "gcd" )) d->type = e_gcd; + else if (strmatch(next, "if" )) d->type = e_if; + else if (strmatch(next, "ifnot" )) d->type = e_ifnot; + else if (strmatch(next, "bitand")) d->type = e_bitand; + else if (strmatch(next, "bitor" )) d->type = e_bitor; + else if (strmatch(next, "between"))d->type = e_between; + else if (strmatch(next, "clip" )) d->type = e_clip; + else if (strmatch(next, "atan2" )) d->type = e_atan2; + else if (strmatch(next, "lerp" )) d->type = e_lerp; + else if (strmatch(next, "sgn" )) d->type = e_sgn; + else { + for (i=0; p->func1_names && p->func1_names[i]; i++) { + if (strmatch(next, p->func1_names[i])) { + d->a.func1 = p->funcs1[i]; + d->type = e_func1; + d->const_index = i; + *e = d; + return 0; + } + } + + for (i=0; p->func2_names && p->func2_names[i]; i++) { + if (strmatch(next, p->func2_names[i])) { + d->a.func2 = p->funcs2[i]; + d->type = e_func2; + d->const_index = i; + *e = d; + return 0; + } + } + + av_log(p, AV_LOG_ERROR, "Unknown function in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + + *e = d; + return 0; +} + +static AVExpr *make_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1) +{ + AVExpr *e = av_mallocz(sizeof(AVExpr)); + if (!e) + return NULL; + e->type =type ; + e->value =value ; + e->param[0] =p0 ; + e->param[1] =p1 ; + return e; +} + +static int parse_pow(AVExpr **e, Parser *p, int *sign) +{ + *sign= (*p->s == '+') - (*p->s == '-'); + p->s += *sign&1; + return parse_primary(e, p); +} + +static int parse_dB(AVExpr **e, Parser *p, int *sign) +{ + /* do not filter out the negative sign when parsing a dB value. + for example, -3dB is not the same as -(3dB) */ + if (*p->s == '-') { + char *next; + double av_unused ignored = strtod(p->s, &next); + if (next != p->s && next[0] == 'd' && next[1] == 'B') { + *sign = 0; + return parse_primary(e, p); + } + } + return parse_pow(e, p, sign); +} + +static int parse_factor(AVExpr **e, Parser *p) +{ + int sign, sign2, ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_dB(&e0, p, &sign)) < 0) + return ret; + while(p->s[0]=='^'){ + e1 = e0; + p->s++; + if ((ret = parse_dB(&e2, p, &sign2)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_pow, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + if (e0->param[1]) e0->param[1]->value *= (sign2|1); + } + if (e0) e0->value *= (sign|1); + + *e = e0; + return 0; +} + +static int parse_term(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_factor(&e0, p)) < 0) + return ret; + while (p->s[0]=='*' || p->s[0]=='/') { + int c= *p->s++; + e1 = e0; + if ((ret = parse_factor(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(c == '*' ? e_mul : e_div, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + } + *e = e0; + return 0; +} + +static int parse_subexpr(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_term(&e0, p)) < 0) + return ret; + while (*p->s == '+' || *p->s == '-') { + e1 = e0; + if ((ret = parse_term(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_add, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + }; + + *e = e0; + return 0; +} + +static int parse_expr(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if (p->stack_index <= 0) //protect against stack overflows + return AVERROR(EINVAL); + p->stack_index--; + + if ((ret = parse_subexpr(&e0, p)) < 0) + return ret; + while (*p->s == ';') { + p->s++; + e1 = e0; + if ((ret = parse_subexpr(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_last, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + }; + + p->stack_index++; + *e = e0; + return 0; +} + +static int verify_expr(AVExpr *e) +{ + if (!e) return 0; + switch (e->type) { + case e_value: + case e_const: return 1; + case e_func0: + case e_func1: + case e_squish: + case e_ld: + case e_gauss: + case e_isnan: + case e_isinf: + case e_floor: + case e_ceil: + case e_trunc: + case e_round: + case e_sqrt: + case e_not: + case e_random: + case e_sgn: + return verify_expr(e->param[0]) && !e->param[1]; + case e_print: + return verify_expr(e->param[0]) + && (!e->param[1] || verify_expr(e->param[1])); + case e_if: + case e_ifnot: + case e_taylor: + return verify_expr(e->param[0]) && verify_expr(e->param[1]) + && (!e->param[2] || verify_expr(e->param[2])); + case e_between: + case e_clip: + case e_lerp: + return verify_expr(e->param[0]) && + verify_expr(e->param[1]) && + verify_expr(e->param[2]); + default: return verify_expr(e->param[0]) && verify_expr(e->param[1]) && !e->param[2]; + } +} + +int av_expr_parse(AVExpr **expr, const char *s, + const char * const *const_names, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + int log_offset, void *log_ctx) +{ + Parser p = { 0 }; + AVExpr *e = NULL; + char *w = av_malloc(strlen(s) + 1); + char *wp = w; + const char *s0 = s; + int ret = 0; + + if (!w) + return AVERROR(ENOMEM); + + while (*s) + if (!av_isspace(*s++)) *wp++ = s[-1]; + *wp++ = 0; + + p.class = &eval_class; + p.stack_index=100; + p.s= w; + p.const_names = const_names; + p.funcs1 = funcs1; + p.func1_names = func1_names; + p.funcs2 = funcs2; + p.func2_names = func2_names; + p.log_offset = log_offset; + p.log_ctx = log_ctx; + + if ((ret = parse_expr(&e, &p)) < 0) + goto end; + if (*p.s) { + av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0); + ret = AVERROR(EINVAL); + goto end; + } + if (!verify_expr(e)) { + ret = AVERROR(EINVAL); + goto end; + } + e->var= av_mallocz(sizeof(double) *VARS); + if (!e->var) { + ret = AVERROR(ENOMEM); + goto end; + } + *expr = e; + e = NULL; +end: + av_expr_free(e); + av_free(w); + return ret; +} + +static int expr_count(AVExpr *e, unsigned *counter, int size, int type) +{ + int i; + + if (!e || !counter || !size) + return AVERROR(EINVAL); + + for (i = 0; e->type != type && i < 3 && e->param[i]; i++) + expr_count(e->param[i], counter, size, type); + + if (e->type == type && e->const_index < size) + counter[e->const_index]++; + + return 0; +} + +int av_expr_count_vars(AVExpr *e, unsigned *counter, int size) +{ + return expr_count(e, counter, size, e_const); +} + +int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg) +{ + return expr_count(e, counter, size, ((int[]){e_const, e_func1, e_func2})[arg]); +} + +double av_expr_eval(AVExpr *e, const double *const_values, void *opaque) +{ + Parser p = { 0 }; + p.var= e->var; + + p.const_values = const_values; + p.opaque = opaque; + return eval_expr(&p, e); +} + +int av_expr_parse_and_eval(double *d, const char *s, + const char * const *const_names, const double *const_values, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + void *opaque, int log_offset, void *log_ctx) +{ + AVExpr *e = NULL; + int ret = av_expr_parse(&e, s, const_names, func1_names, funcs1, func2_names, funcs2, log_offset, log_ctx); + + if (ret < 0) { + *d = NAN; + return ret; + } + *d = av_expr_eval(e, const_values, opaque); + av_expr_free(e); + return isnan(*d) ? AVERROR(EINVAL) : 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/eval.h b/arm/raspi/third_party/ffmpeg/libavutil/eval.h new file mode 100644 index 00000000..ee8cffb0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/eval.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple arithmetic expression evaluator + */ + +#ifndef AVUTIL_EVAL_H +#define AVUTIL_EVAL_H + +typedef struct AVExpr AVExpr; + +/** + * Parse and evaluate an expression. + * Note, this is significantly slower than av_expr_eval(). + * + * @param res a pointer to a double where is put the result value of + * the expression, or NAN in case of error + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param const_values a zero terminated array of values for the identifiers from const_names + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @param log_offset log level offset, can be used to silence error messages + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse_and_eval(double *res, const char *s, + const char * const *const_names, const double *const_values, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + void *opaque, int log_offset, void *log_ctx); + +/** + * Parse an expression. + * + * @param expr a pointer where is put an AVExpr containing the parsed + * value in case of successful parsing, or NULL otherwise. + * The pointed to AVExpr must be freed with av_expr_free() by the user + * when it is not needed anymore. + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param log_offset log level offset, can be used to silence error messages + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse(AVExpr **expr, const char *s, + const char * const *const_names, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + int log_offset, void *log_ctx); + +/** + * Evaluate a previously parsed expression. + * + * @param e the AVExpr to evaluate + * @param const_values a zero terminated array of values for the identifiers from av_expr_parse() const_names + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @return the value of the expression + */ +double av_expr_eval(AVExpr *e, const double *const_values, void *opaque); + +/** + * Track the presence of variables and their number of occurrences in a parsed expression + * + * @param e the AVExpr to track variables in + * @param counter a zero-initialized array where the count of each variable will be stored + * @param size size of array + * @return 0 on success, a negative value indicates that no expression or array was passed + * or size was zero + */ +int av_expr_count_vars(AVExpr *e, unsigned *counter, int size); + +/** + * Track the presence of user provided functions and their number of occurrences + * in a parsed expression. + * + * @param e the AVExpr to track user provided functions in + * @param counter a zero-initialized array where the count of each function will be stored + * if you passed 5 functions with 2 arguments to av_expr_parse() + * then for arg=2 this will use upto 5 entries. + * @param size size of array + * @param arg number of arguments the counted functions have + * @return 0 on success, a negative value indicates that no expression or array was passed + * or size was zero + */ +int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg); + +/** + * Free a parsed expression previously created with av_expr_parse(). + */ +void av_expr_free(AVExpr *e); + +/** + * Parse the string in numstr and return its value as a double. If + * the string is empty, contains only whitespaces, or does not contain + * an initial substring that has the expected syntax for a + * floating-point number, no conversion is performed. In this case, + * returns a value of zero and the value returned in tail is the value + * of numstr. + * + * @param numstr a string representing a number, may contain one of + * the International System number postfixes, for example 'K', 'M', + * 'G'. If 'i' is appended after the postfix, powers of 2 are used + * instead of powers of 10. The 'B' postfix multiplies the value by + * 8, and can be appended after another postfix or used alone. This + * allows using for example 'KB', 'MiB', 'G' and 'B' as postfix. + * @param tail if non-NULL puts here the pointer to the char next + * after the last parsed character + */ +double av_strtod(const char *numstr, char **tail); + +#endif /* AVUTIL_EVAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ffmath.h b/arm/raspi/third_party/ffmpeg/libavutil/ffmath.h new file mode 100644 index 00000000..aad1347f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ffmath.h @@ -0,0 +1,67 @@ +/* + * copyright (c) 2016 Ganesh Ajjanagadde + * + * 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 + * internal math functions header + */ + +#ifndef AVUTIL_FFMATH_H +#define AVUTIL_FFMATH_H + +#include "attributes.h" +#include "libm.h" + +/** + * Compute 10^x for floating point values. Note: this function is by no means + * "correctly rounded", and is meant as a fast, reasonably accurate approximation. + * For instance, maximum relative error for the double precision variant is + * ~ 1e-13 for very small and very large values. + * This is ~2x faster than GNU libm's approach, which is still off by 2ulp on + * some inputs. + * @param x exponent + * @return 10^x + */ +static av_always_inline double ff_exp10(double x) +{ + return exp2(M_LOG2_10 * x); +} + +static av_always_inline float ff_exp10f(float x) +{ + return exp2f(M_LOG2_10 * x); +} + +/** + * Compute x^y for floating point x, y. Note: this function is faster than the + * libm variant due to mainly 2 reasons: + * 1. It does not handle any edge cases. In particular, this is only guaranteed + * to work correctly for x > 0. + * 2. It is not as accurate as a standard nearly "correctly rounded" libm variant. + * @param x base + * @param y exponent + * @return x^y + */ +static av_always_inline float ff_fast_powf(float x, float y) +{ + return expf(logf(x) * y); +} + +#endif /* AVUTIL_FFMATH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/fifo.c b/arm/raspi/third_party/ffmpeg/libavutil/fifo.c new file mode 100644 index 00000000..51a5af6f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/fifo.c @@ -0,0 +1,510 @@ +/* + * a very simple circular buffer FIFO implementation + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2006 Roman Shaposhnik + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "avassert.h" +#include "error.h" +#include "fifo.h" +#include "macros.h" +#include "mem.h" + +// by default the FIFO can be auto-grown to 1MB +#define AUTO_GROW_DEFAULT_BYTES (1024 * 1024) + +struct AVFifo { + uint8_t *buffer; + + size_t elem_size, nb_elems; + size_t offset_r, offset_w; + // distinguishes the ambiguous situation offset_r == offset_w + int is_empty; + + unsigned int flags; + size_t auto_grow_limit; +}; + +AVFifo *av_fifo_alloc2(size_t nb_elems, size_t elem_size, + unsigned int flags) +{ + AVFifo *f; + void *buffer = NULL; + + if (!elem_size) + return NULL; + + if (nb_elems) { + buffer = av_realloc_array(NULL, nb_elems, elem_size); + if (!buffer) + return NULL; + } + f = av_mallocz(sizeof(*f)); + if (!f) { + av_free(buffer); + return NULL; + } + f->buffer = buffer; + f->nb_elems = nb_elems; + f->elem_size = elem_size; + f->is_empty = 1; + + f->flags = flags; + f->auto_grow_limit = FFMAX(AUTO_GROW_DEFAULT_BYTES / elem_size, 1); + + return f; +} + +void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems) +{ + f->auto_grow_limit = max_elems; +} + +size_t av_fifo_elem_size(const AVFifo *f) +{ + return f->elem_size; +} + +size_t av_fifo_can_read(const AVFifo *f) +{ + if (f->offset_w <= f->offset_r && !f->is_empty) + return f->nb_elems - f->offset_r + f->offset_w; + return f->offset_w - f->offset_r; +} + +size_t av_fifo_can_write(const AVFifo *f) +{ + return f->nb_elems - av_fifo_can_read(f); +} + +int av_fifo_grow2(AVFifo *f, size_t inc) +{ + uint8_t *tmp; + + if (inc > SIZE_MAX - f->nb_elems) + return AVERROR(EINVAL); + + tmp = av_realloc_array(f->buffer, f->nb_elems + inc, f->elem_size); + if (!tmp) + return AVERROR(ENOMEM); + f->buffer = tmp; + + // move the data from the beginning of the ring buffer + // to the newly allocated space + if (f->offset_w <= f->offset_r && !f->is_empty) { + const size_t copy = FFMIN(inc, f->offset_w); + memcpy(tmp + f->nb_elems * f->elem_size, tmp, copy * f->elem_size); + if (copy < f->offset_w) { + memmove(tmp, tmp + copy * f->elem_size, + (f->offset_w - copy) * f->elem_size); + f->offset_w -= copy; + } else + f->offset_w = copy == inc ? 0 : f->nb_elems + copy; + } + + f->nb_elems += inc; + + return 0; +} + +static int fifo_check_space(AVFifo *f, size_t to_write) +{ + const size_t can_write = av_fifo_can_write(f); + const size_t need_grow = to_write > can_write ? to_write - can_write : 0; + size_t can_grow; + + if (!need_grow) + return 0; + + can_grow = f->auto_grow_limit > f->nb_elems ? + f->auto_grow_limit - f->nb_elems : 0; + if ((f->flags & AV_FIFO_FLAG_AUTO_GROW) && need_grow <= can_grow) { + // allocate a bit more than necessary, if we can + const size_t inc = (need_grow < can_grow / 2 ) ? need_grow * 2 : can_grow; + return av_fifo_grow2(f, inc); + } + + return AVERROR(ENOSPC); +} + +static int fifo_write_common(AVFifo *f, const uint8_t *buf, size_t *nb_elems, + AVFifoCB read_cb, void *opaque) +{ + size_t to_write = *nb_elems; + size_t offset_w; + int ret = 0; + + ret = fifo_check_space(f, to_write); + if (ret < 0) + return ret; + + offset_w = f->offset_w; + + while (to_write > 0) { + size_t len = FFMIN(f->nb_elems - offset_w, to_write); + uint8_t *wptr = f->buffer + offset_w * f->elem_size; + + if (read_cb) { + ret = read_cb(opaque, wptr, &len); + if (ret < 0 || len == 0) + break; + } else { + memcpy(wptr, buf, len * f->elem_size); + buf += len * f->elem_size; + } + offset_w += len; + if (offset_w >= f->nb_elems) + offset_w = 0; + to_write -= len; + } + f->offset_w = offset_w; + + if (*nb_elems != to_write) + f->is_empty = 0; + *nb_elems -= to_write; + + return ret; +} + +int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems) +{ + return fifo_write_common(f, buf, &nb_elems, NULL, NULL); +} + +int av_fifo_write_from_cb(AVFifo *f, AVFifoCB read_cb, + void *opaque, size_t *nb_elems) +{ + return fifo_write_common(f, NULL, nb_elems, read_cb, opaque); +} + +static int fifo_peek_common(const AVFifo *f, uint8_t *buf, size_t *nb_elems, + size_t offset, AVFifoCB write_cb, void *opaque) +{ + size_t to_read = *nb_elems; + size_t offset_r = f->offset_r; + size_t can_read = av_fifo_can_read(f); + int ret = 0; + + if (offset > can_read || to_read > can_read - offset) { + *nb_elems = 0; + return AVERROR(EINVAL); + } + + if (offset_r >= f->nb_elems - offset) + offset_r -= f->nb_elems - offset; + else + offset_r += offset; + + while (to_read > 0) { + size_t len = FFMIN(f->nb_elems - offset_r, to_read); + uint8_t *rptr = f->buffer + offset_r * f->elem_size; + + if (write_cb) { + ret = write_cb(opaque, rptr, &len); + if (ret < 0 || len == 0) + break; + } else { + memcpy(buf, rptr, len * f->elem_size); + buf += len * f->elem_size; + } + offset_r += len; + if (offset_r >= f->nb_elems) + offset_r = 0; + to_read -= len; + } + + *nb_elems -= to_read; + + return ret; +} + +int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems) +{ + int ret = fifo_peek_common(f, buf, &nb_elems, 0, NULL, NULL); + av_fifo_drain2(f, nb_elems); + return ret; +} + +int av_fifo_read_to_cb(AVFifo *f, AVFifoCB write_cb, + void *opaque, size_t *nb_elems) +{ + int ret = fifo_peek_common(f, NULL, nb_elems, 0, write_cb, opaque); + av_fifo_drain2(f, *nb_elems); + return ret; +} + +int av_fifo_peek(AVFifo *f, void *buf, size_t nb_elems, size_t offset) +{ + return fifo_peek_common(f, buf, &nb_elems, offset, NULL, NULL); +} + +int av_fifo_peek_to_cb(AVFifo *f, AVFifoCB write_cb, void *opaque, + size_t *nb_elems, size_t offset) +{ + return fifo_peek_common(f, NULL, nb_elems, offset, write_cb, opaque); +} + +void av_fifo_drain2(AVFifo *f, size_t size) +{ + const size_t cur_size = av_fifo_can_read(f); + + av_assert0(cur_size >= size); + if (cur_size == size) + f->is_empty = 1; + + if (f->offset_r >= f->nb_elems - size) + f->offset_r -= f->nb_elems - size; + else + f->offset_r += size; +} + +void av_fifo_reset2(AVFifo *f) +{ + f->offset_r = f->offset_w = 0; + f->is_empty = 1; +} + +void av_fifo_freep2(AVFifo **f) +{ + if (*f) { + av_freep(&(*f)->buffer); + av_freep(f); + } +} + + +#if FF_API_FIFO_OLD_API +FF_DISABLE_DEPRECATION_WARNINGS +#define OLD_FIFO_SIZE_MAX (size_t)FFMIN3(INT_MAX, UINT32_MAX, SIZE_MAX) + +AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size) +{ + AVFifoBuffer *f; + void *buffer; + + if (nmemb > OLD_FIFO_SIZE_MAX / size) + return NULL; + + buffer = av_realloc_array(NULL, nmemb, size); + if (!buffer) + return NULL; + f = av_mallocz(sizeof(AVFifoBuffer)); + if (!f) { + av_free(buffer); + return NULL; + } + f->buffer = buffer; + f->end = f->buffer + nmemb * size; + av_fifo_reset(f); + return f; +} + +AVFifoBuffer *av_fifo_alloc(unsigned int size) +{ + return av_fifo_alloc_array(size, 1); +} + +void av_fifo_free(AVFifoBuffer *f) +{ + if (f) { + av_freep(&f->buffer); + av_free(f); + } +} + +void av_fifo_freep(AVFifoBuffer **f) +{ + if (f) { + av_fifo_free(*f); + *f = NULL; + } +} + +void av_fifo_reset(AVFifoBuffer *f) +{ + f->wptr = f->rptr = f->buffer; + f->wndx = f->rndx = 0; +} + +int av_fifo_size(const AVFifoBuffer *f) +{ + return (uint32_t)(f->wndx - f->rndx); +} + +int av_fifo_space(const AVFifoBuffer *f) +{ + return f->end - f->buffer - av_fifo_size(f); +} + +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) +{ + unsigned int old_size = f->end - f->buffer; + + if (new_size > OLD_FIFO_SIZE_MAX) + return AVERROR(EINVAL); + + if (old_size < new_size) { + size_t offset_r = f->rptr - f->buffer; + size_t offset_w = f->wptr - f->buffer; + uint8_t *tmp; + + tmp = av_realloc(f->buffer, new_size); + if (!tmp) + return AVERROR(ENOMEM); + + // move the data from the beginning of the ring buffer + // to the newly allocated space + // the second condition distinguishes full vs empty fifo + if (offset_w <= offset_r && av_fifo_size(f)) { + const size_t copy = FFMIN(new_size - old_size, offset_w); + memcpy(tmp + old_size, tmp, copy); + if (copy < offset_w) { + memmove(tmp, tmp + copy , offset_w - copy); + offset_w -= copy; + } else + offset_w = old_size + copy; + } + + f->buffer = tmp; + f->end = f->buffer + new_size; + f->rptr = f->buffer + offset_r; + f->wptr = f->buffer + offset_w; + } + return 0; +} + +int av_fifo_grow(AVFifoBuffer *f, unsigned int size) +{ + unsigned int old_size = f->end - f->buffer; + if(size + (unsigned)av_fifo_size(f) < size) + return AVERROR(EINVAL); + + size += av_fifo_size(f); + + if (old_size < size) + return av_fifo_realloc2(f, FFMAX(size, 2*old_size)); + return 0; +} + +/* src must NOT be const as it can be a context for func that may need + * updating (like a pointer or byte counter) */ +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, + int (*func)(void *, void *, int)) +{ + int total = size; + uint32_t wndx= f->wndx; + uint8_t *wptr= f->wptr; + + if (size > av_fifo_space(f)) + return AVERROR(ENOSPC); + + do { + int len = FFMIN(f->end - wptr, size); + if (func) { + len = func(src, wptr, len); + if (len <= 0) + break; + } else { + memcpy(wptr, src, len); + src = (uint8_t *)src + len; + } + wptr += len; + if (wptr >= f->end) + wptr = f->buffer; + wndx += len; + size -= len; + } while (size > 0); + f->wndx= wndx; + f->wptr= wptr; + return total - size; +} + +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)) +{ + uint8_t *rptr = f->rptr; + + if (offset < 0 || buf_size > av_fifo_size(f) - offset) + return AVERROR(EINVAL); + + if (offset >= f->end - rptr) + rptr += offset - (f->end - f->buffer); + else + rptr += offset; + + while (buf_size > 0) { + int len; + + if (rptr >= f->end) + rptr -= f->end - f->buffer; + + len = FFMIN(f->end - rptr, buf_size); + if (func) + func(dest, rptr, len); + else { + memcpy(dest, rptr, len); + dest = (uint8_t *)dest + len; + } + + buf_size -= len; + rptr += len; + } + + return 0; +} + +int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, + void (*func)(void *, void *, int)) +{ + return av_fifo_generic_peek_at(f, dest, 0, buf_size, func); +} + +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, + void (*func)(void *, void *, int)) +{ + if (buf_size > av_fifo_size(f)) + return AVERROR(EINVAL); + + do { + int len = FFMIN(f->end - f->rptr, buf_size); + if (func) + func(dest, f->rptr, len); + else { + memcpy(dest, f->rptr, len); + dest = (uint8_t *)dest + len; + } + av_fifo_drain(f, len); + buf_size -= len; + } while (buf_size > 0); + return 0; +} + +/** Discard data from the FIFO. */ +void av_fifo_drain(AVFifoBuffer *f, int size) +{ + av_assert2(av_fifo_size(f) >= size); + f->rptr += size; + if (f->rptr >= f->end) + f->rptr -= f->end - f->buffer; + f->rndx += size; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/fifo.h b/arm/raspi/third_party/ffmpeg/libavutil/fifo.h new file mode 100644 index 00000000..70f9376d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/fifo.h @@ -0,0 +1,448 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_fifo + * A generic FIFO API + */ + +#ifndef AVUTIL_FIFO_H +#define AVUTIL_FIFO_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_fifo AVFifo + * @ingroup lavu_data + * + * @{ + * A generic FIFO API + */ + +typedef struct AVFifo AVFifo; + +/** + * Callback for writing or reading from a FIFO, passed to (and invoked from) the + * av_fifo_*_cb() functions. It may be invoked multiple times from a single + * av_fifo_*_cb() call and may process less data than the maximum size indicated + * by nb_elems. + * + * @param opaque the opaque pointer provided to the av_fifo_*_cb() function + * @param buf the buffer for reading or writing the data, depending on which + * av_fifo_*_cb function is called + * @param nb_elems On entry contains the maximum number of elements that can be + * read from / written into buf. On success, the callback should + * update it to contain the number of elements actually written. + * + * @return 0 on success, a negative error code on failure (will be returned from + * the invoking av_fifo_*_cb() function) + */ +typedef int AVFifoCB(void *opaque, void *buf, size_t *nb_elems); + +/** + * Automatically resize the FIFO on writes, so that the data fits. This + * automatic resizing happens up to a limit that can be modified with + * av_fifo_auto_grow_limit(). + */ +#define AV_FIFO_FLAG_AUTO_GROW (1 << 0) + +/** + * Allocate and initialize an AVFifo with a given element size. + * + * @param elems initial number of elements that can be stored in the FIFO + * @param elem_size Size in bytes of a single element. Further operations on + * the returned FIFO will implicitly use this element size. + * @param flags a combination of AV_FIFO_FLAG_* + * + * @return newly-allocated AVFifo on success, a negative error code on failure + */ +AVFifo *av_fifo_alloc2(size_t elems, size_t elem_size, + unsigned int flags); + +/** + * @return Element size for FIFO operations. This element size is set at + * FIFO allocation and remains constant during its lifetime + */ +size_t av_fifo_elem_size(const AVFifo *f); + +/** + * Set the maximum size (in elements) to which the FIFO can be resized + * automatically. Has no effect unless AV_FIFO_FLAG_AUTO_GROW is used. + */ +void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems); + +/** + * @return number of elements available for reading from the given FIFO. + */ +size_t av_fifo_can_read(const AVFifo *f); + +/** + * @return Number of elements that can be written into the given FIFO without + * growing it. + * + * In other words, this number of elements or less is guaranteed to fit + * into the FIFO. More data may be written when the + * AV_FIFO_FLAG_AUTO_GROW flag was specified at FIFO creation, but this + * may involve memory allocation, which can fail. + */ +size_t av_fifo_can_write(const AVFifo *f); + +/** + * Enlarge an AVFifo. + * + * On success, the FIFO will be large enough to hold exactly + * inc + av_fifo_can_read() + av_fifo_can_write() + * elements. In case of failure, the old FIFO is kept unchanged. + * + * @param f AVFifo to resize + * @param inc number of elements to allocate for, in addition to the current + * allocated size + * @return a non-negative number on success, a negative error code on failure + */ +int av_fifo_grow2(AVFifo *f, size_t inc); + +/** + * Write data into a FIFO. + * + * In case nb_elems > av_fifo_can_write(f) and the AV_FIFO_FLAG_AUTO_GROW flag + * was not specified at FIFO creation, nothing is written and an error + * is returned. + * + * Calling function is guaranteed to succeed if nb_elems <= av_fifo_can_write(f). + * + * @param f the FIFO buffer + * @param buf Data to be written. nb_elems * av_fifo_elem_size(f) bytes will be + * read from buf on success. + * @param nb_elems number of elements to write into FIFO + * + * @return a non-negative number on success, a negative error code on failure + */ +int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems); + +/** + * Write data from a user-provided callback into a FIFO. + * + * @param f the FIFO buffer + * @param read_cb Callback supplying the data to the FIFO. May be called + * multiple times. + * @param opaque opaque user data to be provided to read_cb + * @param nb_elems Should point to the maximum number of elements that can be + * written. Will be updated to contain the number of elements + * actually written. + * + * @return non-negative number on success, a negative error code on failure + */ +int av_fifo_write_from_cb(AVFifo *f, AVFifoCB read_cb, + void *opaque, size_t *nb_elems); + +/** + * Read data from a FIFO. + * + * In case nb_elems > av_fifo_can_read(f), nothing is read and an error + * is returned. + * + * @param f the FIFO buffer + * @param buf Buffer to store the data. nb_elems * av_fifo_elem_size(f) bytes + * will be written into buf on success. + * @param nb_elems number of elements to read from FIFO + * + * @return a non-negative number on success, a negative error code on failure + */ +int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems); + +/** + * Feed data from a FIFO into a user-provided callback. + * + * @param f the FIFO buffer + * @param write_cb Callback the data will be supplied to. May be called + * multiple times. + * @param opaque opaque user data to be provided to write_cb + * @param nb_elems Should point to the maximum number of elements that can be + * read. Will be updated to contain the total number of elements + * actually sent to the callback. + * + * @return non-negative number on success, a negative error code on failure + */ +int av_fifo_read_to_cb(AVFifo *f, AVFifoCB write_cb, + void *opaque, size_t *nb_elems); + +/** + * Read data from a FIFO without modifying FIFO state. + * + * Returns an error if an attempt is made to peek to nonexistent elements + * (i.e. if offset + nb_elems is larger than av_fifo_can_read(f)). + * + * @param f the FIFO buffer + * @param buf Buffer to store the data. nb_elems * av_fifo_elem_size(f) bytes + * will be written into buf. + * @param nb_elems number of elements to read from FIFO + * @param offset number of initial elements to skip. + * + * @return a non-negative number on success, a negative error code on failure + */ +int av_fifo_peek(AVFifo *f, void *buf, size_t nb_elems, size_t offset); + +/** + * Feed data from a FIFO into a user-provided callback. + * + * @param f the FIFO buffer + * @param write_cb Callback the data will be supplied to. May be called + * multiple times. + * @param opaque opaque user data to be provided to write_cb + * @param nb_elems Should point to the maximum number of elements that can be + * read. Will be updated to contain the total number of elements + * actually sent to the callback. + * @param offset number of initial elements to skip; offset + *nb_elems must not + * be larger than av_fifo_can_read(f). + * + * @return a non-negative number on success, a negative error code on failure + */ +int av_fifo_peek_to_cb(AVFifo *f, AVFifoCB write_cb, void *opaque, + size_t *nb_elems, size_t offset); + +/** + * Discard the specified amount of data from an AVFifo. + * @param size number of elements to discard, MUST NOT be larger than + * av_fifo_can_read(f) + */ +void av_fifo_drain2(AVFifo *f, size_t size); + +/* + * Empty the AVFifo. + * @param f AVFifo to reset + */ +void av_fifo_reset2(AVFifo *f); + +/** + * Free an AVFifo and reset pointer to NULL. + * @param f Pointer to an AVFifo to free. *f == NULL is allowed. + */ +void av_fifo_freep2(AVFifo **f); + + +#if FF_API_FIFO_OLD_API +typedef struct AVFifoBuffer { + uint8_t *buffer; + uint8_t *rptr, *wptr, *end; + uint32_t rndx, wndx; +} AVFifoBuffer; + +/** + * Initialize an AVFifoBuffer. + * @param size of FIFO + * @return AVFifoBuffer or NULL in case of memory allocation failure + * @deprecated use av_fifo_alloc2() + */ +attribute_deprecated +AVFifoBuffer *av_fifo_alloc(unsigned int size); + +/** + * Initialize an AVFifoBuffer. + * @param nmemb number of elements + * @param size size of the single element + * @return AVFifoBuffer or NULL in case of memory allocation failure + * @deprecated use av_fifo_alloc2() + */ +attribute_deprecated +AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size); + +/** + * Free an AVFifoBuffer. + * @param f AVFifoBuffer to free + * @deprecated use the AVFifo API with av_fifo_freep2() + */ +attribute_deprecated +void av_fifo_free(AVFifoBuffer *f); + +/** + * Free an AVFifoBuffer and reset pointer to NULL. + * @param f AVFifoBuffer to free + * @deprecated use the AVFifo API with av_fifo_freep2() + */ +attribute_deprecated +void av_fifo_freep(AVFifoBuffer **f); + +/** + * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. + * @param f AVFifoBuffer to reset + * @deprecated use av_fifo_reset2() with the new AVFifo-API + */ +attribute_deprecated +void av_fifo_reset(AVFifoBuffer *f); + +/** + * Return the amount of data in bytes in the AVFifoBuffer, that is the + * amount of data you can read from it. + * @param f AVFifoBuffer to read from + * @return size + * @deprecated use av_fifo_can_read() with the new AVFifo-API + */ +attribute_deprecated +int av_fifo_size(const AVFifoBuffer *f); + +/** + * Return the amount of space in bytes in the AVFifoBuffer, that is the + * amount of data you can write into it. + * @param f AVFifoBuffer to write into + * @return size + * @deprecated use av_fifo_can_write() with the new AVFifo-API + */ +attribute_deprecated +int av_fifo_space(const AVFifoBuffer *f); + +/** + * Feed data at specific position from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param offset offset from current read position + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + * + * @return a non-negative number on success, a negative error code on failure + * + * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL, + * av_fifo_peek_to_cb() otherwise + */ +attribute_deprecated +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + * + * @return a non-negative number on success, a negative error code on failure + * + * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL, + * av_fifo_peek_to_cb() otherwise + */ +attribute_deprecated +int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + * + * @return a non-negative number on success, a negative error code on failure + * + * @deprecated use the new AVFifo-API with av_fifo_read() when func == NULL, + * av_fifo_read_to_cb() otherwise + */ +attribute_deprecated +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from a user-supplied callback to an AVFifoBuffer. + * @param f AVFifoBuffer to write to + * @param src data source; non-const since it may be used as a + * modifiable context by the function defined in func + * @param size number of bytes to write + * @param func generic write function; the first parameter is src, + * the second is dest_buf, the third is dest_buf_size. + * func must return the number of bytes written to dest_buf, or <= 0 to + * indicate no more data available to write. + * If func is NULL, src is interpreted as a simple byte array for source data. + * @return the number of bytes written to the FIFO or a negative error code on failure + * + * @deprecated use the new AVFifo-API with av_fifo_write() when func == NULL, + * av_fifo_write_from_cb() otherwise + */ +attribute_deprecated +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); + +/** + * Resize an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * + * @param f AVFifoBuffer to resize + * @param size new AVFifoBuffer size in bytes + * @return <0 for failure, >=0 otherwise + * + * @deprecated use the new AVFifo-API with av_fifo_grow2() to increase FIFO size, + * decreasing FIFO size is not supported + */ +attribute_deprecated +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); + +/** + * Enlarge an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * The new fifo size may be larger than the requested size. + * + * @param f AVFifoBuffer to resize + * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size() + * @return <0 for failure, >=0 otherwise + * + * @deprecated use the new AVFifo-API with av_fifo_grow2(); note that unlike + * this function it adds to the allocated size, rather than to the used size + */ +attribute_deprecated +int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space); + +/** + * Read and discard the specified amount of data from an AVFifoBuffer. + * @param f AVFifoBuffer to read from + * @param size amount of data to read in bytes + * + * @deprecated use the new AVFifo-API with av_fifo_drain2() + */ +attribute_deprecated +void av_fifo_drain(AVFifoBuffer *f, int size); + +#if FF_API_FIFO_PEEK2 +/** + * Return a pointer to the data stored in a FIFO buffer at a certain offset. + * The FIFO buffer is not modified. + * + * @param f AVFifoBuffer to peek at, f must be non-NULL + * @param offs an offset in bytes, its absolute value must be less + * than the used buffer size or the returned pointer will + * point outside to the buffer data. + * The used buffer size can be checked with av_fifo_size(). + * @deprecated use the new AVFifo-API with av_fifo_peek() or av_fifo_peek_to_cb() + */ +attribute_deprecated +static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs) +{ + uint8_t *ptr = f->rptr + offs; + if (ptr >= f->end) + ptr = f->buffer + (ptr - f->end); + else if (ptr < f->buffer) + ptr = f->end - (f->buffer - ptr); + return ptr; +} +#endif +#endif + +/** + * @} + */ + +#endif /* AVUTIL_FIFO_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/file.c b/arm/raspi/third_party/ffmpeg/libavutil/file.c new file mode 100644 index 00000000..6a2f3aa9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/file.c @@ -0,0 +1,162 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "file.h" +#include "file_open.h" +#include "internal.h" +#include "log.h" +#include "mem.h" +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#if HAVE_MMAP +#include +#elif HAVE_MAPVIEWOFFILE +#include +#endif + +typedef struct FileLogContext { + const AVClass *class; + int log_offset; + void *log_ctx; +} FileLogContext; + +static const AVClass file_log_ctx_class = { + .class_name = "FILE", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(FileLogContext, log_offset), + .parent_log_context_offset = offsetof(FileLogContext, log_ctx), +}; + +int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + int log_offset, void *log_ctx) +{ + FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx }; + int err, fd = avpriv_open(filename, O_RDONLY); + struct stat st; + av_unused void *ptr; + off_t off_size; + char errbuf[128]; + *bufptr = NULL; + *size = 0; + + if (fd < 0) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf); + return err; + } + + if (fstat(fd, &st) < 0) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf); + close(fd); + return err; + } + + off_size = st.st_size; + if (off_size > SIZE_MAX) { + av_log(&file_log_ctx, AV_LOG_ERROR, + "File size for file '%s' is too big\n", filename); + close(fd); + return AVERROR(EINVAL); + } + *size = off_size; + + if (!*size) { + *bufptr = NULL; + goto out; + } + +#if HAVE_MMAP + ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + if (ptr == MAP_FAILED) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf); + close(fd); + *size = 0; + return err; + } + *bufptr = ptr; +#elif HAVE_MAPVIEWOFFILE + { + HANDLE mh, fh = (HANDLE)_get_osfhandle(fd); + + mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL); + if (!mh) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping()\n"); + close(fd); + *size = 0; + return -1; + } + + ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size); + CloseHandle(mh); + if (!ptr) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n"); + close(fd); + *size = 0; + return -1; + } + + *bufptr = ptr; + } +#else + *bufptr = av_malloc(*size); + if (!*bufptr) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n"); + close(fd); + *size = 0; + return AVERROR(ENOMEM); + } + read(fd, *bufptr, *size); +#endif + +out: + close(fd); + return 0; +} + +void av_file_unmap(uint8_t *bufptr, size_t size) +{ + if (!size || !bufptr) + return; +#if HAVE_MMAP + munmap(bufptr, size); +#elif HAVE_MAPVIEWOFFILE + UnmapViewOfFile(bufptr); +#else + av_free(bufptr); +#endif +} + +#if FF_API_AV_FOPEN_UTF8 +int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) { + return avpriv_tempfile(prefix, filename, log_offset, log_ctx); +} +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/file.h b/arm/raspi/third_party/ffmpeg/libavutil/file.h new file mode 100644 index 00000000..fc87a9cd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/file.h @@ -0,0 +1,80 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FILE_H +#define AVUTIL_FILE_H + +#include +#include + +#include "version.h" +#include "attributes.h" + +/** + * @file + * Misc file utilities. + */ + +/** + * Read the file with name filename, and put its content in a newly + * allocated buffer or map it with mmap() when available. + * In case of success set *bufptr to the read or mmapped buffer, and + * *size to the size in bytes of the buffer in *bufptr. + * Unlike mmap this function succeeds with zero sized files, in this + * case *bufptr will be set to NULL and *size will be set to 0. + * The returned buffer must be released with av_file_unmap(). + * + * @param filename path to the file + * @param[out] bufptr pointee is set to the mapped or allocated buffer + * @param[out] size pointee is set to the size in bytes of the buffer + * @param log_offset loglevel offset used for logging + * @param log_ctx context used for logging + * @return a non negative number in case of success, a negative value + * corresponding to an AVERROR error code in case of failure + */ +av_warn_unused_result +int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + int log_offset, void *log_ctx); + +/** + * Unmap or free the buffer bufptr created by av_file_map(). + * + * @param bufptr the buffer previously created with av_file_map() + * @param size size in bytes of bufptr, must be the same as returned + * by av_file_map() + */ +void av_file_unmap(uint8_t *bufptr, size_t size); + +#if FF_API_AV_FOPEN_UTF8 +/** + * Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or negative value corresponding to an + * AVERROR code on error) + * and opened file name in **filename. + * @note On very old libcs it is necessary to set a secure umask before + * calling this, av_tempfile() can't call umask itself as it is used in + * libraries and could interfere with the calling application. + * @deprecated as fd numbers cannot be passed saftely between libs on some platforms + */ +attribute_deprecated +int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx); +#endif + +#endif /* AVUTIL_FILE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/file_open.c b/arm/raspi/third_party/ffmpeg/libavutil/file_open.c new file mode 100644 index 00000000..9aa4e4ac --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/file_open.c @@ -0,0 +1,198 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "avutil.h" +#include "file_open.h" +#include "mem.h" +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif + +#ifdef _WIN32 +#undef open +#undef lseek +#undef stat +#undef fstat +#include +#include +#include +#include "wchar_filename.h" + +static int win32_open(const char *filename_utf8, int oflag, int pmode) +{ + int fd; + wchar_t *filename_w; + + /* convert UTF-8 to wide chars */ + if (get_extended_win32_path(filename_utf8, &filename_w)) + return -1; + if (!filename_w) + goto fallback; + + fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode); + av_freep(&filename_w); + + if (fd != -1 || (oflag & O_CREAT)) + return fd; + +fallback: + /* filename may be in CP_ACP */ + return _sopen(filename_utf8, oflag, SH_DENYNO, pmode); +} +#define open win32_open +#endif + +int avpriv_open(const char *filename, int flags, ...) +{ + int fd; + unsigned int mode = 0; + va_list ap; + + va_start(ap, flags); + if (flags & O_CREAT) + mode = va_arg(ap, unsigned int); + va_end(ap); + +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif +#ifdef O_NOINHERIT + flags |= O_NOINHERIT; +#endif + + fd = open(filename, flags, mode); +#if HAVE_FCNTL + if (fd != -1) { + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n"); + } +#endif + + return fd; +} + +typedef struct FileLogContext { + const AVClass *class; + int log_offset; + void *log_ctx; +} FileLogContext; + +static const AVClass file_log_ctx_class = { + .class_name = "TEMPFILE", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(FileLogContext, log_offset), + .parent_log_context_offset = offsetof(FileLogContext, log_ctx), +}; + +int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) +{ + FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx }; + int fd = -1; +#if !HAVE_MKSTEMP + void *ptr= tempnam(NULL, prefix); + if(!ptr) + ptr= tempnam(".", prefix); + *filename = av_strdup(ptr); +#undef free + free(ptr); +#else + size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ + *filename = av_malloc(len); +#endif + /* -----common section-----*/ + if (!*filename) { + av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); + return AVERROR(ENOMEM); + } +#if !HAVE_MKSTEMP +# ifndef O_BINARY +# define O_BINARY 0 +# endif +# ifndef O_EXCL +# define O_EXCL 0 +# endif + fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600); +#else + snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); + fd = mkstemp(*filename); +#if defined(_WIN32) || defined (__ANDROID__) || defined(__DJGPP__) + if (fd < 0) { + snprintf(*filename, len, "./%sXXXXXX", prefix); + fd = mkstemp(*filename); + } +#endif +#endif + /* -----common section-----*/ + if (fd < 0) { + int err = AVERROR(errno); + av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); + av_freep(filename); + return err; + } + return fd; /* success */ +} + +FILE *avpriv_fopen_utf8(const char *path, const char *mode) +{ + int fd; + int access; + const char *m = mode; + + switch (*m++) { + case 'r': access = O_RDONLY; break; + case 'w': access = O_CREAT|O_WRONLY|O_TRUNC; break; + case 'a': access = O_CREAT|O_WRONLY|O_APPEND; break; + default : + errno = EINVAL; + return NULL; + } + while (*m) { + if (*m == '+') { + access &= ~(O_RDONLY | O_WRONLY); + access |= O_RDWR; + } else if (*m == 'b') { +#ifdef O_BINARY + access |= O_BINARY; +#endif + } else if (*m) { + errno = EINVAL; + return NULL; + } + m++; + } + fd = avpriv_open(path, access, 0666); + if (fd == -1) + return NULL; + return fdopen(fd, mode); +} + +#if FF_API_AV_FOPEN_UTF8 +FILE *av_fopen_utf8(const char *path, const char *mode) +{ + return avpriv_fopen_utf8(path, mode); +} +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/file_open.h b/arm/raspi/third_party/ffmpeg/libavutil/file_open.h new file mode 100644 index 00000000..6a000047 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/file_open.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FILE_OPEN_H +#define AVUTIL_FILE_OPEN_H + +#include + +#include "config.h" +#include "attributes.h" + +#if HAVE_LIBC_MSVCRT +#define avpriv_fopen_utf8 ff_fopen_utf8 +#define avpriv_open ff_open +#define avpriv_tempfile ff_tempfile +#endif + + /** + * A wrapper for open() setting O_CLOEXEC. + */ +av_warn_unused_result +int avpriv_open(const char *filename, int flags, ...); + +/** + * Open a file using a UTF-8 filename. + */ +FILE *avpriv_fopen_utf8(const char *path, const char *mode); + +/** + * Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or negative value corresponding to an + * AVERROR code on error) + * and opened file name in **filename. + * @note On very old libcs it is necessary to set a secure umask before + * calling this, av_tempfile() can't call umask itself as it is used in + * libraries and could interfere with the calling application. + */ +int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx); + +#endif /* AVUTIL_FILE_OPEN_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.c b/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.c new file mode 100644 index 00000000..930d23c7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.c @@ -0,0 +1,42 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "film_grain_params.h" + +AVFilmGrainParams *av_film_grain_params_alloc(size_t *size) +{ + AVFilmGrainParams *params = av_mallocz(sizeof(AVFilmGrainParams)); + + if (size) + *size = sizeof(*params); + + return params; +} + +AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_FILM_GRAIN_PARAMS, + sizeof(AVFilmGrainParams)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVFilmGrainParams)); + + return (AVFilmGrainParams *)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.h b/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.h new file mode 100644 index 00000000..f3bd0a4a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/film_grain_params.h @@ -0,0 +1,260 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FILM_GRAIN_PARAMS_H +#define AVUTIL_FILM_GRAIN_PARAMS_H + +#include "frame.h" + +enum AVFilmGrainParamsType { + AV_FILM_GRAIN_PARAMS_NONE = 0, + + /** + * The union is valid when interpreted as AVFilmGrainAOMParams (codec.aom) + */ + AV_FILM_GRAIN_PARAMS_AV1, + + /** + * The union is valid when interpreted as AVFilmGrainH274Params (codec.h274) + */ + AV_FILM_GRAIN_PARAMS_H274, +}; + +/** + * This structure describes how to handle film grain synthesis for AOM codecs. + * + * @note The struct must be allocated as part of AVFilmGrainParams using + * av_film_grain_params_alloc(). Its size is not a part of the public ABI. + */ +typedef struct AVFilmGrainAOMParams { + /** + * Number of points, and the scale and value for each point of the + * piecewise linear scaling function for the uma plane. + */ + int num_y_points; + uint8_t y_points[14][2 /* value, scaling */]; + + /** + * Signals whether to derive the chroma scaling function from the luma. + * Not equivalent to copying the luma values and scales. + */ + int chroma_scaling_from_luma; + + /** + * If chroma_scaling_from_luma is set to 0, signals the chroma scaling + * function parameters. + */ + int num_uv_points[2 /* cb, cr */]; + uint8_t uv_points[2 /* cb, cr */][10][2 /* value, scaling */]; + + /** + * Specifies the shift applied to the chroma components. For AV1, its within + * [8; 11] and determines the range and quantization of the film grain. + */ + int scaling_shift; + + /** + * Specifies the auto-regression lag. + */ + int ar_coeff_lag; + + /** + * Luma auto-regression coefficients. The number of coefficients is given by + * 2 * ar_coeff_lag * (ar_coeff_lag + 1). + */ + int8_t ar_coeffs_y[24]; + + /** + * Chroma auto-regression coefficients. The number of coefficients is given by + * 2 * ar_coeff_lag * (ar_coeff_lag + 1) + !!num_y_points. + */ + int8_t ar_coeffs_uv[2 /* cb, cr */][25]; + + /** + * Specifies the range of the auto-regressive coefficients. Values of 6, + * 7, 8 and so on represent a range of [-2, 2), [-1, 1), [-0.5, 0.5) and + * so on. For AV1 must be between 6 and 9. + */ + int ar_coeff_shift; + + /** + * Signals the down shift applied to the generated gaussian numbers during + * synthesis. + */ + int grain_scale_shift; + + /** + * Specifies the luma/chroma multipliers for the index to the component + * scaling function. + */ + int uv_mult[2 /* cb, cr */]; + int uv_mult_luma[2 /* cb, cr */]; + + /** + * Offset used for component scaling function. For AV1 its a 9-bit value + * with a range [-256, 255] + */ + int uv_offset[2 /* cb, cr */]; + + /** + * Signals whether to overlap film grain blocks. + */ + int overlap_flag; + + /** + * Signals to clip to limited color levels after film grain application. + */ + int limit_output_range; +} AVFilmGrainAOMParams; + +/** + * This structure describes how to handle film grain synthesis for codecs using + * the ITU-T H.274 Versatile suplemental enhancement information message. + * + * @note The struct must be allocated as part of AVFilmGrainParams using + * av_film_grain_params_alloc(). Its size is not a part of the public ABI. + */ +typedef struct AVFilmGrainH274Params { + /** + * Specifies the film grain simulation mode. + * 0 = Frequency filtering, 1 = Auto-regression + */ + int model_id; + + /** + * Specifies the bit depth used for the luma component. + */ + int bit_depth_luma; + + /** + * Specifies the bit depth used for the chroma components. + */ + int bit_depth_chroma; + + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace color_space; + + /** + * Specifies the blending mode used to blend the simulated film grain + * with the decoded images. + * + * 0 = Additive, 1 = Multiplicative + */ + int blending_mode_id; + + /** + * Specifies a scale factor used in the film grain characterization equations. + */ + int log2_scale_factor; + + /** + * Indicates if the modelling of film grain for a given component is present. + */ + int component_model_present[3 /* y, cb, cr */]; + + /** + * Specifies the number of intensity intervals for which a specific set of + * model values has been estimated, with a range of [1, 256]. + */ + uint16_t num_intensity_intervals[3 /* y, cb, cr */]; + + /** + * Specifies the number of model values present for each intensity interval + * in which the film grain has been modelled, with a range of [1, 6]. + */ + uint8_t num_model_values[3 /* y, cb, cr */]; + + /** + * Specifies the lower ounds of each intensity interval for whichthe set of + * model values applies for the component. + */ + uint8_t intensity_interval_lower_bound[3 /* y, cb, cr */][256 /* intensity interval */]; + + /** + * Specifies the upper bound of each intensity interval for which the set of + * model values applies for the component. + */ + uint8_t intensity_interval_upper_bound[3 /* y, cb, cr */][256 /* intensity interval */]; + + /** + * Specifies the model values for the component for each intensity interval. + * - When model_id == 0, the following applies: + * For comp_model_value[y], the range of values is [0, 2^bit_depth_luma - 1] + * For comp_model_value[cb..cr], the range of values is [0, 2^bit_depth_chroma - 1] + * - Otherwise, the following applies: + * For comp_model_value[y], the range of values is [-2^(bit_depth_luma - 1), 2^(bit_depth_luma - 1) - 1] + * For comp_model_value[cb..cr], the range of values is [-2^(bit_depth_chroma - 1), 2^(bit_depth_chroma - 1) - 1] + */ + int16_t comp_model_value[3 /* y, cb, cr */][256 /* intensity interval */][6 /* model value */]; +} AVFilmGrainH274Params; + +/** + * This structure describes how to handle film grain synthesis in video + * for specific codecs. Must be present on every frame where film grain is + * meant to be synthesised for correct presentation. + * + * @note The struct must be allocated with av_film_grain_params_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVFilmGrainParams { + /** + * Specifies the codec for which this structure is valid. + */ + enum AVFilmGrainParamsType type; + + /** + * Seed to use for the synthesis process, if the codec allows for it. + * + * @note For H.264, this refers to `pic_offset` as defined in + * SMPTE RDD 5-2006. + */ + uint64_t seed; + + /** + * Additional fields may be added both here and in any structure included. + * If a codec's film grain structure differs slightly over another + * codec's, fields within may change meaning depending on the type. + */ + union { + AVFilmGrainAOMParams aom; + AVFilmGrainH274Params h274; + } codec; +} AVFilmGrainParams; + +/** + * Allocate an AVFilmGrainParams structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * If size is not NULL it will be set to the number of bytes allocated. + * + * @return An AVFilmGrainParams filled with default values or NULL + * on failure. + */ +AVFilmGrainParams *av_film_grain_params_alloc(size_t *size); + +/** + * Allocate a complete AVFilmGrainParams and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVFilmGrainParams structure to be filled by caller. + */ +AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_FILM_GRAIN_PARAMS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.c b/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.c new file mode 100644 index 00000000..5ab47d55 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * 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. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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. + * + * Author: Nedeljko Babic (nedeljko.babic imgtec com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "common.h" +#include "fixed_dsp.h" + +static void vector_fmul_add_c(int *dst, const int *src0, const int *src1, const int *src2, int len){ + int i; + int64_t accu; + + for (i=0; i> 31); + } +} + +static void vector_fmul_reverse_c(int *dst, const int *src0, const int *src1, int len) +{ + int i; + int64_t accu; + + src1 += len-1; + for (i=0; i> 31); + } +} + +static void vector_fmul_window_scaled_c(int16_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len, uint8_t bits) +{ + int32_t s0, s1, wi, wj, i,j, round; + + dst += len; + win += len; + src0+= len; + round = bits? 1 << (bits-1) : 0; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = av_clip_int16(((((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31) + round) >> bits); + dst[j] = av_clip_int16(((((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31) + round) >> bits); + } +} + +static void vector_fmul_window_c(int32_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len) +{ + int32_t s0, s1, wi, wj, i, j; + + dst += len; + win += len; + src0+= len; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = ((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31; + dst[j] = ((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31; + } +} + +static void vector_fmul_c(int *dst, const int *src0, const int *src1, int len) +{ + int i; + int64_t accu; + + for (i = 0; i < len; i++){ + accu = (int64_t)src0[i] * src1[i]; + dst[i] = (int)((accu+0x40000000) >> 31); + } +} + +static int scalarproduct_fixed_c(const int *v1, const int *v2, int len) +{ + /** p is initialized with 0x40000000 so that the proper rounding will occur + * at the end */ + int64_t p = 0x40000000; + int i; + + for (i = 0; i < len; i++) + p += (int64_t)v1[i] * v2[i]; + + return (int)(p >> 31); +} + +static void butterflies_fixed_c(int *av_restrict v1s, int *av_restrict v2, int len) +{ + int i; + unsigned int *v1 = v1s; + + for (i = 0; i < len; i++){ + int t = v1[i] - v2[i]; + v1[i] += v2[i]; + v2[i] = t; + } +} + +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int bit_exact) +{ + AVFixedDSPContext * fdsp = av_malloc(sizeof(AVFixedDSPContext)); + + if (!fdsp) + return NULL; + + fdsp->vector_fmul_window_scaled = vector_fmul_window_scaled_c; + fdsp->vector_fmul_window = vector_fmul_window_c; + fdsp->vector_fmul = vector_fmul_c; + fdsp->vector_fmul_add = vector_fmul_add_c; + fdsp->vector_fmul_reverse = vector_fmul_reverse_c; + fdsp->butterflies_fixed = butterflies_fixed_c; + fdsp->scalarproduct_fixed = scalarproduct_fixed_c; + +#if ARCH_RISCV + ff_fixed_dsp_init_riscv(fdsp); +#elif ARCH_X86 + ff_fixed_dsp_init_x86(fdsp); +#endif + + return fdsp; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.h b/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.h new file mode 100644 index 00000000..1217d3a5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/fixed_dsp.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * 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. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FIXED_DSP_H +#define AVUTIL_FIXED_DSP_H + +#include +#include "config.h" +#include "attributes.h" +#include "libavcodec/mathops.h" + +typedef struct AVFixedDSPContext { + /* Assume len is a multiple of 16, and arrays are 32-byte aligned */ + /* Results of multiplications are scaled down by 31 bit (and rounded) if not + * stated otherwise */ + + /** + * Overlap/add with window function. + * Result is scaled down by "bits" bits. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + * @param bits scaling parameter + * + */ + void (*vector_fmul_window_scaled)(int16_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len, uint8_t bits); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(int32_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len); + + /** + * Fixed-point multiplication that calculates the entry wise product of two + * vectors of integers and stores the result in a vector of integers. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul)(int *dst, const int *src0, const int *src1, + int len); + + void (*vector_fmul_reverse)(int *dst, const int *src0, const int *src1, int len); + /** + * Calculate the entry wise product of two vectors of integers, add a third vector of + * integers and store the result in a vector of integers. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param src2 third input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_add)(int *dst, const int *src0, const int *src1, + const int *src2, int len); + + /** + * Calculate the scalar product of two vectors of integers. + * + * @param v1 first vector, 16-byte aligned + * @param v2 second vector, 16-byte aligned + * @param len length of vectors, multiple of 4 + * + * @return sum of elementwise products + */ + int (*scalarproduct_fixed)(const int *v1, const int *v2, int len); + + /** + * Calculate the sum and difference of two vectors of integers. + * + * @param v1 first input vector, sum output, 16-byte aligned + * @param v2 second input vector, difference output, 16-byte aligned + * @param len length of vectors, multiple of 4 + */ + void (*butterflies_fixed)(int *av_restrict v1, int *av_restrict v2, int len); +} AVFixedDSPContext; + +/** + * Allocate and initialize a fixed DSP context. + * note: should be freed with a av_free call when no longer needed. + * + * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant + */ +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int strict); + +void ff_fixed_dsp_init_riscv(AVFixedDSPContext *fdsp); +void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp); + +/** + * Calculate the square root + * + * @param x input fixed point number + * + * @param bits format of fixed point number (32 - bits).bits + * + * note: input is normalized to (0, 1) fixed point value + */ + +static av_always_inline int fixed_sqrt(int x, int bits) +{ + int retval, bit_mask, guess, square, i; + int64_t accu; + int shift1 = 30 - bits; + int shift2 = bits - 15; + + if (shift1 > 0) retval = ff_sqrt(x << shift1); + else retval = ff_sqrt(x >> -shift1); + + if (shift2 > 0) { + retval = retval << shift2; + bit_mask = (1 << (shift2 - 1)); + + for (i=0; i> bits); + if (x >= square) + retval += bit_mask; + bit_mask >>= 1; + } + + } + else retval >>= (-shift2); + + return retval; +} + +#endif /* AVUTIL_FIXED_DSP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/float2half.c b/arm/raspi/third_party/ffmpeg/libavutil/float2half.c new file mode 100644 index 00000000..1a283956 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/float2half.c @@ -0,0 +1,55 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/float2half.h" + +void ff_init_float2half_tables(Float2HalfTables *t) +{ +#if !HAVE_FAST_FLOAT16 + for (int i = 0; i < 256; i++) { + int e = i - 127; + + if (e < -24) { // Very small numbers map to zero + t->basetable[i|0x000] = 0x0000; + t->basetable[i|0x100] = 0x8000; + t->shifttable[i|0x000] = 24; + t->shifttable[i|0x100] = 24; + } else if (e < -14) { // Small numbers map to denorms + t->basetable[i|0x000] = (0x0400>>(-e-14)); + t->basetable[i|0x100] = (0x0400>>(-e-14)) | 0x8000; + t->shifttable[i|0x000] = -e-1; + t->shifttable[i|0x100] = -e-1; + } else if (e <= 15) { // Normal numbers just lose precision + t->basetable[i|0x000] = ((e + 15) << 10); + t->basetable[i|0x100] = ((e + 15) << 10) | 0x8000; + t->shifttable[i|0x000] = 13; + t->shifttable[i|0x100] = 13; + } else if (e < 128) { // Large numbers map to Infinity + t->basetable[i|0x000] = 0x7C00; + t->basetable[i|0x100] = 0xFC00; + t->shifttable[i|0x000] = 24; + t->shifttable[i|0x100] = 24; + } else { // Infinity and NaN's stay Infinity and NaN's + t->basetable[i|0x000] = 0x7C00; + t->basetable[i|0x100] = 0xFC00; + t->shifttable[i|0x000] = 13; + t->shifttable[i|0x100] = 13; + } + } +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/float2half.h b/arm/raspi/third_party/ffmpeg/libavutil/float2half.h new file mode 100644 index 00000000..e6190469 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/float2half.h @@ -0,0 +1,56 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FLOAT2HALF_H +#define AVUTIL_FLOAT2HALF_H + +#include +#include "intfloat.h" + +#include "config.h" + +typedef struct Float2HalfTables { +#if HAVE_FAST_FLOAT16 + uint8_t dummy; +#else + uint16_t basetable[512]; + uint8_t shifttable[512]; +#endif +} Float2HalfTables; + +void ff_init_float2half_tables(Float2HalfTables *t); + +static inline uint16_t float2half(uint32_t f, const Float2HalfTables *t) +{ +#if HAVE_FAST_FLOAT16 + union { + _Float16 f; + uint16_t i; + } u; + u.f = av_int2float(f); + return u.i; +#else + uint16_t h; + + h = t->basetable[(f >> 23) & 0x1ff] + ((f & 0x007fffff) >> t->shifttable[(f >> 23) & 0x1ff]); + + return h; +#endif +} + +#endif /* AVUTIL_FLOAT2HALF_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.c b/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.c new file mode 100644 index 00000000..742dd679 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.c @@ -0,0 +1,167 @@ +/* + * Copyright 2005 Balatoni Denes + * Copyright 2006 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "attributes.h" +#include "float_dsp.h" +#include "mem.h" + +static void vector_fmul_c(float *dst, const float *src0, const float *src1, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i]; +} + +static void vector_dmul_c(double *dst, const double *src0, const double *src1, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i]; +} + +static void vector_fmac_scalar_c(float *dst, const float *src, float mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] += src[i] * mul; +} + +static void vector_dmac_scalar_c(double *dst, const double *src, double mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] += src[i] * mul; +} + +static void vector_fmul_scalar_c(float *dst, const float *src, float mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src[i] * mul; +} + +static void vector_dmul_scalar_c(double *dst, const double *src, double mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src[i] * mul; +} + +static void vector_fmul_window_c(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + int i, j; + + dst += len; + win += len; + src0 += len; + + for (i = -len, j = len - 1; i < 0; i++, j--) { + float s0 = src0[i]; + float s1 = src1[j]; + float wi = win[i]; + float wj = win[j]; + dst[i] = s0 * wj - s1 * wi; + dst[j] = s0 * wi + s1 * wj; + } +} + +static void vector_fmul_add_c(float *dst, const float *src0, const float *src1, + const float *src2, int len){ + int i; + + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i] + src2[i]; +} + +static void vector_fmul_reverse_c(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + + src1 += len-1; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[-i]; +} + +static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2, + int len) +{ + int i; + + for (i = 0; i < len; i++) { + float t = v1[i] - v2[i]; + v1[i] += v2[i]; + v2[i] = t; + } +} + +float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len) +{ + float p = 0.0; + int i; + + for (i = 0; i < len; i++) + p += v1[i] * v2[i]; + + return p; +} + +av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact) +{ + AVFloatDSPContext *fdsp = av_mallocz(sizeof(AVFloatDSPContext)); + if (!fdsp) + return NULL; + + fdsp->vector_fmul = vector_fmul_c; + fdsp->vector_dmul = vector_dmul_c; + fdsp->vector_fmac_scalar = vector_fmac_scalar_c; + fdsp->vector_fmul_scalar = vector_fmul_scalar_c; + fdsp->vector_dmac_scalar = vector_dmac_scalar_c; + fdsp->vector_dmul_scalar = vector_dmul_scalar_c; + fdsp->vector_fmul_window = vector_fmul_window_c; + fdsp->vector_fmul_add = vector_fmul_add_c; + fdsp->vector_fmul_reverse = vector_fmul_reverse_c; + fdsp->butterflies_float = butterflies_float_c; + fdsp->scalarproduct_float = avpriv_scalarproduct_float_c; + +#if ARCH_AARCH64 + ff_float_dsp_init_aarch64(fdsp); +#elif ARCH_ARM + ff_float_dsp_init_arm(fdsp); +#elif ARCH_PPC + ff_float_dsp_init_ppc(fdsp, bit_exact); +#elif ARCH_RISCV + ff_float_dsp_init_riscv(fdsp); +#elif ARCH_X86 + ff_float_dsp_init_x86(fdsp); +#elif ARCH_MIPS + ff_float_dsp_init_mips(fdsp); +#endif + return fdsp; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.h b/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.h new file mode 100644 index 00000000..7cad9fc6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/float_dsp.h @@ -0,0 +1,219 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FLOAT_DSP_H +#define AVUTIL_FLOAT_DSP_H + +#include "config.h" + +typedef struct AVFloatDSPContext { + /** + * Calculate the entry wise product of two vectors of floats and store the result in + * a vector of floats. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul)(float *dst, const float *src0, const float *src1, + int len); + + /** + * Multiply a vector of floats by a scalar float and add to + * destination vector. Source and destination vectors must + * overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 16 + */ + void (*vector_fmac_scalar)(float *dst, const float *src, float mul, + int len); + + /** + * Multiply a vector of doubles by a scalar double and add to + * destination vector. Source and destination vectors must + * overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 16 + */ + void (*vector_dmac_scalar)(double *dst, const double *src, double mul, + int len); + + /** + * Multiply a vector of floats by a scalar float. Source and + * destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src input vector + * constraints: 16-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_scalar)(float *dst, const float *src, float mul, + int len); + + /** + * Multiply a vector of double by a scalar double. Source and + * destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 8 + */ + void (*vector_dmul_scalar)(double *dst, const double *src, double mul, + int len); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(float *dst, const float *src0, + const float *src1, const float *win, int len); + + /** + * Calculate the entry wise product of two vectors of floats, add a third vector of + * floats and store the result in a vector of floats. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param src2 third input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, + const float *src2, int len); + + /** + * Calculate the entry wise product of two vectors of floats, and store the result + * in a vector of floats. The second vector of floats is iterated over + * in reverse order. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_reverse)(float *dst, const float *src0, + const float *src1, int len); + + /** + * Calculate the sum and difference of two vectors of floats. + * + * @param v1 first input vector, sum output, 16-byte aligned + * @param v2 second input vector, difference output, 16-byte aligned + * @param len length of vectors, multiple of 4 + */ + void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len); + + /** + * Calculate the scalar product of two vectors of floats. + * + * @param v1 first vector, 16-byte aligned + * @param v2 second vector, 16-byte aligned + * @param len length of vectors, multiple of 4 + * + * @return sum of elementwise products + */ + float (*scalarproduct_float)(const float *v1, const float *v2, int len); + + /** + * Calculate the entry wise product of two vectors of doubles and store the result in + * a vector of doubles. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_dmul)(double *dst, const double *src0, const double *src1, + int len); +} AVFloatDSPContext; + +/** + * Return the scalar product of two vectors. + * + * @param v1 first input vector + * @param v2 first input vector + * @param len number of elements + * + * @return sum of elementwise products + */ +float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len); + +void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict); +void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp); + +/** + * Allocate a float DSP context. + * + * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant + */ +AVFloatDSPContext *avpriv_float_dsp_alloc(int strict); + +#endif /* AVUTIL_FLOAT_DSP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/frame.c b/arm/raspi/third_party/ffmpeg/libavutil/frame.c new file mode 100644 index 00000000..fa9b11aa --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/frame.c @@ -0,0 +1,937 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "channel_layout.h" +#include "avassert.h" +#include "buffer.h" +#include "common.h" +#include "cpu.h" +#include "dict.h" +#include "frame.h" +#include "imgutils.h" +#include "mem.h" +#include "samplefmt.h" +#include "hwcontext.h" + +#if FF_API_OLD_CHANNEL_LAYOUT +#define CHECK_CHANNELS_CONSISTENCY(frame) \ + av_assert2(!(frame)->channel_layout || \ + (frame)->channels == \ + av_get_channel_layout_nb_channels((frame)->channel_layout)) +#endif + +#if FF_API_COLORSPACE_NAME +const char *av_get_colorspace_name(enum AVColorSpace val) +{ + static const char * const name[] = { + [AVCOL_SPC_RGB] = "GBR", + [AVCOL_SPC_BT709] = "bt709", + [AVCOL_SPC_FCC] = "fcc", + [AVCOL_SPC_BT470BG] = "bt470bg", + [AVCOL_SPC_SMPTE170M] = "smpte170m", + [AVCOL_SPC_SMPTE240M] = "smpte240m", + [AVCOL_SPC_YCOCG] = "YCgCo", + }; + if ((unsigned)val >= FF_ARRAY_ELEMS(name)) + return NULL; + return name[val]; +} +#endif +static void get_frame_defaults(AVFrame *frame) +{ + memset(frame, 0, sizeof(*frame)); + + frame->pts = + frame->pkt_dts = AV_NOPTS_VALUE; + frame->best_effort_timestamp = AV_NOPTS_VALUE; + frame->duration = 0; +#if FF_API_PKT_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_duration = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pkt_pos = -1; + frame->pkt_size = -1; + frame->time_base = (AVRational){ 0, 1 }; + frame->key_frame = 1; + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + frame->format = -1; /* unknown */ + frame->extended_data = frame->data; + frame->color_primaries = AVCOL_PRI_UNSPECIFIED; + frame->color_trc = AVCOL_TRC_UNSPECIFIED; + frame->colorspace = AVCOL_SPC_UNSPECIFIED; + frame->color_range = AVCOL_RANGE_UNSPECIFIED; + frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + frame->flags = 0; +} + +static void free_side_data(AVFrameSideData **ptr_sd) +{ + AVFrameSideData *sd = *ptr_sd; + + av_buffer_unref(&sd->buf); + av_dict_free(&sd->metadata); + av_freep(ptr_sd); +} + +static void wipe_side_data(AVFrame *frame) +{ + int i; + + for (i = 0; i < frame->nb_side_data; i++) { + free_side_data(&frame->side_data[i]); + } + frame->nb_side_data = 0; + + av_freep(&frame->side_data); +} + +AVFrame *av_frame_alloc(void) +{ + AVFrame *frame = av_malloc(sizeof(*frame)); + + if (!frame) + return NULL; + + get_frame_defaults(frame); + + return frame; +} + +void av_frame_free(AVFrame **frame) +{ + if (!frame || !*frame) + return; + + av_frame_unref(*frame); + av_freep(frame); +} + +static int get_video_buffer(AVFrame *frame, int align) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int ret, i, padded_height, total_size; + int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); + ptrdiff_t linesizes[4]; + size_t sizes[4]; + + if (!desc) + return AVERROR(EINVAL); + + if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) + return ret; + + if (!frame->linesize[0]) { + if (align <= 0) + align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */ + + for(i=1; i<=align; i+=i) { + ret = av_image_fill_linesizes(frame->linesize, frame->format, + FFALIGN(frame->width, i)); + if (ret < 0) + return ret; + if (!(frame->linesize[0] & (align-1))) + break; + } + + for (i = 0; i < 4 && frame->linesize[i]; i++) + frame->linesize[i] = FFALIGN(frame->linesize[i], align); + } + + for (i = 0; i < 4; i++) + linesizes[i] = frame->linesize[i]; + + padded_height = FFALIGN(frame->height, 32); + if ((ret = av_image_fill_plane_sizes(sizes, frame->format, + padded_height, linesizes)) < 0) + return ret; + + total_size = 4*plane_padding; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - total_size) + return AVERROR(EINVAL); + total_size += sizes[i]; + } + + frame->buf[0] = av_buffer_alloc(total_size); + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + frame->buf[0]->data, frame->linesize)) < 0) + goto fail; + + for (i = 1; i < 4; i++) { + if (frame->data[i]) + frame->data[i] += i * plane_padding; + } + + frame->extended_data = frame->data; + + return 0; +fail: + av_frame_unref(frame); + return ret; +} + +static int get_audio_buffer(AVFrame *frame, int align) +{ + int planar = av_sample_fmt_is_planar(frame->format); + int channels, planes; + int ret, i; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!frame->ch_layout.nb_channels) { + if (frame->channel_layout) { + av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout); + } else { + frame->ch_layout.nb_channels = frame->channels; + frame->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + } + } + frame->channels = frame->ch_layout.nb_channels; + frame->channel_layout = frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ? + frame->ch_layout.u.mask : 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + channels = frame->ch_layout.nb_channels; + planes = planar ? channels : 1; + if (!frame->linesize[0]) { + ret = av_samples_get_buffer_size(&frame->linesize[0], channels, + frame->nb_samples, frame->format, + align); + if (ret < 0) + return ret; + } + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_calloc(planes, + sizeof(*frame->extended_data)); + frame->extended_buf = av_calloc(planes - AV_NUM_DATA_POINTERS, + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + } else + frame->extended_data = frame->data; + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_alloc(frame->linesize[0]); + if (!frame->buf[i]) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) { + frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]); + if (!frame->extended_buf[i]) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + return 0; + +} + +int av_frame_get_buffer(AVFrame *frame, int align) +{ + if (frame->format < 0) + return AVERROR(EINVAL); + +FF_DISABLE_DEPRECATION_WARNINGS + if (frame->width > 0 && frame->height > 0) + return get_video_buffer(frame, align); + else if (frame->nb_samples > 0 && + (av_channel_layout_check(&frame->ch_layout) +#if FF_API_OLD_CHANNEL_LAYOUT + || frame->channel_layout || frame->channels > 0 +#endif + )) + return get_audio_buffer(frame, align); +FF_ENABLE_DEPRECATION_WARNINGS + + return AVERROR(EINVAL); +} + +static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) +{ + int ret, i; + + dst->key_frame = src->key_frame; + dst->pict_type = src->pict_type; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->crop_top = src->crop_top; + dst->crop_bottom = src->crop_bottom; + dst->crop_left = src->crop_left; + dst->crop_right = src->crop_right; + dst->pts = src->pts; + dst->duration = src->duration; + dst->repeat_pict = src->repeat_pict; + dst->interlaced_frame = src->interlaced_frame; + dst->top_field_first = src->top_field_first; + dst->palette_has_changed = src->palette_has_changed; + dst->sample_rate = src->sample_rate; + dst->opaque = src->opaque; + dst->pkt_dts = src->pkt_dts; + dst->pkt_pos = src->pkt_pos; + dst->pkt_size = src->pkt_size; +#if FF_API_PKT_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + dst->pkt_duration = src->pkt_duration; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + dst->time_base = src->time_base; + dst->reordered_opaque = src->reordered_opaque; + dst->quality = src->quality; + dst->best_effort_timestamp = src->best_effort_timestamp; + dst->coded_picture_number = src->coded_picture_number; + dst->display_picture_number = src->display_picture_number; + dst->flags = src->flags; + dst->decode_error_flags = src->decode_error_flags; + dst->color_primaries = src->color_primaries; + dst->color_trc = src->color_trc; + dst->colorspace = src->colorspace; + dst->color_range = src->color_range; + dst->chroma_location = src->chroma_location; + + av_dict_copy(&dst->metadata, src->metadata, 0); + + for (i = 0; i < src->nb_side_data; i++) { + const AVFrameSideData *sd_src = src->side_data[i]; + AVFrameSideData *sd_dst; + if ( sd_src->type == AV_FRAME_DATA_PANSCAN + && (src->width != dst->width || src->height != dst->height)) + continue; + if (force_copy) { + sd_dst = av_frame_new_side_data(dst, sd_src->type, + sd_src->size); + if (!sd_dst) { + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(sd_dst->data, sd_src->data, sd_src->size); + } else { + AVBufferRef *ref = av_buffer_ref(sd_src->buf); + sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); + if (!sd_dst) { + av_buffer_unref(&ref); + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + } + av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); + } + + ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); + ret |= av_buffer_replace(&dst->private_ref, src->private_ref); + return ret; +} + +int av_frame_ref(AVFrame *dst, const AVFrame *src) +{ + int i, ret = 0; + + av_assert1(dst->width == 0 && dst->height == 0); +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + av_assert1(dst->channels == 0); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_assert1(dst->ch_layout.nb_channels == 0 && + dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC); + + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->nb_samples = src->nb_samples; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + dst->channels = src->channels; + dst->channel_layout = src->channel_layout; + if (!av_channel_layout_check(&src->ch_layout)) { + if (src->channel_layout) + av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout); + else { + dst->ch_layout.nb_channels = src->channels; + dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + } + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + ret = frame_copy_props(dst, src, 0); + if (ret < 0) + goto fail; + + // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out + if (av_channel_layout_check(&src->ch_layout)) { + ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); + if (ret < 0) + goto fail; + } + + /* duplicate the frame data if it's not refcounted */ + if (!src->buf[0]) { + ret = av_frame_get_buffer(dst, 0); + if (ret < 0) + goto fail; + + ret = av_frame_copy(dst, src); + if (ret < 0) + goto fail; + + return 0; + } + + /* ref the buffers */ + for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { + if (!src->buf[i]) + continue; + dst->buf[i] = av_buffer_ref(src->buf[i]); + if (!dst->buf[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + if (src->extended_buf) { + dst->extended_buf = av_calloc(src->nb_extended_buf, + sizeof(*dst->extended_buf)); + if (!dst->extended_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->nb_extended_buf = src->nb_extended_buf; + + for (i = 0; i < src->nb_extended_buf; i++) { + dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]); + if (!dst->extended_buf[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + /* duplicate extended data */ + if (src->extended_data != src->data) { + int ch = dst->ch_layout.nb_channels; + + if (!ch) { + ret = AVERROR(EINVAL); + goto fail; + } + + dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); + if (!dst->extended_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch); + } else + dst->extended_data = dst->data; + + memcpy(dst->data, src->data, sizeof(src->data)); + memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); + + return 0; + +fail: + av_frame_unref(dst); + return ret; +} + +AVFrame *av_frame_clone(const AVFrame *src) +{ + AVFrame *ret = av_frame_alloc(); + + if (!ret) + return NULL; + + if (av_frame_ref(ret, src) < 0) + av_frame_free(&ret); + + return ret; +} + +void av_frame_unref(AVFrame *frame) +{ + int i; + + if (!frame) + return; + + wipe_side_data(frame); + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) + av_buffer_unref(&frame->buf[i]); + for (i = 0; i < frame->nb_extended_buf; i++) + av_buffer_unref(&frame->extended_buf[i]); + av_freep(&frame->extended_buf); + av_dict_free(&frame->metadata); + + av_buffer_unref(&frame->hw_frames_ctx); + + av_buffer_unref(&frame->opaque_ref); + av_buffer_unref(&frame->private_ref); + + if (frame->extended_data != frame->data) + av_freep(&frame->extended_data); + + av_channel_layout_uninit(&frame->ch_layout); + + get_frame_defaults(frame); +} + +void av_frame_move_ref(AVFrame *dst, AVFrame *src) +{ + av_assert1(dst->width == 0 && dst->height == 0); +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + av_assert1(dst->channels == 0); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_assert1(dst->ch_layout.nb_channels == 0 && + dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC); + + *dst = *src; + if (src->extended_data == src->data) + dst->extended_data = dst->data; + get_frame_defaults(src); +} + +int av_frame_is_writable(AVFrame *frame) +{ + int i, ret = 1; + + /* assume non-refcounted frames are not writable */ + if (!frame->buf[0]) + return 0; + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) + if (frame->buf[i]) + ret &= !!av_buffer_is_writable(frame->buf[i]); + for (i = 0; i < frame->nb_extended_buf; i++) + ret &= !!av_buffer_is_writable(frame->extended_buf[i]); + + return ret; +} + +int av_frame_make_writable(AVFrame *frame) +{ + AVFrame tmp; + int ret; + + if (av_frame_is_writable(frame)) + return 0; + + memset(&tmp, 0, sizeof(tmp)); + tmp.format = frame->format; + tmp.width = frame->width; + tmp.height = frame->height; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + tmp.channels = frame->channels; + tmp.channel_layout = frame->channel_layout; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + tmp.nb_samples = frame->nb_samples; + ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + + if (frame->hw_frames_ctx) + ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); + else + ret = av_frame_get_buffer(&tmp, 0); + if (ret < 0) + return ret; + + ret = av_frame_copy(&tmp, frame); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + + ret = av_frame_copy_props(&tmp, frame); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + + av_frame_unref(frame); + + *frame = tmp; + if (tmp.data == tmp.extended_data) + frame->extended_data = frame->data; + + return 0; +} + +int av_frame_copy_props(AVFrame *dst, const AVFrame *src) +{ + return frame_copy_props(dst, src, 1); +} + +AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) +{ + uint8_t *data; + int planes, i; + + if (frame->nb_samples) { + int channels = frame->ch_layout.nb_channels; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!channels) { + channels = frame->channels; + CHECK_CHANNELS_CONSISTENCY(frame); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (!channels) + return NULL; + planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; + } else + planes = 4; + + if (plane < 0 || plane >= planes || !frame->extended_data[plane]) + return NULL; + data = frame->extended_data[plane]; + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) { + AVBufferRef *buf = frame->buf[i]; + if (data >= buf->data && data < buf->data + buf->size) + return buf; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + AVBufferRef *buf = frame->extended_buf[i]; + if (data >= buf->data && data < buf->data + buf->size) + return buf; + } + return NULL; +} + +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf) +{ + AVFrameSideData *ret, **tmp; + + if (!buf) + return NULL; + + if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1) + return NULL; + + tmp = av_realloc(frame->side_data, + (frame->nb_side_data + 1) * sizeof(*frame->side_data)); + if (!tmp) + return NULL; + frame->side_data = tmp; + + ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->buf = buf; + ret->data = ret->buf->data; + ret->size = buf->size; + ret->type = type; + + frame->side_data[frame->nb_side_data++] = ret; + + return ret; +} + +AVFrameSideData *av_frame_new_side_data(AVFrame *frame, + enum AVFrameSideDataType type, + size_t size) +{ + AVFrameSideData *ret; + AVBufferRef *buf = av_buffer_alloc(size); + ret = av_frame_new_side_data_from_buf(frame, type, buf); + if (!ret) + av_buffer_unref(&buf); + return ret; +} + +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, + enum AVFrameSideDataType type) +{ + int i; + + for (i = 0; i < frame->nb_side_data; i++) { + if (frame->side_data[i]->type == type) + return frame->side_data[i]; + } + return NULL; +} + +static int frame_copy_video(AVFrame *dst, const AVFrame *src) +{ + const uint8_t *src_data[4]; + int i, planes; + + if (dst->width < src->width || + dst->height < src->height) + return AVERROR(EINVAL); + + if (src->hw_frames_ctx || dst->hw_frames_ctx) + return av_hwframe_transfer_data(dst, src, 0); + + planes = av_pix_fmt_count_planes(dst->format); + for (i = 0; i < planes; i++) + if (!dst->data[i] || !src->data[i]) + return AVERROR(EINVAL); + + memcpy(src_data, src->data, sizeof(src_data)); + av_image_copy(dst->data, dst->linesize, + src_data, src->linesize, + dst->format, src->width, src->height); + + return 0; +} + +static int frame_copy_audio(AVFrame *dst, const AVFrame *src) +{ + int planar = av_sample_fmt_is_planar(dst->format); + int channels = dst->ch_layout.nb_channels; + int planes = planar ? channels : 1; + int i; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!channels || !src->ch_layout.nb_channels) { + if (dst->channels != src->channels || + dst->channel_layout != src->channel_layout) + return AVERROR(EINVAL); + CHECK_CHANNELS_CONSISTENCY(src); + } + if (!channels) { + channels = dst->channels; + planes = planar ? channels : 1; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + if (dst->nb_samples != src->nb_samples || +#if FF_API_OLD_CHANNEL_LAYOUT + (av_channel_layout_check(&dst->ch_layout) && + av_channel_layout_check(&src->ch_layout) && +#endif + av_channel_layout_compare(&dst->ch_layout, &src->ch_layout)) +#if FF_API_OLD_CHANNEL_LAYOUT + ) +#endif + return AVERROR(EINVAL); + + for (i = 0; i < planes; i++) + if (!dst->extended_data[i] || !src->extended_data[i]) + return AVERROR(EINVAL); + + av_samples_copy(dst->extended_data, src->extended_data, 0, 0, + dst->nb_samples, channels, dst->format); + + return 0; +} + +int av_frame_copy(AVFrame *dst, const AVFrame *src) +{ + if (dst->format != src->format || dst->format < 0) + return AVERROR(EINVAL); + +FF_DISABLE_DEPRECATION_WARNINGS + if (dst->width > 0 && dst->height > 0) + return frame_copy_video(dst, src); + else if (dst->nb_samples > 0 && + (av_channel_layout_check(&dst->ch_layout) +#if FF_API_OLD_CHANNEL_LAYOUT + || dst->channels > 0 +#endif + )) + return frame_copy_audio(dst, src); +FF_ENABLE_DEPRECATION_WARNINGS + + return AVERROR(EINVAL); +} + +void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) +{ + int i; + + for (i = frame->nb_side_data - 1; i >= 0; i--) { + AVFrameSideData *sd = frame->side_data[i]; + if (sd->type == type) { + free_side_data(&frame->side_data[i]); + frame->side_data[i] = frame->side_data[frame->nb_side_data - 1]; + frame->nb_side_data--; + } + } +} + +const char *av_frame_side_data_name(enum AVFrameSideDataType type) +{ + switch(type) { + case AV_FRAME_DATA_PANSCAN: return "AVPanScan"; + case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions"; + case AV_FRAME_DATA_STEREO3D: return "Stereo 3D"; + case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding"; + case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure"; + case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain"; + case AV_FRAME_DATA_DISPLAYMATRIX: return "3x3 displaymatrix"; + case AV_FRAME_DATA_AFD: return "Active format description"; + case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors"; + case AV_FRAME_DATA_SKIP_SAMPLES: return "Skip samples"; + case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio service type"; + case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; + case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; + case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; + case AV_FRAME_DATA_S12M_TIMECODE: return "SMPTE 12-1 timecode"; + case AV_FRAME_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; + case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; + case AV_FRAME_DATA_DYNAMIC_HDR_VIVID: return "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)"; + case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; + case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters"; + case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message"; + case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters"; + case AV_FRAME_DATA_DETECTION_BBOXES: return "Bounding boxes for object detection and classification"; + case AV_FRAME_DATA_DOVI_RPU_BUFFER: return "Dolby Vision RPU Data"; + case AV_FRAME_DATA_DOVI_METADATA: return "Dolby Vision Metadata"; + case AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT: return "Ambient viewing environment"; + } + return NULL; +} + +static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, + const AVPixFmtDescriptor *desc) +{ + int i, j; + + for (i = 0; frame->data[i]; i++) { + const AVComponentDescriptor *comp = NULL; + int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; + int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + + if (desc->flags & AV_PIX_FMT_FLAG_PAL && i == 1) { + offsets[i] = 0; + break; + } + + /* find any component descriptor for this plane */ + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].plane == i) { + comp = &desc->comp[j]; + break; + } + } + if (!comp) + return AVERROR_BUG; + + offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + + (frame->crop_left >> shift_x) * comp->step; + } + + return 0; +} + +int av_frame_apply_cropping(AVFrame *frame, int flags) +{ + const AVPixFmtDescriptor *desc; + size_t offsets[4]; + int i; + + if (!(frame->width > 0 && frame->height > 0)) + return AVERROR(EINVAL); + + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) + return AVERROR(ERANGE); + + desc = av_pix_fmt_desc_get(frame->format); + if (!desc) + return AVERROR_BUG; + + /* Apply just the right/bottom cropping for hwaccel formats. Bitstream + * formats cannot be easily handled here either (and corresponding decoders + * should not export any cropping anyway), so do the same for those as well. + * */ + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { + frame->width -= frame->crop_right; + frame->height -= frame->crop_bottom; + frame->crop_right = 0; + frame->crop_bottom = 0; + return 0; + } + + /* calculate the offsets for each plane */ + calc_cropping_offsets(offsets, frame, desc); + + /* adjust the offsets to avoid breaking alignment */ + if (!(flags & AV_FRAME_CROP_UNALIGNED)) { + int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; + int min_log2_align = INT_MAX; + + for (i = 0; frame->data[i]; i++) { + int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX; + min_log2_align = FFMIN(log2_align, min_log2_align); + } + + /* we assume, and it should always be true, that the data alignment is + * related to the cropping alignment by a constant power-of-2 factor */ + if (log2_crop_align < min_log2_align) + return AVERROR_BUG; + + if (min_log2_align < 5) { + frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); + calc_cropping_offsets(offsets, frame, desc); + } + } + + for (i = 0; frame->data[i]; i++) + frame->data[i] += offsets[i]; + + frame->width -= (frame->crop_left + frame->crop_right); + frame->height -= (frame->crop_top + frame->crop_bottom); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/frame.h b/arm/raspi/third_party/ffmpeg/libavutil/frame.h new file mode 100644 index 00000000..bbe909ee --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/frame.h @@ -0,0 +1,964 @@ +/* + * 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 + * @ingroup lavu_frame + * reference-counted frame API + */ + +#ifndef AVUTIL_FRAME_H +#define AVUTIL_FRAME_H + +#include +#include + +#include "avutil.h" +#include "buffer.h" +#include "channel_layout.h" +#include "dict.h" +#include "rational.h" +#include "samplefmt.h" +#include "pixfmt.h" +#include "version.h" + + +/** + * @defgroup lavu_frame AVFrame + * @ingroup lavu_data + * + * @{ + * AVFrame is an abstraction for reference-counted raw multimedia data. + */ + +enum AVFrameSideDataType { + /** + * The data is the AVPanScan struct defined in libavcodec. + */ + AV_FRAME_DATA_PANSCAN, + /** + * ATSC A53 Part 4 Closed Captions. + * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. + * The number of bytes of CC data is AVFrameSideData.size. + */ + AV_FRAME_DATA_A53_CC, + /** + * Stereoscopic 3d metadata. + * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. + */ + AV_FRAME_DATA_STEREO3D, + /** + * The data is the AVMatrixEncoding enum defined in libavutil/channel_layout.h. + */ + AV_FRAME_DATA_MATRIXENCODING, + /** + * Metadata relevant to a downmix procedure. + * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. + */ + AV_FRAME_DATA_DOWNMIX_INFO, + /** + * ReplayGain information in the form of the AVReplayGain struct. + */ + AV_FRAME_DATA_REPLAYGAIN, + /** + * This side data contains a 3x3 transformation matrix describing an affine + * transformation that needs to be applied to the frame for correct + * presentation. + * + * See libavutil/display.h for a detailed description of the data. + */ + AV_FRAME_DATA_DISPLAYMATRIX, + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_FRAME_DATA_AFD, + /** + * Motion vectors exported by some codecs (on demand through the export_mvs + * flag set in the libavcodec AVCodecContext flags2 option). + * The data is the AVMotionVector struct defined in + * libavutil/motion_vector.h. + */ + AV_FRAME_DATA_MOTION_VECTORS, + /** + * Recommmends skipping the specified number of samples. This is exported + * only if the "skip_manual" AVOption is set in libavcodec. + * This has the same format as AV_PKT_DATA_SKIP_SAMPLES. + * @code + * u32le number of samples to skip from start of this packet + * u32le number of samples to skip from end of this packet + * u8 reason for start skip + * u8 reason for end skip (0=padding silence, 1=convergence) + * @endcode + */ + AV_FRAME_DATA_SKIP_SAMPLES, + /** + * This side data must be associated with an audio frame and corresponds to + * enum AVAudioServiceType defined in avcodec.h. + */ + AV_FRAME_DATA_AUDIO_SERVICE_TYPE, + /** + * Mastering display metadata associated with a video frame. The payload is + * an AVMasteringDisplayMetadata type and contains information about the + * mastering display color volume. + */ + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, + /** + * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer. + * This is set on the first frame of a GOP that has a temporal reference of 0. + */ + AV_FRAME_DATA_GOP_TIMECODE, + + /** + * The data represents the AVSphericalMapping structure defined in + * libavutil/spherical.h. + */ + AV_FRAME_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This payload contains data in + * the form of the AVContentLightMetadata struct. + */ + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + + /** + * The data contains an ICC profile as an opaque octet buffer following the + * format described by ISO 15076-1 with an optional name defined in the + * metadata key entry "name". + */ + AV_FRAME_DATA_ICC_PROFILE, + + /** + * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t + * where the first uint32_t describes how many (1-3) of the other timecodes are used. + * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.h. + */ + AV_FRAME_DATA_S12M_TIMECODE, + + /** + * HDR dynamic metadata associated with a video frame. The payload is + * an AVDynamicHDRPlus type and contains information for color + * volume transform - application 4 of SMPTE 2094-40:2016 standard. + */ + AV_FRAME_DATA_DYNAMIC_HDR_PLUS, + + /** + * Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of + * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size. + */ + AV_FRAME_DATA_REGIONS_OF_INTEREST, + + /** + * Encoding parameters for a video frame, as described by AVVideoEncParams. + */ + AV_FRAME_DATA_VIDEO_ENC_PARAMS, + + /** + * User data unregistered metadata associated with a video frame. + * This is the H.26[45] UDU SEI message, and shouldn't be used for any other purpose + * The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of + * uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte. + */ + AV_FRAME_DATA_SEI_UNREGISTERED, + + /** + * Film grain parameters for a frame, described by AVFilmGrainParams. + * Must be present for every frame which should have film grain applied. + */ + AV_FRAME_DATA_FILM_GRAIN_PARAMS, + + /** + * Bounding boxes for object detection and classification, + * as described by AVDetectionBBoxHeader. + */ + AV_FRAME_DATA_DETECTION_BBOXES, + + /** + * Dolby Vision RPU raw data, suitable for passing to x265 + * or other libraries. Array of uint8_t, with NAL emulation + * bytes intact. + */ + AV_FRAME_DATA_DOVI_RPU_BUFFER, + + /** + * Parsed Dolby Vision metadata, suitable for passing to a software + * implementation. The payload is the AVDOVIMetadata struct defined in + * libavutil/dovi_meta.h. + */ + AV_FRAME_DATA_DOVI_METADATA, + + /** + * HDR Vivid dynamic metadata associated with a video frame. The payload is + * an AVDynamicHDRVivid type and contains information for color + * volume transform - CUVA 005.1-2021. + */ + AV_FRAME_DATA_DYNAMIC_HDR_VIVID, + + /** + * Ambient viewing environment metadata, as defined by H.274. + */ + AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, +}; + +enum AVActiveFormatDescription { + AV_AFD_SAME = 8, + AV_AFD_4_3 = 9, + AV_AFD_16_9 = 10, + AV_AFD_14_9 = 11, + AV_AFD_4_3_SP_14_9 = 13, + AV_AFD_16_9_SP_14_9 = 14, + AV_AFD_SP_4_3 = 15, +}; + + +/** + * Structure to hold side data for an AVFrame. + * + * sizeof(AVFrameSideData) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + */ +typedef struct AVFrameSideData { + enum AVFrameSideDataType type; + uint8_t *data; + size_t size; + AVDictionary *metadata; + AVBufferRef *buf; +} AVFrameSideData; + +/** + * Structure describing a single Region Of Interest. + * + * When multiple regions are defined in a single side-data block, they + * should be ordered from most to least important - some encoders are only + * capable of supporting a limited number of distinct regions, so will have + * to truncate the list. + * + * When overlapping regions are defined, the first region containing a given + * area of the frame applies. + */ +typedef struct AVRegionOfInterest { + /** + * Must be set to the size of this data structure (that is, + * sizeof(AVRegionOfInterest)). + */ + uint32_t self_size; + /** + * Distance in pixels from the top edge of the frame to the top and + * bottom edges and from the left edge of the frame to the left and + * right edges of the rectangle defining this region of interest. + * + * The constraints on a region are encoder dependent, so the region + * actually affected may be slightly larger for alignment or other + * reasons. + */ + int top; + int bottom; + int left; + int right; + /** + * Quantisation offset. + * + * Must be in the range -1 to +1. A value of zero indicates no quality + * change. A negative value asks for better quality (less quantisation), + * while a positive value asks for worse quality (greater quantisation). + * + * The range is calibrated so that the extreme values indicate the + * largest possible offset - if the rest of the frame is encoded with the + * worst possible quality, an offset of -1 indicates that this region + * should be encoded with the best possible quality anyway. Intermediate + * values are then interpolated in some codec-dependent way. + * + * For example, in 10-bit H.264 the quantisation parameter varies between + * -12 and 51. A typical qoffset value of -1/10 therefore indicates that + * this region should be encoded with a QP around one-tenth of the full + * range better than the rest of the frame. So, if most of the frame + * were to be encoded with a QP of around 30, this region would get a QP + * of around 24 (an offset of approximately -1/10 * (51 - -12) = -6.3). + * An extreme value of -1 would indicate that this region should be + * encoded with the best possible quality regardless of the treatment of + * the rest of the frame - that is, should be encoded at a QP of -12. + */ + AVRational qoffset; +} AVRegionOfInterest; + +/** + * This structure describes decoded (raw) audio or video data. + * + * AVFrame must be allocated using av_frame_alloc(). Note that this only + * allocates the AVFrame itself, the buffers for the data must be managed + * through other means (see below). + * AVFrame must be freed with av_frame_free(). + * + * AVFrame is typically allocated once and then reused multiple times to hold + * different data (e.g. a single AVFrame to hold frames received from a + * decoder). In such a case, av_frame_unref() will free any references held by + * the frame and reset it to its original clean state before it + * is reused again. + * + * The data described by an AVFrame is usually reference counted through the + * AVBuffer API. The underlying buffer references are stored in AVFrame.buf / + * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at + * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, + * every single data plane must be contained in one of the buffers in + * AVFrame.buf or AVFrame.extended_buf. + * There may be a single buffer for all the data, or one separate buffer for + * each plane, or anything in between. + * + * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + * + * Fields can be accessed through AVOptions, the name string used, matches the + * C structure field name for fields accessible through AVOptions. The AVClass + * for AVFrame can be obtained from avcodec_get_frame_class() + */ +typedef struct AVFrame { +#define AV_NUM_DATA_POINTERS 8 + /** + * pointer to the picture/channel planes. + * This might be different from the first allocated byte. For video, + * it could even point to the end of the image data. + * + * All pointers in data and extended_data must point into one of the + * AVBufferRef in buf or extended_buf. + * + * Some decoders access areas outside 0,0 - width,height, please + * see avcodec_align_dimensions2(). Some filters and swscale can read + * up to 16 bytes beyond the planes, if these filters are to be used, + * then 16 extra bytes must be allocated. + * + * NOTE: Pointers not needed by the format MUST be set to NULL. + * + * @attention In case of video, the data[] pointers can point to the + * end of image data in order to reverse line order, when used in + * combination with negative values in the linesize[] array. + */ + uint8_t *data[AV_NUM_DATA_POINTERS]; + + /** + * For video, a positive or negative value, which is typically indicating + * the size in bytes of each picture line, but it can also be: + * - the negative byte size of lines for vertical flipping + * (with data[n] pointing to the end of the data + * - a positive or negative multiple of the byte size as for accessing + * even and odd fields of a frame (possibly flipped) + * + * For audio, only linesize[0] may be set. For planar audio, each channel + * plane must be the same size. + * + * For video the linesizes should be multiples of the CPUs alignment + * preference, this is 16 or 32 for modern desktop CPUs. + * Some code requires such alignment other code can be slower without + * correct alignment, for yet other it makes no difference. + * + * @note The linesize may be larger than the size of usable data -- there + * may be extra padding present for performance reasons. + * + * @attention In case of video, line size values can be negative to achieve + * a vertically inverted iteration over image lines. + */ + int linesize[AV_NUM_DATA_POINTERS]; + + /** + * pointers to the data planes/channels. + * + * For video, this should simply point to data[]. + * + * For planar audio, each channel has a separate data pointer, and + * linesize[0] contains the size of each channel buffer. + * For packed audio, there is just one data pointer, and linesize[0] + * contains the total size of the buffer for all channels. + * + * Note: Both data and extended_data should always be set in a valid frame, + * but for planar audio with more channels that can fit in data, + * extended_data must be used in order to access all channels. + */ + uint8_t **extended_data; + + /** + * @name Video dimensions + * Video frames only. The coded dimensions (in pixels) of the video frame, + * i.e. the size of the rectangle that contains some well-defined values. + * + * @note The part of the frame intended for display/presentation is further + * restricted by the @ref cropping "Cropping rectangle". + * @{ + */ + int width, height; + /** + * @} + */ + + /** + * number of audio samples (per channel) described by this frame + */ + int nb_samples; + + /** + * format of the frame, -1 if unknown or unset + * Values correspond to enum AVPixelFormat for video frames, + * enum AVSampleFormat for audio) + */ + int format; + + /** + * 1 -> keyframe, 0-> not + */ + int key_frame; + + /** + * Picture type of the frame. + */ + enum AVPictureType pict_type; + + /** + * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified. + */ + AVRational sample_aspect_ratio; + + /** + * Presentation timestamp in time_base units (time when frame should be shown to user). + */ + int64_t pts; + + /** + * DTS copied from the AVPacket that triggered returning this frame. (if frame threading isn't used) + * This is also the Presentation time of this AVFrame calculated from + * only AVPacket.dts values without pts values. + */ + int64_t pkt_dts; + + /** + * Time base for the timestamps in this frame. + * In the future, this field may be set on frames output by decoders or + * filters, but its value will be by default ignored on input to encoders + * or filters. + */ + AVRational time_base; + + /** + * picture number in bitstream order + */ + int coded_picture_number; + /** + * picture number in display order + */ + int display_picture_number; + + /** + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) + */ + int quality; + + /** + * for some private data of the user + */ + void *opaque; + + /** + * When decoding, this signals how much the picture must be delayed. + * extra_delay = repeat_pict / (2*fps) + */ + int repeat_pict; + + /** + * The content of the picture is interlaced. + */ + int interlaced_frame; + + /** + * If the content is interlaced, is top field displayed first. + */ + int top_field_first; + + /** + * Tell user application that palette has changed from previous frame. + */ + int palette_has_changed; + + /** + * reordered opaque 64 bits (generally an integer or a double precision float + * PTS but can be anything). + * The user sets AVCodecContext.reordered_opaque to represent the input at + * that time, + * the decoder reorders values as needed and sets AVFrame.reordered_opaque + * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque + */ + int64_t reordered_opaque; + + /** + * Sample rate of the audio data. + */ + int sample_rate; + +#if FF_API_OLD_CHANNEL_LAYOUT + /** + * Channel layout of the audio data. + * @deprecated use ch_layout instead + */ + attribute_deprecated + uint64_t channel_layout; +#endif + + /** + * AVBuffer references backing the data for this frame. All the pointers in + * data and extended_data must point inside one of the buffers in buf or + * extended_buf. This array must be filled contiguously -- if buf[i] is + * non-NULL then buf[j] must also be non-NULL for all j < i. + * + * There may be at most one AVBuffer per data plane, so for video this array + * always contains all the references. For planar audio with more than + * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in + * this array. Then the extra AVBufferRef pointers are stored in the + * extended_buf array. + */ + AVBufferRef *buf[AV_NUM_DATA_POINTERS]; + + /** + * For planar audio which requires more than AV_NUM_DATA_POINTERS + * AVBufferRef pointers, this array will hold all the references which + * cannot fit into AVFrame.buf. + * + * Note that this is different from AVFrame.extended_data, which always + * contains all the pointers. This array only contains the extra pointers, + * which cannot fit into AVFrame.buf. + * + * This array is always allocated using av_malloc() by whoever constructs + * the frame. It is freed in av_frame_unref(). + */ + AVBufferRef **extended_buf; + /** + * Number of elements in extended_buf. + */ + int nb_extended_buf; + + AVFrameSideData **side_data; + int nb_side_data; + +/** + * @defgroup lavu_frame_flags AV_FRAME_FLAGS + * @ingroup lavu_frame + * Flags describing additional frame properties. + * + * @{ + */ + +/** + * The frame data may be corrupted, e.g. due to decoding errors. + */ +#define AV_FRAME_FLAG_CORRUPT (1 << 0) +/** + * A flag to mark the frames which need to be decoded, but shouldn't be output. + */ +#define AV_FRAME_FLAG_DISCARD (1 << 2) +/** + * @} + */ + + /** + * Frame flags, a combination of @ref lavu_frame_flags + */ + int flags; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + enum AVColorPrimaries color_primaries; + + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + enum AVChromaLocation chroma_location; + + /** + * frame timestamp estimated using various heuristics, in stream time base + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int64_t best_effort_timestamp; + + /** + * reordered pos from the last AVPacket that has been input into the decoder + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_pos; + +#if FF_API_PKT_DURATION + /** + * duration of the corresponding packet, expressed in + * AVStream->time_base units, 0 if unknown. + * - encoding: unused + * - decoding: Read by user. + * + * @deprecated use duration instead + */ + attribute_deprecated + int64_t pkt_duration; +#endif + + /** + * metadata. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVDictionary *metadata; + + /** + * decode error flags of the frame, set to a combination of + * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there + * were errors during the decoding. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int decode_error_flags; +#define FF_DECODE_ERROR_INVALID_BITSTREAM 1 +#define FF_DECODE_ERROR_MISSING_REFERENCE 2 +#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 +#define FF_DECODE_ERROR_DECODE_SLICES 8 + +#if FF_API_OLD_CHANNEL_LAYOUT + /** + * number of audio channels, only used for audio. + * - encoding: unused + * - decoding: Read by user. + * @deprecated use ch_layout instead + */ + attribute_deprecated + int channels; +#endif + + /** + * size of the corresponding packet containing the compressed + * frame. + * It is set to a negative value if unknown. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int pkt_size; + + /** + * For hwaccel-format frames, this should be a reference to the + * AVHWFramesContext describing the frame. + */ + AVBufferRef *hw_frames_ctx; + + /** + * AVBufferRef for free use by the API user. FFmpeg will never check the + * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when + * the frame is unreferenced. av_frame_copy_props() calls create a new + * reference with av_buffer_ref() for the target frame's opaque_ref field. + * + * This is unrelated to the opaque field, although it serves a similar + * purpose. + */ + AVBufferRef *opaque_ref; + + /** + * @anchor cropping + * @name Cropping + * Video frames only. The number of pixels to discard from the the + * top/bottom/left/right border of the frame to obtain the sub-rectangle of + * the frame intended for presentation. + * @{ + */ + size_t crop_top; + size_t crop_bottom; + size_t crop_left; + size_t crop_right; + /** + * @} + */ + + /** + * AVBufferRef for internal use by a single libav* library. + * Must not be used to transfer data between libraries. + * Has to be NULL when ownership of the frame leaves the respective library. + * + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. + */ + AVBufferRef *private_ref; + + /** + * Channel layout of the audio data. + */ + AVChannelLayout ch_layout; + + /** + * Duration of the frame, in the same units as pts. 0 if unknown. + */ + int64_t duration; +} AVFrame; + + +#if FF_API_COLORSPACE_NAME +/** + * Get the name of a colorspace. + * @return a static string identifying the colorspace; can be NULL. + * @deprecated use av_color_space_name() + */ +attribute_deprecated +const char *av_get_colorspace_name(enum AVColorSpace val); +#endif +/** + * Allocate an AVFrame and set its fields to default values. The resulting + * struct must be freed using av_frame_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * + * @note this only allocates the AVFrame itself, not the data buffers. Those + * must be allocated through other means, e.g. with av_frame_get_buffer() or + * manually. + */ +AVFrame *av_frame_alloc(void); + +/** + * Free the frame and any dynamically allocated objects in it, + * e.g. extended_data. If the frame is reference counted, it will be + * unreferenced first. + * + * @param frame frame to be freed. The pointer will be set to NULL. + */ +void av_frame_free(AVFrame **frame); + +/** + * Set up a new reference to the data described by the source frame. + * + * Copy frame properties from src to dst and create a new reference for each + * AVBufferRef from src. + * + * If src is not reference counted, new buffers are allocated and the data is + * copied. + * + * @warning: dst MUST have been either unreferenced with av_frame_unref(dst), + * or newly allocated with av_frame_alloc() before calling this + * function, or undefined behavior will occur. + * + * @return 0 on success, a negative AVERROR on error + */ +int av_frame_ref(AVFrame *dst, const AVFrame *src); + +/** + * Create a new frame that references the same data as src. + * + * This is a shortcut for av_frame_alloc()+av_frame_ref(). + * + * @return newly created AVFrame on success, NULL on error. + */ +AVFrame *av_frame_clone(const AVFrame *src); + +/** + * Unreference all the buffers referenced by frame and reset the frame fields. + */ +void av_frame_unref(AVFrame *frame); + +/** + * Move everything contained in src to dst and reset src. + * + * @warning: dst is not unreferenced, but directly overwritten without reading + * or deallocating its contents. Call av_frame_unref(dst) manually + * before calling this function to ensure that no memory is leaked. + */ +void av_frame_move_ref(AVFrame *dst, AVFrame *src); + +/** + * Allocate new buffer(s) for audio or video data. + * + * The following fields must be set on frame before calling this function: + * - format (pixel format for video, sample format for audio) + * - width and height for video + * - nb_samples and ch_layout for audio + * + * This function will fill AVFrame.data and AVFrame.buf arrays and, if + * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. + * For planar formats, one buffer will be allocated for each plane. + * + * @warning: if frame already has been allocated, calling this function will + * leak memory. In addition, undefined behavior can occur in certain + * cases. + * + * @param frame frame in which to store the new buffers. + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_frame_get_buffer(AVFrame *frame, int align); + +/** + * Check if the frame data is writable. + * + * @return A positive value if the frame data is writable (which is true if and + * only if each of the underlying buffers has only one reference, namely the one + * stored in this frame). Return 0 otherwise. + * + * If 1 is returned the answer is valid until av_buffer_ref() is called on any + * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly). + * + * @see av_frame_make_writable(), av_buffer_is_writable() + */ +int av_frame_is_writable(AVFrame *frame); + +/** + * Ensure that the frame data is writable, avoiding data copy if possible. + * + * Do nothing if the frame is writable, allocate new buffers and copy the data + * if it is not. Non-refcounted frames behave as non-writable, i.e. a copy + * is always made. + * + * @return 0 on success, a negative AVERROR on error. + * + * @see av_frame_is_writable(), av_buffer_is_writable(), + * av_buffer_make_writable() + */ +int av_frame_make_writable(AVFrame *frame); + +/** + * Copy the frame data from src to dst. + * + * This function does not allocate anything, dst must be already initialized and + * allocated with the same parameters as src. + * + * This function only copies the frame data (i.e. the contents of the data / + * extended data arrays), not any other properties. + * + * @return >= 0 on success, a negative AVERROR on error. + */ +int av_frame_copy(AVFrame *dst, const AVFrame *src); + +/** + * Copy only "metadata" fields from src to dst. + * + * Metadata for the purpose of this function are those fields that do not affect + * the data layout in the buffers. E.g. pts, sample rate (for audio) or sample + * aspect ratio (for video), but not width/height or channel layout. + * Side data is also copied. + */ +int av_frame_copy_props(AVFrame *dst, const AVFrame *src); + +/** + * Get the buffer reference a given data plane is stored in. + * + * @param frame the frame to get the plane's buffer from + * @param plane index of the data plane of interest in frame->extended_data. + * + * @return the buffer reference that contains the plane or NULL if the input + * frame is not valid. + */ +AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane); + +/** + * Add a new side data to a frame. + * + * @param frame a frame to which the side data should be added + * @param type type of the added side data + * @param size size of the side data + * + * @return newly added side data on success, NULL on error + */ +AVFrameSideData *av_frame_new_side_data(AVFrame *frame, + enum AVFrameSideDataType type, + size_t size); + +/** + * Add a new side data to a frame from an existing AVBufferRef + * + * @param frame a frame to which the side data should be added + * @param type the type of the added side data + * @param buf an AVBufferRef to add as side data. The ownership of + * the reference is transferred to the frame. + * + * @return newly added side data on success, NULL on error. On failure + * the frame is unchanged and the AVBufferRef remains owned by + * the caller. + */ +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + +/** + * @return a pointer to the side data of a given type on success, NULL if there + * is no side data with such type in this frame. + */ +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, + enum AVFrameSideDataType type); + +/** + * Remove and free all side data instances of the given type. + */ +void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); + + +/** + * Flags for frame cropping. + */ +enum { + /** + * Apply the maximum possible cropping, even if it requires setting the + * AVFrame.data[] entries to unaligned pointers. Passing unaligned data + * to FFmpeg API is generally not allowed, and causes undefined behavior + * (such as crashes). You can pass unaligned data only to FFmpeg APIs that + * are explicitly documented to accept it. Use this flag only if you + * absolutely know what you are doing. + */ + AV_FRAME_CROP_UNALIGNED = 1 << 0, +}; + +/** + * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ + * crop_bottom fields. If cropping is successful, the function will adjust the + * data pointers and the width/height fields, and set the crop fields to 0. + * + * In all cases, the cropping boundaries will be rounded to the inherent + * alignment of the pixel format. In some cases, such as for opaque hwaccel + * formats, the left/top cropping is ignored. The crop fields are set to 0 even + * if the cropping was rounded or ignored. + * + * @param frame the frame which should be cropped + * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. + * + * @return >= 0 on success, a negative AVERROR on error. If the cropping fields + * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. + */ +int av_frame_apply_cropping(AVFrame *frame, int flags); + +/** + * @return a string identifying the side data type + */ +const char *av_frame_side_data_name(enum AVFrameSideDataType type); + +/** + * @} + */ + +#endif /* AVUTIL_FRAME_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/getenv_utf8.h b/arm/raspi/third_party/ffmpeg/libavutil/getenv_utf8.h new file mode 100644 index 00000000..c10291ad --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/getenv_utf8.h @@ -0,0 +1,86 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_GETENV_UTF8_H +#define AVUTIL_GETENV_UTF8_H + +#include + +#include "config.h" +#include "mem.h" + +#if HAVE_GETENV && defined(_WIN32) + +#include "libavutil/wchar_filename.h" + +static inline char *getenv_utf8(const char *varname) +{ + wchar_t *varname_w, *var_w; + char *var; + + if (utf8towchar(varname, &varname_w)) + return NULL; + if (!varname_w) + return NULL; + + var_w = _wgetenv(varname_w); + av_free(varname_w); + + if (!var_w) + return NULL; + if (wchartoutf8(var_w, &var)) + return NULL; + + return var; + + // No CP_ACP fallback compared to other *_utf8() functions: + // non UTF-8 strings must not be returned. +} + +static inline void freeenv_utf8(char *var) +{ + av_free(var); +} + +static inline char *getenv_dup(const char *varname) +{ + return getenv_utf8(varname); +} + +#else + +static inline char *getenv_utf8(const char *varname) +{ + return getenv(varname); +} + +static inline void freeenv_utf8(char *var) +{ +} + +static inline char *getenv_dup(const char *varname) +{ + char *var = getenv(varname); + if (!var) + return NULL; + return av_strdup(var); +} + +#endif // HAVE_GETENV && defined(_WIN32) + +#endif // AVUTIL_GETENV_UTF8_H diff --git a/arm/raspi/third_party/ffmpeg/libavutil/half2float.c b/arm/raspi/third_party/ffmpeg/libavutil/half2float.c new file mode 100644 index 00000000..4de2180a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/half2float.c @@ -0,0 +1,67 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/half2float.h" + +#if !HAVE_FAST_FLOAT16 +static uint32_t convertmantissa(uint32_t i) +{ + int32_t m = i << 13; // Zero pad mantissa bits + int32_t e = 0; // Zero exponent + + while (!(m & 0x00800000)) { // While not normalized + e -= 0x00800000; // Decrement exponent (1<<23) + m <<= 1; // Shift mantissa + } + + m &= ~0x00800000; // Clear leading 1 bit + e += 0x38800000; // Adjust bias ((127-14)<<23) + + return m | e; // Return combined number +} +#endif + +void ff_init_half2float_tables(Half2FloatTables *t) +{ +#if !HAVE_FAST_FLOAT16 + t->mantissatable[0] = 0; + for (int i = 1; i < 1024; i++) + t->mantissatable[i] = convertmantissa(i); + for (int i = 1024; i < 2048; i++) + t->mantissatable[i] = 0x38000000UL + ((i - 1024) << 13UL); + for (int i = 2048; i < 3072; i++) + t->mantissatable[i] = t->mantissatable[i - 1024] | 0x400000UL; + t->mantissatable[2048] = t->mantissatable[1024]; + + t->exponenttable[0] = 0; + for (int i = 1; i < 31; i++) + t->exponenttable[i] = i << 23; + for (int i = 33; i < 63; i++) + t->exponenttable[i] = 0x80000000UL + ((i - 32) << 23UL); + t->exponenttable[31]= 0x47800000UL; + t->exponenttable[32]= 0x80000000UL; + t->exponenttable[63]= 0xC7800000UL; + + t->offsettable[0] = 0; + for (int i = 1; i < 64; i++) + t->offsettable[i] = 1024; + t->offsettable[31] = 2048; + t->offsettable[32] = 0; + t->offsettable[63] = 2048; +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/half2float.h b/arm/raspi/third_party/ffmpeg/libavutil/half2float.h new file mode 100644 index 00000000..dbd5e715 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/half2float.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HALF2FLOAT_H +#define AVUTIL_HALF2FLOAT_H + +#include +#include "intfloat.h" + +#include "config.h" + +typedef struct Half2FloatTables { +#if HAVE_FAST_FLOAT16 + uint8_t dummy; +#else + uint32_t mantissatable[3072]; + uint32_t exponenttable[64]; + uint16_t offsettable[64]; +#endif +} Half2FloatTables; + +void ff_init_half2float_tables(Half2FloatTables *t); + +static inline uint32_t half2float(uint16_t h, const Half2FloatTables *t) +{ +#if HAVE_FAST_FLOAT16 + union { + _Float16 f; + uint16_t i; + } u; + u.i = h; + return av_float2int(u.f); +#else + uint32_t f; + + f = t->mantissatable[t->offsettable[h >> 10] + (h & 0x3ff)] + t->exponenttable[h >> 10]; + + return f; +#endif +} + +#endif /* AVUTIL_HALF2FLOAT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hash.c b/arm/raspi/third_party/ffmpeg/libavutil/hash.c new file mode 100644 index 00000000..9a497481 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hash.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "hash.h" + +#include "adler32.h" +#include "crc.h" +#include "md5.h" +#include "murmur3.h" +#include "ripemd.h" +#include "sha.h" +#include "sha512.h" + +#include "avstring.h" +#include "base64.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" + +enum hashtype { + MD5, + MURMUR3, + RIPEMD128, + RIPEMD160, + RIPEMD256, + RIPEMD320, + SHA160, + SHA224, + SHA256, + SHA512_224, + SHA512_256, + SHA384, + SHA512, + CRC32, + ADLER32, + NUM_HASHES +}; + +typedef struct AVHashContext { + void *ctx; + enum hashtype type; + const AVCRC *crctab; + uint32_t crc; +} AVHashContext; + +static const struct { + const char *name; + int size; +} hashdesc[] = { + [MD5] = {"MD5", 16}, + [MURMUR3] = {"murmur3", 16}, + [RIPEMD128] = {"RIPEMD128", 16}, + [RIPEMD160] = {"RIPEMD160", 20}, + [RIPEMD256] = {"RIPEMD256", 32}, + [RIPEMD320] = {"RIPEMD320", 40}, + [SHA160] = {"SHA160", 20}, + [SHA224] = {"SHA224", 28}, + [SHA256] = {"SHA256", 32}, + [SHA512_224] = {"SHA512/224", 28}, + [SHA512_256] = {"SHA512/256", 32}, + [SHA384] = {"SHA384", 48}, + [SHA512] = {"SHA512", 64}, + [CRC32] = {"CRC32", 4}, + [ADLER32] = {"adler32", 4}, +}; + +const char *av_hash_names(int i) +{ + if (i < 0 || i >= NUM_HASHES) return NULL; + return hashdesc[i].name; +} + +const char *av_hash_get_name(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].name; +} + +int av_hash_get_size(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].size; +} + +int av_hash_alloc(AVHashContext **ctx, const char *name) +{ + AVHashContext *res; + int i; + *ctx = NULL; + for (i = 0; i < NUM_HASHES; i++) + if (av_strcasecmp(name, hashdesc[i].name) == 0) + break; + if (i >= NUM_HASHES) return AVERROR(EINVAL); + res = av_mallocz(sizeof(*res)); + if (!res) return AVERROR(ENOMEM); + res->type = i; + switch (i) { + case MD5: res->ctx = av_md5_alloc(); break; + case MURMUR3: res->ctx = av_murmur3_alloc(); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: res->ctx = av_ripemd_alloc(); break; + case SHA160: + case SHA224: + case SHA256: res->ctx = av_sha_alloc(); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: res->ctx = av_sha512_alloc(); break; + case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break; + case ADLER32: break; + } + if (i != ADLER32 && i != CRC32 && !res->ctx) { + av_free(res); + return AVERROR(ENOMEM); + } + *ctx = res; + return 0; +} + +void av_hash_init(AVHashContext *ctx) +{ + switch (ctx->type) { + case MD5: av_md5_init(ctx->ctx); break; + case MURMUR3: av_murmur3_init(ctx->ctx); break; + case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break; + case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break; + case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break; + case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break; + case SHA160: av_sha_init(ctx->ctx, 160); break; + case SHA224: av_sha_init(ctx->ctx, 224); break; + case SHA256: av_sha_init(ctx->ctx, 256); break; + case SHA512_224: av_sha512_init(ctx->ctx, 224); break; + case SHA512_256: av_sha512_init(ctx->ctx, 256); break; + case SHA384: av_sha512_init(ctx->ctx, 384); break; + case SHA512: av_sha512_init(ctx->ctx, 512); break; + case CRC32: ctx->crc = UINT32_MAX; break; + case ADLER32: ctx->crc = 1; break; + } +} + +void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len) +{ + switch (ctx->type) { + case MD5: av_md5_update(ctx->ctx, src, len); break; + case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break; + case SHA160: + case SHA224: + case SHA256: av_sha_update(ctx->ctx, src, len); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: av_sha512_update(ctx->ctx, src, len); break; + case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break; + case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break; + } +} + +void av_hash_final(AVHashContext *ctx, uint8_t *dst) +{ + switch (ctx->type) { + case MD5: av_md5_final(ctx->ctx, dst); break; + case MURMUR3: av_murmur3_final(ctx->ctx, dst); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break; + case SHA160: + case SHA224: + case SHA256: av_sha_final(ctx->ctx, dst); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: av_sha512_final(ctx->ctx, dst); break; + case CRC32: AV_WB32(dst, ctx->crc ^ UINT32_MAX); break; + case ADLER32: AV_WB32(dst, ctx->crc); break; + } +} + +void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE]; + unsigned rsize = av_hash_get_size(ctx); + + av_hash_final(ctx, buf); + memcpy(dst, buf, FFMIN(size, rsize)); + if (size > rsize) + memset(dst + rsize, 0, size - rsize); +} + +void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE]; + unsigned rsize = av_hash_get_size(ctx), i; + + av_hash_final(ctx, buf); + for (i = 0; i < FFMIN(rsize, size / 2); i++) + snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]); +} + +void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE], b64[AV_BASE64_SIZE(AV_HASH_MAX_SIZE)]; + unsigned rsize = av_hash_get_size(ctx), osize; + + av_hash_final(ctx, buf); + av_base64_encode(b64, sizeof(b64), buf, rsize); + osize = AV_BASE64_SIZE(rsize); + memcpy(dst, b64, FFMIN(osize, size)); + if (size < osize) + dst[size - 1] = 0; +} + +void av_hash_freep(AVHashContext **ctx) +{ + if (*ctx) + av_freep(&(*ctx)->ctx); + av_freep(ctx); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hash.h b/arm/raspi/third_party/ffmpeg/libavutil/hash.h new file mode 100644 index 00000000..94151ded --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hash.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_hash_generic + * Generic hashing API + */ + +#ifndef AVUTIL_HASH_H +#define AVUTIL_HASH_H + +#include +#include + +/** + * @defgroup lavu_hash Hash Functions + * @ingroup lavu_crypto + * Hash functions useful in multimedia. + * + * Hash functions are widely used in multimedia, from error checking and + * concealment to internal regression testing. libavutil has efficient + * implementations of a variety of hash functions that may be useful for + * FFmpeg and other multimedia applications. + * + * @{ + * + * @defgroup lavu_hash_generic Generic Hashing API + * An abstraction layer for all hash functions supported by libavutil. + * + * If your application needs to support a wide range of different hash + * functions, then the Generic Hashing API is for you. It provides a generic, + * reusable API for @ref lavu_hash "all hash functions" implemented in libavutil. + * If you just need to use one particular hash function, use the @ref lavu_hash + * "individual hash" directly. + * + * @section Sample Code + * + * A basic template for using the Generic Hashing API follows: + * + * @code + * struct AVHashContext *ctx = NULL; + * const char *hash_name = NULL; + * uint8_t *output_buf = NULL; + * + * // Select from a string returned by av_hash_names() + * hash_name = ...; + * + * // Allocate a hash context + * ret = av_hash_alloc(&ctx, hash_name); + * if (ret < 0) + * return ret; + * + * // Initialize the hash context + * av_hash_init(ctx); + * + * // Update the hash context with data + * while (data_left) { + * av_hash_update(ctx, data, size); + * } + * + * // Now we have no more data, so it is time to finalize the hash and get the + * // output. But we need to first allocate an output buffer. Note that you can + * // use any memory allocation function, including malloc(), not just + * // av_malloc(). + * output_buf = av_malloc(av_hash_get_size(ctx)); + * if (!output_buf) + * return AVERROR(ENOMEM); + * + * // Finalize the hash context. + * // You can use any of the av_hash_final*() functions provided, for other + * // output formats. If you do so, be sure to adjust the memory allocation + * // above. See the function documentation below for the exact amount of extra + * // memory needed. + * av_hash_final(ctx, output_buffer); + * + * // Free the context + * av_hash_freep(&ctx); + * @endcode + * + * @section Hash Function-Specific Information + * If the CRC32 hash is selected, the #AV_CRC_32_IEEE polynomial will be + * used. + * + * If the Murmur3 hash is selected, the default seed will be used. See @ref + * lavu_murmur3_seedinfo "Murmur3" for more information. + * + * @{ + */ + +/** + * @example ffhash.c + * This example is a simple command line application that takes one or more + * arguments. It demonstrates a typical use of the hashing API with allocation, + * initialization, updating, and finalizing. + */ + +struct AVHashContext; + +/** + * Allocate a hash context for the algorithm specified by name. + * + * @return >= 0 for success, a negative error code for failure + * + * @note The context is not initialized after a call to this function; you must + * call av_hash_init() to do so. + */ +int av_hash_alloc(struct AVHashContext **ctx, const char *name); + +/** + * Get the names of available hash algorithms. + * + * This function can be used to enumerate the algorithms. + * + * @param[in] i Index of the hash algorithm, starting from 0 + * @return Pointer to a static string or `NULL` if `i` is out of range + */ +const char *av_hash_names(int i); + +/** + * Get the name of the algorithm corresponding to the given hash context. + */ +const char *av_hash_get_name(const struct AVHashContext *ctx); + +/** + * Maximum value that av_hash_get_size() will currently return. + * + * You can use this if you absolutely want or need to use static allocation for + * the output buffer and are fine with not supporting hashes newly added to + * libavutil without recompilation. + * + * @warning + * Adding new hashes with larger sizes, and increasing the macro while doing + * so, will not be considered an ABI change. To prevent your code from + * overflowing a buffer, either dynamically allocate the output buffer with + * av_hash_get_size(), or limit your use of the Hashing API to hashes that are + * already in FFmpeg during the time of compilation. + */ +#define AV_HASH_MAX_SIZE 64 + +/** + * Get the size of the resulting hash value in bytes. + * + * The maximum value this function will currently return is available as macro + * #AV_HASH_MAX_SIZE. + * + * @param[in] ctx Hash context + * @return Size of the hash value in bytes + */ +int av_hash_get_size(const struct AVHashContext *ctx); + +/** + * Initialize or reset a hash context. + * + * @param[in,out] ctx Hash context + */ +void av_hash_init(struct AVHashContext *ctx); + +/** + * Update a hash context with additional data. + * + * @param[in,out] ctx Hash context + * @param[in] src Data to be added to the hash context + * @param[in] len Size of the additional data + */ +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, size_t len); + +/** + * Finalize a hash context and compute the actual hash value. + * + * The minimum size of `dst` buffer is given by av_hash_get_size() or + * #AV_HASH_MAX_SIZE. The use of the latter macro is discouraged. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * + * @see av_hash_final_bin() provides an alternative API + */ +void av_hash_final(struct AVHashContext *ctx, uint8_t *dst); + +/** + * Finalize a hash context and store the actual hash value in a buffer. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * If `size` is smaller than the hash size (given by av_hash_get_size()), the + * hash is truncated; if size is larger, the buffer is padded with 0. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Number of bytes to write to `dst` + */ +void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the hexadecimal representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than `2 * hash_size + 1`, where `hash_size` is the + * value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the string will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the Base64 representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than AV_BASE64_SIZE(hash_size), where `hash_size` is + * the value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Free hash context and set hash context pointer to `NULL`. + * + * @param[in,out] ctx Pointer to hash context + */ +void av_hash_freep(struct AVHashContext **ctx); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_HASH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.c b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.c new file mode 100644 index 00000000..0fa1ee82 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 Mohammad Izadi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "hdr_dynamic_metadata.h" +#include "mem.h" + +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size) +{ + AVDynamicHDRPlus *hdr_plus = av_mallocz(sizeof(AVDynamicHDRPlus)); + if (!hdr_plus) + return NULL; + + if (size) + *size = sizeof(*hdr_plus); + + return hdr_plus; +} + +AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_DYNAMIC_HDR_PLUS, + sizeof(AVDynamicHDRPlus)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVDynamicHDRPlus)); + + return (AVDynamicHDRPlus *)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.h b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.h new file mode 100644 index 00000000..2d72de56 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_metadata.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2018 Mohammad Izadi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HDR_DYNAMIC_METADATA_H +#define AVUTIL_HDR_DYNAMIC_METADATA_H + +#include "frame.h" +#include "rational.h" + +/** + * Option for overlapping elliptical pixel selectors in an image. + */ +enum AVHDRPlusOverlapProcessOption { + AV_HDR_PLUS_OVERLAP_PROCESS_WEIGHTED_AVERAGING = 0, + AV_HDR_PLUS_OVERLAP_PROCESS_LAYERING = 1, +}; + +/** + * Represents the percentile at a specific percentage in + * a distribution. + */ +typedef struct AVHDRPlusPercentile { + /** + * The percentage value corresponding to a specific percentile linearized + * RGB value in the processing window in the scene. The value shall be in + * the range of 0 to100, inclusive. + */ + uint8_t percentage; + + /** + * The linearized maxRGB value at a specific percentile in the processing + * window in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.00001. + */ + AVRational percentile; +} AVHDRPlusPercentile; + +/** + * Color transform parameters at a processing window in a dynamic metadata for + * SMPTE 2094-40. + */ +typedef struct AVHDRPlusColorTransformParams { + /** + * The relative x coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_x; + + /** + * The relative y coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_y; + + /** + * The relative x coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_x; + + /** + * The relative y coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_y; + + /** + * The x coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (width of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_x; + + /** + * The y coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (height of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_y; + + /** + * The clockwise rotation angle in degree of arc with respect to the + * positive direction of the x-axis of the concentric internal and external + * ellipses of the elliptical pixel selector in the processing window. The + * value shall be in the range of 0 to 180, inclusive and in multiples of 1. + */ + uint8_t rotation_angle; + + /** + * The semi-major axis value of the internal ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_internal_ellipse; + + /** + * The semi-major axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value + * shall not be less than semimajor_axis_internal_ellipse of the current + * processing window. The value shall be in the range of 1 to 65535, + * inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_external_ellipse; + + /** + * The semi-minor axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semiminor_axis_external_ellipse; + + /** + * Overlap process option indicates one of the two methods of combining + * rendered pixels in the processing window in an image with at least one + * elliptical pixel selector. For overlapping elliptical pixel selectors + * in an image, overlap_process_option shall have the same value. + */ + enum AVHDRPlusOverlapProcessOption overlap_process_option; + + /** + * The maximum of the color components of linearized RGB values in the + * processing window in the scene. The values should be in the range of 0 to + * 1, inclusive and in multiples of 0.00001. maxscl[ 0 ], maxscl[ 1 ], and + * maxscl[ 2 ] are corresponding to R, G, B color components respectively. + */ + AVRational maxscl[3]; + + /** + * The average of linearized maxRGB values in the processing window in the + * scene. The value should be in the range of 0 to 1, inclusive and in + * multiples of 0.00001. + */ + AVRational average_maxrgb; + + /** + * The number of linearized maxRGB values at given percentiles in the + * processing window in the scene. The maximum value shall be 15. + */ + uint8_t num_distribution_maxrgb_percentiles; + + /** + * The linearized maxRGB values at given percentiles in the + * processing window in the scene. + */ + AVHDRPlusPercentile distribution_maxrgb[15]; + + /** + * The fraction of selected pixels in the image that contains the brightest + * pixel in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.001. + */ + AVRational fraction_bright_pixels; + + /** + * This flag indicates that the metadata for the tone mapping function in + * the processing window is present (for value of 1). + */ + uint8_t tone_mapping_flag; + + /** + * The x coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_x; + + /** + * The y coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_y; + + /** + * The number of the intermediate anchor parameters of the tone mapping + * function in the processing window. The maximum value shall be 15. + */ + uint8_t num_bezier_curve_anchors; + + /** + * The intermediate anchor parameters of the tone mapping function in the + * processing window in the scene. The values should be in the range of 0 + * to 1, inclusive and in multiples of 1/1023. + */ + AVRational bezier_curve_anchors[15]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. Other values are reserved for future use. + */ + uint8_t color_saturation_mapping_flag; + + /** + * The color saturation gain in the processing window in the scene. The + * value shall be in the range of 0 to 63/8, inclusive and in multiples of + * 1/8. The default value shall be 1. + */ + AVRational color_saturation_weight; +} AVHDRPlusColorTransformParams; + +/** + * This struct represents dynamic metadata for color volume transform - + * application 4 of SMPTE 2094-40:2016 standard. + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with + * av_dynamic_hdr_plus_alloc() and its size is not a part of + * the public ABI. + */ +typedef struct AVDynamicHDRPlus { + /** + * Country code by Rec. ITU-T T.35 Annex A. The value shall be 0xB5. + */ + uint8_t itu_t_t35_country_code; + + /** + * Application version in the application defining document in ST-2094 + * suite. The value shall be set to 0. + */ + uint8_t application_version; + + /** + * The number of processing windows. The value shall be in the range + * of 1 to 3, inclusive. + */ + uint8_t num_windows; + + /** + * The color transform parameters for every processing window. + */ + AVHDRPlusColorTransformParams params[3]; + + /** + * The nominal maximum display luminance of the targeted system display, + * in units of 0.0001 candelas per square metre. The value shall be in + * the range of 0 to 10000, inclusive. + */ + AVRational targeted_system_display_maximum_luminance; + + /** + * This flag shall be equal to 0 in bit streams conforming to this version + * of this Specification. The value 1 is reserved for future use. + */ + uint8_t targeted_system_display_actual_peak_luminance_flag; + + /** + * The number of rows in the targeted system_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_targeted_system_display_actual_peak_luminance; + + /** + * The number of columns in the + * targeted_system_display_actual_peak_luminance array. The value shall be + * in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_targeted_system_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the targeted system display. The + * values should be in the range of 0 to 1, inclusive and in multiples of + * 1/15. + */ + AVRational targeted_system_display_actual_peak_luminance[25][25]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. The value 1 is reserved for future use. + */ + uint8_t mastering_display_actual_peak_luminance_flag; + + /** + * The number of rows in the mastering_display_actual_peak_luminance array. + * The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_mastering_display_actual_peak_luminance; + + /** + * The number of columns in the mastering_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_mastering_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the mastering display used for + * mastering the image essence. The values should be in the range of 0 to 1, + * inclusive and in multiples of 1/15. + */ + AVRational mastering_display_actual_peak_luminance[25][25]; +} AVDynamicHDRPlus; + +/** + * Allocate an AVDynamicHDRPlus structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVDynamicHDRPlus filled with default values or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size); + +/** + * Allocate a complete AVDynamicHDRPlus and add it to the frame. + * @param frame The frame which side data is added to. + * + * @return The AVDynamicHDRPlus structure to be filled by caller or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.c b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.c new file mode 100644 index 00000000..32da01f5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2021 Limin Wang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "hdr_dynamic_vivid_metadata.h" +#include "mem.h" + +AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size) +{ + AVDynamicHDRVivid *hdr_vivid = av_mallocz(sizeof(AVDynamicHDRVivid)); + if (!hdr_vivid) + return NULL; + + if (size) + *size = sizeof(*hdr_vivid); + + return hdr_vivid; +} + +AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_DYNAMIC_HDR_VIVID, + sizeof(AVDynamicHDRVivid)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVDynamicHDRVivid)); + + return (AVDynamicHDRVivid *)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.h b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.h new file mode 100644 index 00000000..a34f8307 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hdr_dynamic_vivid_metadata.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2021 Limin Wang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H +#define AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H + +#include "frame.h" +#include "rational.h" + +/** + * Color tone mapping parameters at a processing window in a dynamic metadata for + * CUVA 005.1:2021. + */ +typedef struct AVHDRVividColorToneMappingParams { + /** + * The nominal maximum display luminance of the targeted system display, + * in multiples of 1.0/4095 candelas per square metre. The value shall be in + * the range of 0.0 to 1.0, inclusive. + */ + AVRational targeted_system_display_maximum_luminance; + + /** + * This flag indicates that transfer the base paramter(for value of 1) + */ + int base_enable_flag; + + /** + * base_param_m_p in the base parameter, + * in multiples of 1.0/16383. The value shall be in + * the range of 0.0 to 1.0, inclusive. + */ + AVRational base_param_m_p; + + /** + * base_param_m_m in the base parameter, + * in multiples of 1.0/10. The value shall be in + * the range of 0.0 to 6.3, inclusive. + */ + AVRational base_param_m_m; + + /** + * base_param_m_a in the base parameter, + * in multiples of 1.0/1023. The value shall be in + * the range of 0.0 to 1.0 inclusive. + */ + AVRational base_param_m_a; + + /** + * base_param_m_b in the base parameter, + * in multiples of 1/1023. The value shall be in + * the range of 0.0 to 1.0, inclusive. + */ + AVRational base_param_m_b; + + /** + * base_param_m_n in the base parameter, + * in multiples of 1.0/10. The value shall be in + * the range of 0.0 to 6.3, inclusive. + */ + AVRational base_param_m_n; + + /** + * indicates k1_0 in the base parameter, + * base_param_k1 <= 1: k1_0 = base_param_k1 + * base_param_k1 > 1: reserved + */ + int base_param_k1; + + /** + * indicates k2_0 in the base parameter, + * base_param_k2 <= 1: k2_0 = base_param_k2 + * base_param_k2 > 1: reserved + */ + int base_param_k2; + + /** + * indicates k3_0 in the base parameter, + * base_param_k3 == 1: k3_0 = base_param_k3 + * base_param_k3 == 2: k3_0 = maximum_maxrgb + * base_param_k3 > 2: reserved + */ + int base_param_k3; + + /** + * This flag indicates that delta mode of base paramter(for value of 1) + */ + int base_param_Delta_enable_mode; + + /** + * base_param_Delta in the base parameter, + * in multiples of 1.0/127. The value shall be in + * the range of 0.0 to 1.0, inclusive. + */ + AVRational base_param_Delta; + + /** + * indicates 3Spline_enable_flag in the base parameter, + * This flag indicates that transfer three Spline of base paramter(for value of 1) + */ + int three_Spline_enable_flag; + + /** + * The number of three Spline. The value shall be in the range + * of 1 to 2, inclusive. + */ + int three_Spline_num; + + /** + * The mode of three Spline. the value shall be in the range + * of 0 to 3, inclusive. + */ + int three_Spline_TH_mode; + + /** + * three_Spline_TH_enable_MB is in the range of 0.0 to 1.0, inclusive + * and in multiples of 1.0/255. + * + */ + AVRational three_Spline_TH_enable_MB; + + /** + * 3Spline_TH_enable of three Spline. + * The value shall be in the range of 0.0 to 1.0, inclusive. + * and in multiples of 1.0/4095. + */ + AVRational three_Spline_TH_enable; + + /** + * 3Spline_TH_Delta1 of three Spline. + * The value shall be in the range of 0.0 to 0.25, inclusive, + * and in multiples of 0.25/1023. + */ + AVRational three_Spline_TH_Delta1; + + /** + * 3Spline_TH_Delta2 of three Spline. + * The value shall be in the range of 0.0 to 0.25, inclusive, + * and in multiples of 0.25/1023. + */ + AVRational three_Spline_TH_Delta2; + + /** + * 3Spline_enable_Strength of three Spline. + * The value shall be in the range of 0.0 to 1.0, inclusive, + * and in multiples of 1.0/255. + */ + AVRational three_Spline_enable_Strength; +} AVHDRVividColorToneMappingParams; + + +/** + * Color transform parameters at a processing window in a dynamic metadata for + * CUVA 005.1:2021. + */ +typedef struct AVHDRVividColorTransformParams { + /** + * Indicates the minimum brightness of the displayed content. + * The values should be in the range of 0.0 to 1.0, + * inclusive and in multiples of 1/4095. + */ + AVRational minimum_maxrgb; + + /** + * Indicates the average brightness of the displayed content. + * The values should be in the range of 0.0 to 1.0, + * inclusive and in multiples of 1/4095. + */ + AVRational average_maxrgb; + + /** + * Indicates the variance brightness of the displayed content. + * The values should be in the range of 0.0 to 1.0, + * inclusive and in multiples of 1/4095. + */ + AVRational variance_maxrgb; + + /** + * Indicates the maximum brightness of the displayed content. + * The values should be in the range of 0.0 to 1.0, inclusive + * and in multiples of 1/4095. + */ + AVRational maximum_maxrgb; + + /** + * This flag indicates that the metadata for the tone mapping function in + * the processing window is present (for value of 1). + */ + int tone_mapping_mode_flag; + + /** + * The number of tone mapping param. The value shall be in the range + * of 1 to 2, inclusive. + */ + int tone_mapping_param_num; + + /** + * The color tone mapping parameters. + */ + AVHDRVividColorToneMappingParams tm_params[2]; + + /** + * This flag indicates that the metadata for the color saturation mapping in + * the processing window is present (for value of 1). + */ + int color_saturation_mapping_flag; + + /** + * The number of color saturation param. The value shall be in the range + * of 0 to 7, inclusive. + */ + int color_saturation_num; + + /** + * Indicates the color correction strength parameter. + * The values should be in the range of 0.0 to 2.0, inclusive + * and in multiples of 1/128. + */ + AVRational color_saturation_gain[8]; +} AVHDRVividColorTransformParams; + +/** + * This struct represents dynamic metadata for color volume transform - + * CUVA 005.1:2021 standard + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with + * av_dynamic_hdr_vivid_alloc() and its size is not a part of + * the public ABI. + */ +typedef struct AVDynamicHDRVivid { + /** + * The system start code. The value shall be set to 0x01. + */ + uint8_t system_start_code; + + /** + * The number of processing windows. The value shall be set to 0x01 + * if the system_start_code is 0x01. + */ + uint8_t num_windows; + + /** + * The color transform parameters for every processing window. + */ + AVHDRVividColorTransformParams params[3]; +} AVDynamicHDRVivid; + +/** + * Allocate an AVDynamicHDRVivid structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVDynamicHDRVivid filled with default values or NULL + * on failure. + */ +AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size); + +/** + * Allocate a complete AVDynamicHDRVivid and add it to the frame. + * @param frame The frame which side data is added to. + * + * @return The AVDynamicHDRVivid structure to be filled by caller or NULL + * on failure. + */ +AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hmac.c b/arm/raspi/third_party/ffmpeg/libavutil/hmac.c new file mode 100644 index 00000000..7d241fc7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hmac.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2012 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "attributes.h" +#include "hmac.h" +#include "md5.h" +#include "sha.h" +#include "sha512.h" +#include "mem.h" + +#define MAX_HASHLEN 64 +#define MAX_BLOCKLEN 128 + +typedef void (*hmac_final)(void *ctx, uint8_t *dst); +typedef void (*hmac_update)(void *ctx, const uint8_t *src, size_t len); +typedef void (*hmac_init)(void *ctx); + +struct AVHMAC { + void *hash; + int blocklen, hashlen; + hmac_final final; + hmac_update update; + hmac_init init; + uint8_t key[MAX_BLOCKLEN]; + int keylen; +}; + +#define DEFINE_SHA(bits) \ +static av_cold void sha ## bits ##_init(void *ctx) \ +{ \ + av_sha_init(ctx, bits); \ +} + +#define DEFINE_SHA512(bits) \ +static av_cold void sha ## bits ##_init(void *ctx) \ +{ \ + av_sha512_init(ctx, bits); \ +} + +DEFINE_SHA(160) +DEFINE_SHA(224) +DEFINE_SHA(256) +DEFINE_SHA512(384) +DEFINE_SHA512(512) + +AVHMAC *av_hmac_alloc(enum AVHMACType type) +{ + AVHMAC *c = av_mallocz(sizeof(*c)); + if (!c) + return NULL; + switch (type) { + case AV_HMAC_MD5: + c->blocklen = 64; + c->hashlen = 16; + c->init = (hmac_init) av_md5_init; + c->update = (hmac_update) av_md5_update; + c->final = (hmac_final) av_md5_final; + c->hash = av_md5_alloc(); + break; + case AV_HMAC_SHA1: + c->blocklen = 64; + c->hashlen = 20; + c->init = sha160_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA224: + c->blocklen = 64; + c->hashlen = 28; + c->init = sha224_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA256: + c->blocklen = 64; + c->hashlen = 32; + c->init = sha256_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA384: + c->blocklen = 128; + c->hashlen = 48; + c->init = sha384_init; + c->update = (hmac_update) av_sha512_update; + c->final = (hmac_final) av_sha512_final; + c->hash = av_sha512_alloc(); + break; + case AV_HMAC_SHA512: + c->blocklen = 128; + c->hashlen = 64; + c->init = sha512_init; + c->update = (hmac_update) av_sha512_update; + c->final = (hmac_final) av_sha512_final; + c->hash = av_sha512_alloc(); + break; + default: + av_free(c); + return NULL; + } + if (!c->hash) { + av_free(c); + return NULL; + } + return c; +} + +void av_hmac_free(AVHMAC *c) +{ + if (!c) + return; + av_freep(&c->hash); + av_free(c); +} + +void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen) +{ + int i; + uint8_t block[MAX_BLOCKLEN]; + if (keylen > c->blocklen) { + c->init(c->hash); + c->update(c->hash, key, keylen); + c->final(c->hash, c->key); + c->keylen = c->hashlen; + } else { + memcpy(c->key, key, keylen); + c->keylen = keylen; + } + c->init(c->hash); + for (i = 0; i < c->keylen; i++) + block[i] = c->key[i] ^ 0x36; + for (i = c->keylen; i < c->blocklen; i++) + block[i] = 0x36; + c->update(c->hash, block, c->blocklen); +} + +void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len) +{ + c->update(c->hash, data, len); +} + +int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen) +{ + uint8_t block[MAX_BLOCKLEN]; + int i; + if (outlen < c->hashlen) + return AVERROR(EINVAL); + c->final(c->hash, out); + c->init(c->hash); + for (i = 0; i < c->keylen; i++) + block[i] = c->key[i] ^ 0x5C; + for (i = c->keylen; i < c->blocklen; i++) + block[i] = 0x5C; + c->update(c->hash, block, c->blocklen); + c->update(c->hash, out, c->hashlen); + c->final(c->hash, out); + return c->hashlen; +} + +int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len, + const uint8_t *key, unsigned int keylen, + uint8_t *out, unsigned int outlen) +{ + av_hmac_init(c, key, keylen); + av_hmac_update(c, data, len); + return av_hmac_final(c, out, outlen); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hmac.h b/arm/raspi/third_party/ffmpeg/libavutil/hmac.h new file mode 100644 index 00000000..ca4da6a6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hmac.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HMAC_H +#define AVUTIL_HMAC_H + +#include + +/** + * @defgroup lavu_hmac HMAC + * @ingroup lavu_crypto + * @{ + */ + +enum AVHMACType { + AV_HMAC_MD5, + AV_HMAC_SHA1, + AV_HMAC_SHA224, + AV_HMAC_SHA256, + AV_HMAC_SHA384, + AV_HMAC_SHA512, +}; + +typedef struct AVHMAC AVHMAC; + +/** + * Allocate an AVHMAC context. + * @param type The hash function used for the HMAC. + */ +AVHMAC *av_hmac_alloc(enum AVHMACType type); + +/** + * Free an AVHMAC context. + * @param ctx The context to free, may be NULL + */ +void av_hmac_free(AVHMAC *ctx); + +/** + * Initialize an AVHMAC context with an authentication key. + * @param ctx The HMAC context + * @param key The authentication key + * @param keylen The length of the key, in bytes + */ +void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen); + +/** + * Hash data with the HMAC. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + */ +void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len); + +/** + * Finish hashing and output the HMAC digest. + * @param ctx The HMAC context + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen); + +/** + * Hash an array of data with a key. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + * @param key The authentication key + * @param keylen The length of the key, in bytes + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len, + const uint8_t *key, unsigned int keylen, + uint8_t *out, unsigned int outlen); + +/** + * @} + */ + +#endif /* AVUTIL_HMAC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.c new file mode 100644 index 00000000..33965982 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.c @@ -0,0 +1,955 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "avassert.h" +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "log.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" + +static const HWContextType * const hw_table[] = { +#if CONFIG_CUDA + &ff_hwcontext_type_cuda, +#endif +#if CONFIG_D3D11VA + &ff_hwcontext_type_d3d11va, +#endif +#if CONFIG_LIBDRM + &ff_hwcontext_type_drm, +#endif +#if CONFIG_DXVA2 + &ff_hwcontext_type_dxva2, +#endif +#if CONFIG_OPENCL + &ff_hwcontext_type_opencl, +#endif +#if CONFIG_QSV + &ff_hwcontext_type_qsv, +#endif +#if CONFIG_VAAPI + &ff_hwcontext_type_vaapi, +#endif +#if CONFIG_VDPAU + &ff_hwcontext_type_vdpau, +#endif +#if CONFIG_VIDEOTOOLBOX + &ff_hwcontext_type_videotoolbox, +#endif +#if CONFIG_MEDIACODEC + &ff_hwcontext_type_mediacodec, +#endif +#if CONFIG_VULKAN + &ff_hwcontext_type_vulkan, +#endif + NULL, +}; + +static const char *const hw_type_names[] = { + [AV_HWDEVICE_TYPE_CUDA] = "cuda", + [AV_HWDEVICE_TYPE_DRM] = "drm", + [AV_HWDEVICE_TYPE_DXVA2] = "dxva2", + [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va", + [AV_HWDEVICE_TYPE_OPENCL] = "opencl", + [AV_HWDEVICE_TYPE_QSV] = "qsv", + [AV_HWDEVICE_TYPE_VAAPI] = "vaapi", + [AV_HWDEVICE_TYPE_VDPAU] = "vdpau", + [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", + [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", + [AV_HWDEVICE_TYPE_VULKAN] = "vulkan", +}; + +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) +{ + int type; + for (type = 0; type < FF_ARRAY_ELEMS(hw_type_names); type++) { + if (hw_type_names[type] && !strcmp(hw_type_names[type], name)) + return type; + } + return AV_HWDEVICE_TYPE_NONE; +} + +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type) +{ + if (type > AV_HWDEVICE_TYPE_NONE && + type < FF_ARRAY_ELEMS(hw_type_names)) + return hw_type_names[type]; + else + return NULL; +} + +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev) +{ + enum AVHWDeviceType next; + int i, set = 0; + for (i = 0; hw_table[i]; i++) { + if (prev != AV_HWDEVICE_TYPE_NONE && hw_table[i]->type <= prev) + continue; + if (!set || hw_table[i]->type < next) { + next = hw_table[i]->type; + set = 1; + } + } + return set ? next : AV_HWDEVICE_TYPE_NONE; +} + +static const AVClass hwdevice_ctx_class = { + .class_name = "AVHWDeviceContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwdevice_ctx_free(void *opaque, uint8_t *data) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)data; + + /* uninit might still want access the hw context and the user + * free() callback might destroy it, so uninit has to be called first */ + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_device); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type) +{ + AVHWDeviceContext *ctx; + AVBufferRef *buf; + const HWContextType *hw_type = NULL; + int i; + + for (i = 0; hw_table[i]; i++) { + if (hw_table[i]->type == type) { + hw_type = hw_table[i]; + break; + } + } + if (!hw_type) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->device_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->device_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->device_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->device_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwdevice_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->type = type; + ctx->av_class = &hwdevice_ctx_class; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +int av_hwdevice_ctx_init(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + int ret; + + if (ctx->internal->hw_type->device_init) { + ret = ctx->internal->hw_type->device_init(ctx); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + return ret; +} + +static const AVClass hwframe_ctx_class = { + .class_name = "AVHWFramesContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwframe_ctx_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)data; + + if (ctx->internal->pool_internal) + av_buffer_pool_uninit(&ctx->internal->pool_internal); + + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_frames); + + av_buffer_unref(&ctx->device_ref); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in) +{ + AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data; + const HWContextType *hw_type = device_ctx->internal->hw_type; + AVHWFramesContext *ctx; + AVBufferRef *buf, *device_ref = NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->frames_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->frames_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->frames_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + device_ref = av_buffer_ref(device_ref_in); + if (!device_ref) + goto fail; + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwframe_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->av_class = &hwframe_ctx_class; + ctx->device_ref = device_ref; + ctx->device_ctx = device_ctx; + ctx->format = AV_PIX_FMT_NONE; + ctx->sw_format = AV_PIX_FMT_NONE; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (device_ref) + av_buffer_unref(&device_ref); + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +static int hwframe_pool_prealloc(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + AVFrame **frames; + int i, ret = 0; + + frames = av_calloc(ctx->initial_pool_size, sizeof(*frames)); + if (!frames) + return AVERROR(ENOMEM); + + for (i = 0; i < ctx->initial_pool_size; i++) { + frames[i] = av_frame_alloc(); + if (!frames[i]) + goto fail; + + ret = av_hwframe_get_buffer(ref, frames[i], 0); + if (ret < 0) + goto fail; + } + +fail: + for (i = 0; i < ctx->initial_pool_size; i++) + av_frame_free(&frames[i]); + av_freep(&frames); + + return ret; +} + +int av_hwframe_ctx_init(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + const enum AVPixelFormat *pix_fmt; + int ret; + + if (ctx->internal->source_frames) { + /* A derived frame context is already initialised. */ + return 0; + } + + /* validate the pixel format */ + for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) { + if (*pix_fmt == ctx->format) + break; + } + if (*pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "The hardware pixel format '%s' is not supported by the device type '%s'\n", + av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name); + return AVERROR(ENOSYS); + } + + /* validate the dimensions */ + ret = av_image_check_size(ctx->width, ctx->height, 0, ctx); + if (ret < 0) + return ret; + + /* format-specific init */ + if (ctx->internal->hw_type->frames_init) { + ret = ctx->internal->hw_type->frames_init(ctx); + if (ret < 0) + goto fail; + } + + if (ctx->internal->pool_internal && !ctx->pool) + ctx->pool = ctx->internal->pool_internal; + + /* preallocate the frames in the pool, if requested */ + if (ctx->initial_pool_size > 0) { + ret = hwframe_pool_prealloc(ref); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + return ret; +} + +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + + if (!ctx->internal->hw_type->transfer_get_formats) + return AVERROR(ENOSYS); + + return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats); +} + +static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx; + AVFrame *frame_tmp; + int ret = 0; + + if (!src->hw_frames_ctx) + return AVERROR(EINVAL); + ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + + frame_tmp = av_frame_alloc(); + if (!frame_tmp) + return AVERROR(ENOMEM); + + /* if the format is set, use that + * otherwise pick the first supported one */ + if (dst->format >= 0) { + frame_tmp->format = dst->format; + } else { + enum AVPixelFormat *formats; + + ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx, + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + &formats, 0); + if (ret < 0) + goto fail; + frame_tmp->format = formats[0]; + av_freep(&formats); + } + frame_tmp->width = ctx->width; + frame_tmp->height = ctx->height; + + ret = av_frame_get_buffer(frame_tmp, 0); + if (ret < 0) + goto fail; + + ret = av_hwframe_transfer_data(frame_tmp, src, flags); + if (ret < 0) + goto fail; + + frame_tmp->width = src->width; + frame_tmp->height = src->height; + + av_frame_move_ref(dst, frame_tmp); + +fail: + av_frame_free(&frame_tmp); + return ret; +} + +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx; + int ret; + + if (!dst->buf[0]) + return transfer_data_alloc(dst, src, flags); + + /* + * Hardware -> Hardware Transfer. + * Unlike Software -> Hardware or Hardware -> Software, the transfer + * function could be provided by either the src or dst, depending on + * the specific combination of hardware. + */ + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + AVHWFramesContext *src_ctx = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVHWFramesContext *dst_ctx = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (src_ctx->internal->source_frames) { + av_log(src_ctx, AV_LOG_ERROR, + "A device with a derived frame context cannot be used as " + "the source of a HW -> HW transfer."); + return AVERROR(ENOSYS); + } + + if (dst_ctx->internal->source_frames) { + av_log(src_ctx, AV_LOG_ERROR, + "A device with a derived frame context cannot be used as " + "the destination of a HW -> HW transfer."); + return AVERROR(ENOSYS); + } + + ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src); + if (ret == AVERROR(ENOSYS)) + ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src); + if (ret < 0) + return ret; + } else { + if (src->hw_frames_ctx) { + ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); + if (ret < 0) + return ret; + } else if (dst->hw_frames_ctx) { + ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); + if (ret < 0) + return ret; + } else { + return AVERROR(ENOSYS); + } + } + return 0; +} + +int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + int ret; + + if (ctx->internal->source_frames) { + // This is a derived frame context, so we allocate in the source + // and map the frame immediately. + AVFrame *src_frame; + + frame->format = ctx->format; + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + src_frame = av_frame_alloc(); + if (!src_frame) + return AVERROR(ENOMEM); + + ret = av_hwframe_get_buffer(ctx->internal->source_frames, + src_frame, 0); + if (ret < 0) { + av_frame_free(&src_frame); + return ret; + } + + ret = av_hwframe_map(frame, src_frame, + ctx->internal->source_allocation_map_flags); + if (ret) { + av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived " + "frame context: %d.\n", ret); + av_frame_free(&src_frame); + return ret; + } + + // Free the source frame immediately - the mapped frame still + // contains a reference to it. + av_frame_free(&src_frame); + + return 0; + } + + if (!ctx->internal->hw_type->frames_get_buffer) + return AVERROR(ENOSYS); + + if (!ctx->pool) + return AVERROR(EINVAL); + + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame); + if (ret < 0) { + av_buffer_unref(&frame->hw_frames_ctx); + return ret; + } + + frame->extended_data = frame->data; + + return 0; +} + +void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + + if (hw_type->device_hwconfig_size == 0) + return NULL; + + return av_mallocz(hw_type->device_hwconfig_size); +} + +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + AVHWFramesConstraints *constraints; + + if (!hw_type->frames_get_constraints) + return NULL; + + constraints = av_mallocz(sizeof(*constraints)); + if (!constraints) + return NULL; + + constraints->min_width = constraints->min_height = 0; + constraints->max_width = constraints->max_height = INT_MAX; + + if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) { + return constraints; + } else { + av_hwframe_constraints_free(&constraints); + return NULL; + } +} + +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints) +{ + if (*constraints) { + av_freep(&(*constraints)->valid_hw_formats); + av_freep(&(*constraints)->valid_sw_formats); + } + av_freep(constraints); +} + +int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags) +{ + AVBufferRef *device_ref = NULL; + AVHWDeviceContext *device_ctx; + int ret = 0; + + device_ref = av_hwdevice_ctx_alloc(type); + if (!device_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + device_ctx = (AVHWDeviceContext*)device_ref->data; + + if (!device_ctx->internal->hw_type->device_create) { + ret = AVERROR(ENOSYS); + goto fail; + } + + ret = device_ctx->internal->hw_type->device_create(device_ctx, device, + opts, flags); + if (ret < 0) + goto fail; + + ret = av_hwdevice_ctx_init(device_ref); + if (ret < 0) + goto fail; + + *pdevice_ref = device_ref; + return 0; +fail: + av_buffer_unref(&device_ref); + *pdevice_ref = NULL; + return ret; +} + +int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr, + enum AVHWDeviceType type, + AVBufferRef *src_ref, + AVDictionary *options, int flags) +{ + AVBufferRef *dst_ref = NULL, *tmp_ref; + AVHWDeviceContext *dst_ctx, *tmp_ctx; + int ret = 0; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (tmp_ctx->type == type) { + dst_ref = av_buffer_ref(tmp_ref); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + goto done; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + dst_ref = av_hwdevice_ctx_alloc(type); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst_ctx = (AVHWDeviceContext*)dst_ref->data; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (dst_ctx->internal->hw_type->device_derive) { + ret = dst_ctx->internal->hw_type->device_derive(dst_ctx, + tmp_ctx, + options, + flags); + if (ret == 0) { + dst_ctx->internal->source_device = av_buffer_ref(src_ref); + if (!dst_ctx->internal->source_device) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_hwdevice_ctx_init(dst_ref); + if (ret < 0) + goto fail; + goto done; + } + if (ret != AVERROR(ENOSYS)) + goto fail; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + ret = AVERROR(ENOSYS); + goto fail; + +done: + *dst_ref_ptr = dst_ref; + return 0; + +fail: + av_buffer_unref(&dst_ref); + *dst_ref_ptr = NULL; + return ret; +} + +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, + enum AVHWDeviceType type, + AVBufferRef *src_ref, int flags) +{ + return av_hwdevice_ctx_create_derived_opts(dst_ref_ptr, type, src_ref, + NULL, flags); +} + +static void ff_hwframe_unmap(void *opaque, uint8_t *data) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)data; + AVHWFramesContext *ctx = opaque; + + if (hwmap->unmap) + hwmap->unmap(ctx, hwmap); + + av_frame_free(&hwmap->source); + + av_buffer_unref(&hwmap->hw_frames_ctx); + + av_free(hwmap); +} + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + HWMapDescriptor *hwmap; + int ret; + + hwmap = av_mallocz(sizeof(*hwmap)); + if (!hwmap) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->source = av_frame_alloc(); + if (!hwmap->source) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_frame_ref(hwmap->source, src); + if (ret < 0) + goto fail; + + hwmap->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!hwmap->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->unmap = unmap; + hwmap->priv = priv; + + dst->buf[0] = av_buffer_create((uint8_t*)hwmap, sizeof(*hwmap), + &ff_hwframe_unmap, ctx, 0); + if (!dst->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + if (hwmap) { + av_buffer_unref(&hwmap->hw_frames_ctx); + av_frame_free(&hwmap->source); + } + av_free(hwmap); + return ret; +} + +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) +{ + AVBufferRef *orig_dst_frames = dst->hw_frames_ctx; + enum AVPixelFormat orig_dst_fmt = dst->format; + AVHWFramesContext *src_frames, *dst_frames; + HWMapDescriptor *hwmap; + int ret; + + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if ((src_frames == dst_frames && + src->format == dst_frames->sw_format && + dst->format == dst_frames->format) || + (src_frames->internal->source_frames && + src_frames->internal->source_frames->data == + (uint8_t*)dst_frames)) { + // This is an unmap operation. We don't need to directly + // do anything here other than fill in the original frame, + // because the real unmap will be invoked when the last + // reference to the mapped frame disappears. + if (!src->buf[0]) { + av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " + "found when attempting unmap.\n"); + return AVERROR(EINVAL); + } + hwmap = (HWMapDescriptor*)src->buf[0]->data; + av_frame_unref(dst); + return av_frame_ref(dst, hwmap->source); + } + } + + if (src->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + + if (src_frames->format == src->format && + src_frames->internal->hw_type->map_from) { + ret = src_frames->internal->hw_type->map_from(src_frames, + dst, src, flags); + if (ret >= 0) + return ret; + else if (ret != AVERROR(ENOSYS)) + goto fail; + } + } + + if (dst->hw_frames_ctx) { + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (dst_frames->format == dst->format && + dst_frames->internal->hw_type->map_to) { + ret = dst_frames->internal->hw_type->map_to(dst_frames, + dst, src, flags); + if (ret >= 0) + return ret; + else if (ret != AVERROR(ENOSYS)) + goto fail; + } + } + + return AVERROR(ENOSYS); + +fail: + // if the caller provided dst frames context, it should be preserved + // by this function + av_assert0(orig_dst_frames == NULL || + orig_dst_frames == dst->hw_frames_ctx); + + // preserve user-provided dst frame fields, but clean + // anything we might have set + dst->hw_frames_ctx = NULL; + av_frame_unref(dst); + + dst->hw_frames_ctx = orig_dst_frames; + dst->format = orig_dst_fmt; + + return ret; +} + +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags) +{ + AVBufferRef *dst_ref = NULL; + AVHWFramesContext *dst = NULL; + AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data; + int ret; + + if (src->internal->source_frames) { + AVHWFramesContext *src_src = + (AVHWFramesContext*)src->internal->source_frames->data; + AVHWDeviceContext *dst_dev = + (AVHWDeviceContext*)derived_device_ctx->data; + + if (src_src->device_ctx == dst_dev) { + // This is actually an unmapping, so we just return a + // reference to the source frame context. + *derived_frame_ctx = + av_buffer_ref(src->internal->source_frames); + if (!*derived_frame_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + return 0; + } + } + + dst_ref = av_hwframe_ctx_alloc(derived_device_ctx); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst = (AVHWFramesContext*)dst_ref->data; + + dst->format = format; + dst->sw_format = src->sw_format; + dst->width = src->width; + dst->height = src->height; + + dst->internal->source_frames = av_buffer_ref(source_frame_ctx); + if (!dst->internal->source_frames) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst->internal->source_allocation_map_flags = + flags & (AV_HWFRAME_MAP_READ | + AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE | + AV_HWFRAME_MAP_DIRECT); + + ret = AVERROR(ENOSYS); + if (src->internal->hw_type->frames_derive_from) + ret = src->internal->hw_type->frames_derive_from(dst, src, flags); + if (ret == AVERROR(ENOSYS) && + dst->internal->hw_type->frames_derive_to) + ret = dst->internal->hw_type->frames_derive_to(dst, src, flags); + if (ret == AVERROR(ENOSYS)) + ret = 0; + if (ret) + goto fail; + + *derived_frame_ctx = dst_ref; + return 0; + +fail: + if (dst) + av_buffer_unref(&dst->internal->source_frames); + av_buffer_unref(&dst_ref); + return ret; +} + +int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)dst->buf[0]->data; + av_frame_unref(hwmap->source); + return av_frame_ref(hwmap->source, src); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.h new file mode 100644 index 00000000..7ff08c86 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext.h @@ -0,0 +1,610 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_H +#define AVUTIL_HWCONTEXT_H + +#include "buffer.h" +#include "frame.h" +#include "log.h" +#include "pixfmt.h" + +enum AVHWDeviceType { + AV_HWDEVICE_TYPE_NONE, + AV_HWDEVICE_TYPE_VDPAU, + AV_HWDEVICE_TYPE_CUDA, + AV_HWDEVICE_TYPE_VAAPI, + AV_HWDEVICE_TYPE_DXVA2, + AV_HWDEVICE_TYPE_QSV, + AV_HWDEVICE_TYPE_VIDEOTOOLBOX, + AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_DRM, + AV_HWDEVICE_TYPE_OPENCL, + AV_HWDEVICE_TYPE_MEDIACODEC, + AV_HWDEVICE_TYPE_VULKAN, +}; + +typedef struct AVHWDeviceInternal AVHWDeviceInternal; + +/** + * This struct aggregates all the (hardware/vendor-specific) "high-level" state, + * i.e. state that is not tied to a concrete processing configuration. + * E.g., in an API that supports hardware-accelerated encoding and decoding, + * this struct will (if possible) wrap the state that is common to both encoding + * and decoding and from which specific instances of encoders or decoders can be + * derived. + * + * This struct is reference-counted with the AVBuffer mechanism. The + * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field + * points to the actual AVHWDeviceContext. Further objects derived from + * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with + * specific properties) will hold an internal reference to it. After all the + * references are released, the AVHWDeviceContext itself will be freed, + * optionally invoking a user-specified callback for uninitializing the hardware + * state. + */ +typedef struct AVHWDeviceContext { + /** + * A class for logging. Set by av_hwdevice_ctx_alloc(). + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWDeviceInternal *internal; + + /** + * This field identifies the underlying API used for hardware access. + * + * This field is set when this struct is allocated and never changed + * afterwards. + */ + enum AVHWDeviceType type; + + /** + * The format-specific data, allocated and freed by libavutil along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwcontext_*.h) and filled as described in the + * documentation before calling av_hwdevice_ctx_init(). + * + * After calling av_hwdevice_ctx_init() this struct should not be modified + * by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwdevice_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + * + * @note when other objects (e.g an AVHWFramesContext) are derived from this + * struct, this callback will be invoked after all such child objects + * are fully uninitialized and their respective destructors invoked. + */ + void (*free)(struct AVHWDeviceContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; +} AVHWDeviceContext; + +typedef struct AVHWFramesInternal AVHWFramesInternal; + +/** + * This struct describes a set or pool of "hardware" frames (i.e. those with + * data not located in normal system memory). All the frames in the pool are + * assumed to be allocated in the same way and interchangeable. + * + * This struct is reference-counted with the AVBuffer mechanism and tied to a + * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor + * yields a reference, whose data field points to the actual AVHWFramesContext + * struct. + */ +typedef struct AVHWFramesContext { + /** + * A class for logging. + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWFramesInternal *internal; + + /** + * A reference to the parent AVHWDeviceContext. This reference is owned and + * managed by the enclosing AVHWFramesContext, but the caller may derive + * additional references from it. + */ + AVBufferRef *device_ref; + + /** + * The parent AVHWDeviceContext. This is simply a pointer to + * device_ref->data provided for convenience. + * + * Set by libavutil in av_hwframe_ctx_init(). + */ + AVHWDeviceContext *device_ctx; + + /** + * The format-specific data, allocated and freed automatically along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwframe_*.h) and filled as described in the + * documentation before calling av_hwframe_ctx_init(). + * + * After any frames using this context are created, the contents of this + * struct should not be modified by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + */ + void (*free)(struct AVHWFramesContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; + + /** + * A pool from which the frames are allocated by av_hwframe_get_buffer(). + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * The buffers returned by calling av_buffer_pool_get() on this pool must + * have the properties described in the documentation in the corresponding hw + * type's header (hwcontext_*.h). The pool will be freed strictly before + * this struct's free() callback is invoked. + * + * This field may be NULL, then libavutil will attempt to allocate a pool + * internally. Note that certain device types enforce pools allocated at + * fixed size (frame count), which cannot be extended dynamically. In such a + * case, initial_pool_size must be set appropriately. + */ + AVBufferPool *pool; + + /** + * Initial size of the frame pool. If a device type does not support + * dynamically resizing the pool, then this is also the maximum pool size. + * + * May be set by the caller before calling av_hwframe_ctx_init(). Must be + * set if pool is NULL and the device type does not support dynamic pools. + */ + int initial_pool_size; + + /** + * The pixel format identifying the underlying HW surface type. + * + * Must be a hwaccel format, i.e. the corresponding descriptor must have the + * AV_PIX_FMT_FLAG_HWACCEL flag set. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + enum AVPixelFormat format; + + /** + * The pixel format identifying the actual data layout of the hardware + * frames. + * + * Must be set by the caller before calling av_hwframe_ctx_init(). + * + * @note when the underlying API does not provide the exact data layout, but + * only the colorspace/bit depth, this field should be set to the fully + * planar version of that format (e.g. for 8-bit 420 YUV it should be + * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else). + */ + enum AVPixelFormat sw_format; + + /** + * The allocated dimensions of the frames in this pool. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + int width, height; +} AVHWFramesContext; + +/** + * Look up an AVHWDeviceType by name. + * + * @param name String name of the device type (case-insensitive). + * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if + * not found. + */ +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name); + +/** Get the string name of an AVHWDeviceType. + * + * @param type Type from enum AVHWDeviceType. + * @return Pointer to a static string containing the name, or NULL if the type + * is not valid. + */ +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type); + +/** + * Iterate over supported device types. + * + * @param prev AV_HWDEVICE_TYPE_NONE initially, then the previous type + * returned by this function in subsequent iterations. + * @return The next usable device type from enum AVHWDeviceType, or + * AV_HWDEVICE_TYPE_NONE if there are no more. + */ +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev); + +/** + * Allocate an AVHWDeviceContext for a given hardware type. + * + * @param type the type of the hardware device to allocate. + * @return a reference to the newly created AVHWDeviceContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type); + +/** + * Finalize the device context before use. This function must be called after + * the context is filled with all the required information and before it is + * used in any way. + * + * @param ref a reference to the AVHWDeviceContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwdevice_ctx_init(AVBufferRef *ref); + +/** + * Open a device of the specified type and create an AVHWDeviceContext for it. + * + * This is a convenience function intended to cover the simple cases. Callers + * who need to fine-tune device creation/management should open the device + * manually and then wrap it in an AVHWDeviceContext using + * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). + * + * The returned context is already initialized and ready for use, the caller + * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of + * the created AVHWDeviceContext are set by this function and should not be + * touched by the caller. + * + * @param device_ctx On success, a reference to the newly-created device context + * will be written here. The reference is owned by the caller + * and must be released with av_buffer_unref() when no longer + * needed. On failure, NULL will be written to this pointer. + * @param type The type of the device to create. + * @param device A type-specific string identifying the device to open. + * @param opts A dictionary of additional (type-specific) options to use in + * opening the device. The dictionary remains owned by the caller. + * @param flags currently unused + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags); + +/** + * Create a new device of the specified type from an existing device. + * + * If the source device is a device of the target type or was originally + * derived from such a device (possibly through one or more intermediate + * devices of other types), then this will return a reference to the + * existing device of the same type as is requested. + * + * Otherwise, it will attempt to derive a new device from the given source + * device. If direct derivation to the new type is not implemented, it will + * attempt the same derivation from each ancestor of the source device in + * turn looking for an implemented derivation method. + * + * @param dst_ctx On success, a reference to the newly-created + * AVHWDeviceContext. + * @param type The type of the new device to create. + * @param src_ctx A reference to an existing AVHWDeviceContext which will be + * used to create the new device. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx, + enum AVHWDeviceType type, + AVBufferRef *src_ctx, int flags); + +/** + * Create a new device of the specified type from an existing device. + * + * This function performs the same action as av_hwdevice_ctx_create_derived, + * however, it is able to set options for the new device to be derived. + * + * @param dst_ctx On success, a reference to the newly-created + * AVHWDeviceContext. + * @param type The type of the new device to create. + * @param src_ctx A reference to an existing AVHWDeviceContext which will be + * used to create the new device. + * @param options Options for the new device to create, same format as in + * av_hwdevice_ctx_create. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ctx, + enum AVHWDeviceType type, + AVBufferRef *src_ctx, + AVDictionary *options, int flags); + +/** + * Allocate an AVHWFramesContext tied to a given device context. + * + * @param device_ctx a reference to a AVHWDeviceContext. This function will make + * a new reference for internal use, the one passed to the + * function remains owned by the caller. + * @return a reference to the newly created AVHWFramesContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ctx); + +/** + * Finalize the context before use. This function must be called after the + * context is filled with all the required information and before it is attached + * to any frames. + * + * @param ref a reference to the AVHWFramesContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_ctx_init(AVBufferRef *ref); + +/** + * Allocate a new frame attached to the given AVHWFramesContext. + * + * @param hwframe_ctx a reference to an AVHWFramesContext + * @param frame an empty (freshly allocated or unreffed) frame to be filled with + * newly allocated buffers. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags); + +/** + * Copy data to or from a hw surface. At least one of dst/src must have an + * AVHWFramesContext attached. + * + * If src has an AVHWFramesContext attached, then the format of dst (if set) + * must use one of the formats returned by av_hwframe_transfer_get_formats(src, + * AV_HWFRAME_TRANSFER_DIRECTION_FROM). + * If dst has an AVHWFramesContext attached, then the format of src must use one + * of the formats returned by av_hwframe_transfer_get_formats(dst, + * AV_HWFRAME_TRANSFER_DIRECTION_TO) + * + * dst may be "clean" (i.e. with data/buf pointers unset), in which case the + * data buffers will be allocated by this function using av_frame_get_buffer(). + * If dst->format is set, then this format will be used, otherwise (when + * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen. + * + * The two frames must have matching allocated dimensions (i.e. equal to + * AVHWFramesContext.width/height), since not all device types support + * transferring a sub-rectangle of the whole surface. The display dimensions + * (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but + * also have to be equal for both frames. When the display dimensions are + * smaller than the allocated dimensions, the content of the padding in the + * destination frame is unspecified. + * + * @param dst the destination frame. dst is not touched on failure. + * @param src the source frame. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR error code on failure. + */ +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags); + +enum AVHWFrameTransferDirection { + /** + * Transfer the data from the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + + /** + * Transfer the data to the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_TO, +}; + +/** + * Get a list of possible source or target formats usable in + * av_hwframe_transfer_data(). + * + * @param hwframe_ctx the frame context to obtain the information for + * @param dir the direction of the transfer + * @param formats the pointer to the output format list will be written here. + * The list is terminated with AV_PIX_FMT_NONE and must be freed + * by the caller when no longer needed using av_free(). + * If this function returns successfully, the format list will + * have at least one item (not counting the terminator). + * On failure, the contents of this pointer are unspecified. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags); + + +/** + * This struct describes the constraints on hardware frames attached to + * a given device with a hardware-specific configuration. This is returned + * by av_hwdevice_get_hwframe_constraints() and must be freed by + * av_hwframe_constraints_free() after use. + */ +typedef struct AVHWFramesConstraints { + /** + * A list of possible values for format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. This member will always be filled. + */ + enum AVPixelFormat *valid_hw_formats; + + /** + * A list of possible values for sw_format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. Can be NULL if this information is + * not known. + */ + enum AVPixelFormat *valid_sw_formats; + + /** + * The minimum size of frames in this hw_frames_ctx. + * (Zero if not known.) + */ + int min_width; + int min_height; + + /** + * The maximum size of frames in this hw_frames_ctx. + * (INT_MAX if not known / no limit.) + */ + int max_width; + int max_height; +} AVHWFramesConstraints; + +/** + * Allocate a HW-specific configuration structure for a given HW device. + * After use, the user must free all members as required by the specific + * hardware structure being used, then free the structure itself with + * av_free(). + * + * @param device_ctx a reference to the associated AVHWDeviceContext. + * @return The newly created HW-specific configuration structure on + * success or NULL on failure. + */ +void *av_hwdevice_hwconfig_alloc(AVBufferRef *device_ctx); + +/** + * Get the constraints on HW frames given a device and the HW-specific + * configuration to be used with that device. If no HW-specific + * configuration is provided, returns the maximum possible capabilities + * of the device. + * + * @param ref a reference to the associated AVHWDeviceContext. + * @param hwconfig a filled HW-specific configuration structure, or NULL + * to return the maximum possible capabilities of the device. + * @return AVHWFramesConstraints structure describing the constraints + * on the device, or NULL if not available. + */ +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig); + +/** + * Free an AVHWFrameConstraints structure. + * + * @param constraints The (filled or unfilled) AVHWFrameConstraints structure. + */ +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints); + + +/** + * Flags to apply to frame mappings. + */ +enum { + /** + * The mapping must be readable. + */ + AV_HWFRAME_MAP_READ = 1 << 0, + /** + * The mapping must be writeable. + */ + AV_HWFRAME_MAP_WRITE = 1 << 1, + /** + * The mapped frame will be overwritten completely in subsequent + * operations, so the current frame data need not be loaded. Any values + * which are not overwritten are unspecified. + */ + AV_HWFRAME_MAP_OVERWRITE = 1 << 2, + /** + * The mapping must be direct. That is, there must not be any copying in + * the map or unmap steps. Note that performance of direct mappings may + * be much lower than normal memory. + */ + AV_HWFRAME_MAP_DIRECT = 1 << 3, +}; + +/** + * Map a hardware frame. + * + * This has a number of different possible effects, depending on the format + * and origin of the src and dst frames. On input, src should be a usable + * frame with valid buffers and dst should be blank (typically as just created + * by av_frame_alloc()). src should have an associated hwframe context, and + * dst may optionally have a format and associated hwframe context. + * + * If src was created by mapping a frame from the hwframe context of dst, + * then this function undoes the mapping - dst is replaced by a reference to + * the frame that src was originally mapped from. + * + * If both src and dst have an associated hwframe context, then this function + * attempts to map the src frame from its hardware context to that of dst and + * then fill dst with appropriate data to be usable there. This will only be + * possible if the hwframe contexts and associated devices are compatible - + * given compatible devices, av_hwframe_ctx_create_derived() can be used to + * create a hwframe context for dst in which mapping should be possible. + * + * If src has a hwframe context but dst does not, then the src frame is + * mapped to normal memory and should thereafter be usable as a normal frame. + * If the format is set on dst, then the mapping will attempt to create dst + * with that format and fail if it is not possible. If format is unset (is + * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate + * format to use is (probably the sw_format of the src hwframe context). + * + * A return value of AVERROR(ENOSYS) indicates that the mapping is not + * possible with the given arguments and hwframe setup, while other return + * values indicate that it failed somehow. + * + * On failure, the destination frame will be left blank, except for the + * hw_frames_ctx/format fields thay may have been set by the caller - those will + * be preserved as they were. + * + * @param dst Destination frame, to contain the mapping. + * @param src Source frame, to be mapped. + * @param flags Some combination of AV_HWFRAME_MAP_* flags. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags); + + +/** + * Create and initialise an AVHWFramesContext as a mapping of another existing + * AVHWFramesContext on a different device. + * + * av_hwframe_ctx_init() should not be called after this. + * + * @param derived_frame_ctx On success, a reference to the newly created + * AVHWFramesContext. + * @param format The AVPixelFormat for the derived context. + * @param derived_device_ctx A reference to the device to create the new + * AVHWFramesContext on. + * @param source_frame_ctx A reference to an existing AVHWFramesContext + * which will be mapped to the derived context. + * @param flags Some combination of AV_HWFRAME_MAP_* flags, defining the + * mapping parameters to apply to frames which are allocated + * in the derived device. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags); + +#endif /* AVUTIL_HWCONTEXT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.c new file mode 100644 index 00000000..5ae7711c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.c @@ -0,0 +1,552 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_cuda_internal.h" +#if CONFIG_VULKAN +#include "hwcontext_vulkan.h" +#endif +#include "cuda_check.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "imgutils.h" + +typedef struct CUDAFramesContext { + int shift_width, shift_height; + int tex_alignment; +} CUDAFramesContext; + +static const enum AVPixelFormat supported_formats[] = { + AV_PIX_FMT_NV12, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUVA420P, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_P010, + AV_PIX_FMT_P016, + AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_0RGB32, + AV_PIX_FMT_0BGR32, +#if CONFIG_VULKAN + AV_PIX_FMT_VULKAN, +#endif +}; + +#define CHECK_CU(x) FF_CUDA_CHECK_DL(device_ctx, cu, x) + +static int cuda_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) + constraints->valid_sw_formats[i] = supported_formats[i]; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_CUDA; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void cuda_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = opaque; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + CUcontext dummy; + + CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + + CHECK_CU(cu->cuMemFree((CUdeviceptr)data)); + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); +} + +static AVBufferRef *cuda_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *ctx = opaque; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + AVBufferRef *ret = NULL; + CUcontext dummy = NULL; + CUdeviceptr data; + int err; + + err = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + if (err < 0) + return NULL; + + err = CHECK_CU(cu->cuMemAlloc(&data, size)); + if (err < 0) + goto fail; + + ret = av_buffer_create((uint8_t*)data, size, cuda_buffer_free, ctx, 0); + if (!ret) { + CHECK_CU(cu->cuMemFree(data)); + goto fail; + } + +fail: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return ret; +} + +static int cuda_frames_init(AVHWFramesContext *ctx) +{ + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CUDAFramesContext *priv = ctx->internal->priv; + CudaFunctions *cu = hwctx->internal->cuda_dl; + int err, i; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i]) + break; + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(ENOSYS); + } + + err = CHECK_CU(cu->cuDeviceGetAttribute(&priv->tex_alignment, + 14 /* CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT */, + hwctx->internal->cuda_device)); + if (err < 0) + return err; + + av_log(ctx, AV_LOG_DEBUG, "CUDA texture alignment: %d\n", priv->tex_alignment); + + // YUV420P is a special case. + // Since nvenc expects the U/V planes to have half the linesize of the Y plane + // alignment has to be doubled to ensure the U/V planes still end up aligned. + if (ctx->sw_format == AV_PIX_FMT_YUV420P) + priv->tex_alignment *= 2; + + av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height); + + if (!ctx->pool) { + int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment); + if (size < 0) + return size; + + ctx->internal->pool_internal = av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + CUDAFramesContext *priv = ctx->internal->priv; + int res; + + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data, + ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment); + if (res < 0) + return res; + + // YUV420P is a special case. + // Nvenc expects the U/V planes in swapped order from how ffmpeg expects them, also chroma is half-aligned + if (ctx->sw_format == AV_PIX_FMT_YUV420P) { + frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2; + frame->data[2] = frame->data[1]; + frame->data[1] = frame->data[2] + frame->linesize[2] * (ctx->height / 2); + } + + frame->format = AV_PIX_FMT_CUDA; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int cuda_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int cuda_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + CUDAFramesContext *priv = ctx->internal->priv; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + CUcontext dummy; + int i, ret; + + if ((src->hw_frames_ctx && ((AVHWFramesContext*)src->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA) || + (dst->hw_frames_ctx && ((AVHWFramesContext*)dst->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA)) + return AVERROR(ENOSYS); + + ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + if (ret < 0) + return ret; + + for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) { + CUDA_MEMCPY2D cpy = { + .srcPitch = src->linesize[i], + .dstPitch = dst->linesize[i], + .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]), + .Height = src->height >> ((i == 0 || i == 3) ? 0 : priv->shift_height), + }; + + if (src->hw_frames_ctx) { + cpy.srcMemoryType = CU_MEMORYTYPE_DEVICE; + cpy.srcDevice = (CUdeviceptr)src->data[i]; + } else { + cpy.srcMemoryType = CU_MEMORYTYPE_HOST; + cpy.srcHost = src->data[i]; + } + + if (dst->hw_frames_ctx) { + cpy.dstMemoryType = CU_MEMORYTYPE_DEVICE; + cpy.dstDevice = (CUdeviceptr)dst->data[i]; + } else { + cpy.dstMemoryType = CU_MEMORYTYPE_HOST; + cpy.dstHost = dst->data[i]; + } + + ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream)); + if (ret < 0) + goto exit; + } + + if (!dst->hw_frames_ctx) { + ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream)); + if (ret < 0) + goto exit; + } + +exit: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + return 0; +} + +static void cuda_device_uninit(AVHWDeviceContext *device_ctx) +{ + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + + if (hwctx->internal) { + CudaFunctions *cu = hwctx->internal->cuda_dl; + + if (hwctx->internal->is_allocated && hwctx->cuda_ctx) { + if (hwctx->internal->flags & AV_CUDA_USE_PRIMARY_CONTEXT) + CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal->cuda_device)); + else + CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx)); + + hwctx->cuda_ctx = NULL; + } + + cuda_free_functions(&hwctx->internal->cuda_dl); + } + + av_freep(&hwctx->internal); +} + +static int cuda_device_init(AVHWDeviceContext *ctx) +{ + AVCUDADeviceContext *hwctx = ctx->hwctx; + int ret; + + if (!hwctx->internal) { + hwctx->internal = av_mallocz(sizeof(*hwctx->internal)); + if (!hwctx->internal) + return AVERROR(ENOMEM); + } + + if (!hwctx->internal->cuda_dl) { + ret = cuda_load_functions(&hwctx->internal->cuda_dl, ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Could not dynamically load CUDA\n"); + goto error; + } + } + + return 0; + +error: + cuda_device_uninit(ctx); + return ret; +} + +static int cuda_context_init(AVHWDeviceContext *device_ctx, int flags) { + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu; + CUcontext dummy; + int ret, dev_active = 0; + unsigned int dev_flags = 0; + + const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC; + + cu = hwctx->internal->cuda_dl; + + hwctx->internal->flags = flags; + + if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) { + ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, + &dev_flags, &dev_active)); + if (ret < 0) + return ret; + + if (dev_active && dev_flags != desired_flags) { + av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n"); + return AVERROR(ENOTSUP); + } else if (dev_flags != desired_flags) { + ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device, + desired_flags)); + if (ret < 0) + return ret; + } + + ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, + hwctx->internal->cuda_device)); + if (ret < 0) + return ret; + } else { + ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, + hwctx->internal->cuda_device)); + if (ret < 0) + return ret; + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + } + + hwctx->internal->is_allocated = 1; + + // Setting stream to NULL will make functions automatically use the default CUstream + hwctx->stream = NULL; + + return 0; +} + +static int cuda_flags_from_opts(AVHWDeviceContext *device_ctx, + AVDictionary *opts, int *flags) +{ + AVDictionaryEntry *primary_ctx_opt = av_dict_get(opts, "primary_ctx", NULL, 0); + + if (primary_ctx_opt && strtol(primary_ctx_opt->value, NULL, 10)) { + av_log(device_ctx, AV_LOG_VERBOSE, "Using CUDA primary device context\n"); + *flags |= AV_CUDA_USE_PRIMARY_CONTEXT; + } else if (primary_ctx_opt) { + av_log(device_ctx, AV_LOG_VERBOSE, "Disabling use of CUDA primary device context\n"); + *flags &= ~AV_CUDA_USE_PRIMARY_CONTEXT; + } + + return 0; +} + +static int cuda_device_create(AVHWDeviceContext *device_ctx, + const char *device, + AVDictionary *opts, int flags) +{ + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu; + int ret, device_idx = 0; + + ret = cuda_flags_from_opts(device_ctx, opts, &flags); + if (ret < 0) + goto error; + + if (device) + device_idx = strtol(device, NULL, 0); + + ret = cuda_device_init(device_ctx); + if (ret < 0) + goto error; + + cu = hwctx->internal->cuda_dl; + + ret = CHECK_CU(cu->cuInit(0)); + if (ret < 0) + goto error; + + ret = CHECK_CU(cu->cuDeviceGet(&hwctx->internal->cuda_device, device_idx)); + if (ret < 0) + goto error; + + ret = cuda_context_init(device_ctx, flags); + if (ret < 0) + goto error; + + return 0; + +error: + cuda_device_uninit(device_ctx); + return ret; +} + +static int cuda_device_derive(AVHWDeviceContext *device_ctx, + AVHWDeviceContext *src_ctx, AVDictionary *opts, + int flags) { + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu; + const char *src_uuid = NULL; +#if CONFIG_VULKAN + VkPhysicalDeviceIDProperties vk_idp; +#endif + int ret, i, device_count; + + ret = cuda_flags_from_opts(device_ctx, opts, &flags); + if (ret < 0) + goto error; + +#if CONFIG_VULKAN + vk_idp = (VkPhysicalDeviceIDProperties) { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, + }; +#endif + + switch (src_ctx->type) { +#if CONFIG_VULKAN +#define TYPE PFN_vkGetPhysicalDeviceProperties2 + case AV_HWDEVICE_TYPE_VULKAN: { + AVVulkanDeviceContext *vkctx = src_ctx->hwctx; + TYPE prop_fn = (TYPE)vkctx->get_proc_addr(vkctx->inst, "vkGetPhysicalDeviceProperties2"); + VkPhysicalDeviceProperties2 vk_dev_props = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &vk_idp, + }; + prop_fn(vkctx->phys_dev, &vk_dev_props); + src_uuid = vk_idp.deviceUUID; + break; + } +#undef TYPE +#endif + default: + ret = AVERROR(ENOSYS); + goto error; + } + + if (!src_uuid) { + av_log(device_ctx, AV_LOG_ERROR, + "Failed to get UUID of source device.\n"); + ret = AVERROR(EINVAL); + goto error; + } + + ret = cuda_device_init(device_ctx); + if (ret < 0) + goto error; + + cu = hwctx->internal->cuda_dl; + + ret = CHECK_CU(cu->cuInit(0)); + if (ret < 0) + goto error; + + ret = CHECK_CU(cu->cuDeviceGetCount(&device_count)); + if (ret < 0) + goto error; + + hwctx->internal->cuda_device = -1; + for (i = 0; i < device_count; i++) { + CUdevice dev; + CUuuid uuid; + + ret = CHECK_CU(cu->cuDeviceGet(&dev, i)); + if (ret < 0) + goto error; + + ret = CHECK_CU(cu->cuDeviceGetUuid(&uuid, dev)); + if (ret < 0) + goto error; + + if (memcmp(src_uuid, uuid.bytes, sizeof (uuid.bytes)) == 0) { + hwctx->internal->cuda_device = dev; + break; + } + } + + if (hwctx->internal->cuda_device == -1) { + av_log(device_ctx, AV_LOG_ERROR, "Could not derive CUDA device.\n"); + goto error; + } + + ret = cuda_context_init(device_ctx, flags); + if (ret < 0) + goto error; + + return 0; + +error: + cuda_device_uninit(device_ctx); + return ret; +} + +const HWContextType ff_hwcontext_type_cuda = { + .type = AV_HWDEVICE_TYPE_CUDA, + .name = "CUDA", + + .device_hwctx_size = sizeof(AVCUDADeviceContext), + .frames_priv_size = sizeof(CUDAFramesContext), + + .device_create = cuda_device_create, + .device_derive = cuda_device_derive, + .device_init = cuda_device_init, + .device_uninit = cuda_device_uninit, + .frames_get_constraints = cuda_frames_get_constraints, + .frames_init = cuda_frames_init, + .frames_get_buffer = cuda_get_buffer, + .transfer_get_formats = cuda_transfer_get_formats, + .transfer_data_to = cuda_transfer_data, + .transfer_data_from = cuda_transfer_data, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.h new file mode 100644 index 00000000..cefbe0ce --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda.h @@ -0,0 +1,69 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_CUDA_H +#define AVUTIL_HWCONTEXT_CUDA_H + +#ifndef CUDA_VERSION +#include +#endif + +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_CUDA. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CUdeviceptr. + */ + +typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal; + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVCUDADeviceContext { + CUcontext cuda_ctx; + CUstream stream; + AVCUDADeviceContextInternal *internal; +} AVCUDADeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +/** + * @defgroup hwcontext_cuda Device context creation flags + * + * Flags for av_hwdevice_ctx_create. + * + * @{ + */ + +/** + * Use primary device context instead of creating a new one. + */ +#define AV_CUDA_USE_PRIMARY_CONTEXT (1 << 0) + +/** + * @} + */ + +#endif /* AVUTIL_HWCONTEXT_CUDA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda_internal.h new file mode 100644 index 00000000..d5633c58 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_cuda_internal.h @@ -0,0 +1,39 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_CUDA_INTERNAL_H +#define AVUTIL_HWCONTEXT_CUDA_INTERNAL_H + +#include "compat/cuda/dynlink_loader.h" +#include "hwcontext_cuda.h" + +/** + * @file + * FFmpeg internal API for CUDA. + */ + +struct AVCUDADeviceContextInternal { + CudaFunctions *cuda_dl; + int is_allocated; + CUdevice cuda_device; + int flags; +}; + +#endif /* AVUTIL_HWCONTEXT_CUDA_INTERNAL_H */ + diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.c new file mode 100644 index 00000000..363ec6a4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.c @@ -0,0 +1,650 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#define COBJMACROS + +#include +#include +#include + +#if HAVE_DXGIDEBUG_H +#include +#endif + +#include "avassert.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_d3d11va.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "thread.h" +#include "compat/w32dlfcn.h" + +typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); + +static AVOnce functions_loaded = AV_ONCE_INIT; + +static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory; +static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice; + +static av_cold void load_functions(void) +{ +#if !HAVE_UWP + // We let these "leak" - this is fine, as unloading has no great benefit, and + // Windows will mark a DLL as loaded forever if its internal refcount overflows + // from too many LoadLibrary calls. + HANDLE d3dlib, dxgilib; + + d3dlib = dlopen("d3d11.dll", 0); + dxgilib = dlopen("dxgi.dll", 0); + if (!d3dlib || !dxgilib) + return; + + mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice"); + mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory"); +#else + // In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't available, + // only CreateDXGIFactory1 + mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) D3D11CreateDevice; + mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) CreateDXGIFactory1; +#endif +} + +typedef struct D3D11VAFramesContext { + int nb_surfaces; + int nb_surfaces_used; + + DXGI_FORMAT format; + + ID3D11Texture2D *staging_texture; +} D3D11VAFramesContext; + +static const struct { + DXGI_FORMAT d3d_format; + enum AVPixelFormat pix_fmt; +} supported_formats[] = { + { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 }, + { DXGI_FORMAT_P010, AV_PIX_FMT_P010 }, + { DXGI_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGRA }, + { DXGI_FORMAT_R10G10B10A2_UNORM, AV_PIX_FMT_X2BGR10 }, + { DXGI_FORMAT_R16G16B16A16_FLOAT, AV_PIX_FMT_RGBAF16 }, + // Special opaque formats. The pix_fmt is merely a place holder, as the + // opaque format cannot be accessed directly. + { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P }, +}; + +static void d3d11va_default_lock(void *ctx) +{ + WaitForSingleObjectEx(ctx, INFINITE, FALSE); +} + +static void d3d11va_default_unlock(void *ctx) +{ + ReleaseMutex(ctx); +} + +static void d3d11va_frames_uninit(AVHWFramesContext *ctx) +{ + AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + + if (frames_hwctx->texture) + ID3D11Texture2D_Release(frames_hwctx->texture); + frames_hwctx->texture = NULL; + + if (s->staging_texture) + ID3D11Texture2D_Release(s->staging_texture); + s->staging_texture = NULL; + + av_freep(&frames_hwctx->texture_infos); +} + +static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; + int nb_sw_formats = 0; + HRESULT hr; + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + UINT format_support = 0; + hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support); + if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D)) + constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt; + } + constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void free_texture(void *opaque, uint8_t *data) +{ + ID3D11Texture2D_Release((ID3D11Texture2D *)opaque); + av_free(data); +} + +static AVBufferRef *wrap_texture_buf(AVHWFramesContext *ctx, ID3D11Texture2D *tex, int index) +{ + AVBufferRef *buf; + AVD3D11FrameDescriptor *desc = av_mallocz(sizeof(*desc)); + D3D11VAFramesContext *s = ctx->internal->priv; + AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx; + if (!desc) { + ID3D11Texture2D_Release(tex); + return NULL; + } + + if (s->nb_surfaces <= s->nb_surfaces_used) { + frames_hwctx->texture_infos = av_realloc_f(frames_hwctx->texture_infos, + s->nb_surfaces_used + 1, + sizeof(*frames_hwctx->texture_infos)); + if (!frames_hwctx->texture_infos) { + ID3D11Texture2D_Release(tex); + return NULL; + } + s->nb_surfaces = s->nb_surfaces_used + 1; + } + + frames_hwctx->texture_infos[s->nb_surfaces_used].texture = tex; + frames_hwctx->texture_infos[s->nb_surfaces_used].index = index; + s->nb_surfaces_used++; + + desc->texture = tex; + desc->index = index; + + buf = av_buffer_create((uint8_t *)desc, sizeof(desc), free_texture, tex, 0); + if (!buf) { + ID3D11Texture2D_Release(tex); + av_free(desc); + return NULL; + } + + return buf; +} + +static AVBufferRef *d3d11va_alloc_single(AVHWFramesContext *ctx) +{ + D3D11VAFramesContext *s = ctx->internal->priv; + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + HRESULT hr; + ID3D11Texture2D *tex; + D3D11_TEXTURE2D_DESC texDesc = { + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = s->format, + .SampleDesc = { .Count = 1 }, + .ArraySize = 1, + .Usage = D3D11_USAGE_DEFAULT, + .BindFlags = hwctx->BindFlags, + .MiscFlags = hwctx->MiscFlags, + }; + + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); + return NULL; + } + + return wrap_texture_buf(ctx, tex, 0); +} + +static AVBufferRef *d3d11va_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + D3D11VAFramesContext *s = ctx->internal->priv; + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + D3D11_TEXTURE2D_DESC texDesc; + + if (!hwctx->texture) + return d3d11va_alloc_single(ctx); + + ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc); + + if (s->nb_surfaces_used >= texDesc.ArraySize) { + av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n"); + return NULL; + } + + ID3D11Texture2D_AddRef(hwctx->texture); + return wrap_texture_buf(ctx, hwctx->texture, s->nb_surfaces_used); +} + +static int d3d11va_frames_init(AVHWFramesContext *ctx) +{ + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + + int i; + HRESULT hr; + D3D11_TEXTURE2D_DESC texDesc; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i].pix_fmt) { + s->format = supported_formats[i].d3d_format; + break; + } + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(EINVAL); + } + + texDesc = (D3D11_TEXTURE2D_DESC){ + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = s->format, + .SampleDesc = { .Count = 1 }, + .ArraySize = ctx->initial_pool_size, + .Usage = D3D11_USAGE_DEFAULT, + .BindFlags = hwctx->BindFlags, + .MiscFlags = hwctx->MiscFlags, + }; + + if (hwctx->texture) { + D3D11_TEXTURE2D_DESC texDesc2; + ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc2); + + if (texDesc.Width != texDesc2.Width || + texDesc.Height != texDesc2.Height || + texDesc.Format != texDesc2.Format) { + av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n"); + return AVERROR(EINVAL); + } + + ctx->initial_pool_size = texDesc2.ArraySize; + hwctx->BindFlags = texDesc2.BindFlags; + hwctx->MiscFlags = texDesc2.MiscFlags; + } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && texDesc.ArraySize > 0) { + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + } + + hwctx->texture_infos = av_realloc_f(NULL, ctx->initial_pool_size, sizeof(*hwctx->texture_infos)); + if (!hwctx->texture_infos) + return AVERROR(ENOMEM); + s->nb_surfaces = ctx->initial_pool_size; + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor), + ctx, d3d11va_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + return 0; +} + +static int d3d11va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + AVD3D11FrameDescriptor *desc; + + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + desc = (AVD3D11FrameDescriptor *)frame->buf[0]->data; + + frame->data[0] = (uint8_t *)desc->texture; + frame->data[1] = (uint8_t *)desc->index; + frame->format = AV_PIX_FMT_D3D11; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int d3d11va_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + D3D11VAFramesContext *s = ctx->internal->priv; + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + // Don't signal support for opaque formats. Actual access would fail. + if (s->format == DXGI_FORMAT_420_OPAQUE) + fmts[0] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int d3d11va_create_staging_texture(AVHWFramesContext *ctx, DXGI_FORMAT format) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + HRESULT hr; + D3D11_TEXTURE2D_DESC texDesc = { + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = format, + .SampleDesc = { .Count = 1 }, + .ArraySize = 1, + .Usage = D3D11_USAGE_STAGING, + .CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, + }; + + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &s->staging_texture); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the staging texture (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static void fill_texture_ptrs(uint8_t *data[4], int linesize[4], + AVHWFramesContext *ctx, + D3D11_TEXTURE2D_DESC *desc, + D3D11_MAPPED_SUBRESOURCE *map) +{ + int i; + + for (i = 0; i < 4; i++) + linesize[i] = map->RowPitch; + + av_image_fill_pointers(data, ctx->sw_format, desc->Height, + (uint8_t*)map->pData, linesize); +} + +static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + int download = src->format == AV_PIX_FMT_D3D11; + const AVFrame *frame = download ? src : dst; + const AVFrame *other = download ? dst : src; + // (The interface types are compatible.) + ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D *)frame->data[0]; + int index = (intptr_t)frame->data[1]; + ID3D11Resource *staging; + int w = FFMIN(dst->width, src->width); + int h = FFMIN(dst->height, src->height); + uint8_t *map_data[4]; + int map_linesize[4]; + D3D11_TEXTURE2D_DESC desc; + D3D11_MAPPED_SUBRESOURCE map; + HRESULT hr; + int res; + + if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format) + return AVERROR(EINVAL); + + device_hwctx->lock(device_hwctx->lock_ctx); + + if (!s->staging_texture) { + ID3D11Texture2D_GetDesc((ID3D11Texture2D *)texture, &desc); + res = d3d11va_create_staging_texture(ctx, desc.Format); + if (res < 0) + return res; + } + + staging = (ID3D11Resource *)s->staging_texture; + + ID3D11Texture2D_GetDesc(s->staging_texture, &desc); + + if (download) { + ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, + staging, 0, 0, 0, 0, + texture, index, NULL); + + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, + staging, 0, D3D11_MAP_READ, 0, &map); + if (FAILED(hr)) + goto map_failed; + + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); + + av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize, + ctx->sw_format, w, h); + + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); + } else { + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, + staging, 0, D3D11_MAP_WRITE, 0, &map); + if (FAILED(hr)) + goto map_failed; + + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); + + av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize, + ctx->sw_format, w, h); + + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); + + ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, + texture, index, 0, 0, 0, + staging, 0, NULL); + } + + device_hwctx->unlock(device_hwctx->lock_ctx); + return 0; + +map_failed: + av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", (long)hr); + device_hwctx->unlock(device_hwctx->lock_ctx); + return AVERROR_UNKNOWN; +} + +static int d3d11va_device_init(AVHWDeviceContext *hwdev) +{ + AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx; + HRESULT hr; + + if (!device_hwctx->lock) { + device_hwctx->lock_ctx = CreateMutex(NULL, 0, NULL); + if (device_hwctx->lock_ctx == INVALID_HANDLE_VALUE) { + av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n"); + return AVERROR(EINVAL); + } + device_hwctx->lock = d3d11va_default_lock; + device_hwctx->unlock = d3d11va_default_unlock; + } + + if (!device_hwctx->device_context) { + ID3D11Device_GetImmediateContext(device_hwctx->device, &device_hwctx->device_context); + if (!device_hwctx->device_context) + return AVERROR_UNKNOWN; + } + + if (!device_hwctx->video_device) { + hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device, &IID_ID3D11VideoDevice, + (void **)&device_hwctx->video_device); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + } + + if (!device_hwctx->video_context) { + hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device_context, &IID_ID3D11VideoContext, + (void **)&device_hwctx->video_context); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + } + + return 0; +} + +static void d3d11va_device_uninit(AVHWDeviceContext *hwdev) +{ + AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx; + + if (device_hwctx->device) { + ID3D11Device_Release(device_hwctx->device); + device_hwctx->device = NULL; + } + + if (device_hwctx->device_context) { + ID3D11DeviceContext_Release(device_hwctx->device_context); + device_hwctx->device_context = NULL; + } + + if (device_hwctx->video_device) { + ID3D11VideoDevice_Release(device_hwctx->video_device); + device_hwctx->video_device = NULL; + } + + if (device_hwctx->video_context) { + ID3D11VideoContext_Release(device_hwctx->video_context); + device_hwctx->video_context = NULL; + } + + if (device_hwctx->lock == d3d11va_default_lock) { + CloseHandle(device_hwctx->lock_ctx); + device_hwctx->lock_ctx = INVALID_HANDLE_VALUE; + device_hwctx->lock = NULL; + } +} + +static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; + + HRESULT hr; + IDXGIAdapter *pAdapter = NULL; + ID3D10Multithread *pMultithread; + UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; + int is_debug = !!av_dict_get(opts, "debug", NULL, 0); + int ret; + + // (On UWP we can't check this.) +#if !HAVE_UWP + if (!LoadLibrary("d3d11_1sdklayers.dll")) + is_debug = 0; +#endif + + if (is_debug) + creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + + if ((ret = ff_thread_once(&functions_loaded, load_functions)) != 0) + return AVERROR_UNKNOWN; + if (!mD3D11CreateDevice || !mCreateDXGIFactory) { + av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n"); + return AVERROR_UNKNOWN; + } + + if (device) { + IDXGIFactory2 *pDXGIFactory; + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory); + if (SUCCEEDED(hr)) { + int adapter = atoi(device); + if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter))) + pAdapter = NULL; + IDXGIFactory2_Release(pDXGIFactory); + } + } + + if (pAdapter) { + DXGI_ADAPTER_DESC desc; + hr = IDXGIAdapter2_GetDesc(pAdapter, &desc); + if (!FAILED(hr)) { + av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n", + desc.VendorId, desc.DeviceId, desc.Description); + } + } + + hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0, + D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL); + if (pAdapter) + IDXGIAdapter_Release(pAdapter); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + + hr = ID3D11Device_QueryInterface(device_hwctx->device, &IID_ID3D10Multithread, (void **)&pMultithread); + if (SUCCEEDED(hr)) { + ID3D10Multithread_SetMultithreadProtected(pMultithread, TRUE); + ID3D10Multithread_Release(pMultithread); + } + +#if !HAVE_UWP && HAVE_DXGIDEBUG_H + if (is_debug) { + HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll"); + if (dxgidebug_dll) { + HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug) + = (void *)GetProcAddress(dxgidebug_dll, "DXGIGetDebugInterface"); + if (pf_DXGIGetDebugInterface) { + IDXGIDebug *dxgi_debug = NULL; + hr = pf_DXGIGetDebugInterface(&IID_IDXGIDebug, (void**)&dxgi_debug); + if (SUCCEEDED(hr) && dxgi_debug) + IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL); + } + } + } +#endif + + return 0; +} + +const HWContextType ff_hwcontext_type_d3d11va = { + .type = AV_HWDEVICE_TYPE_D3D11VA, + .name = "D3D11VA", + + .device_hwctx_size = sizeof(AVD3D11VADeviceContext), + .frames_hwctx_size = sizeof(AVD3D11VAFramesContext), + .frames_priv_size = sizeof(D3D11VAFramesContext), + + .device_create = d3d11va_device_create, + .device_init = d3d11va_device_init, + .device_uninit = d3d11va_device_uninit, + .frames_get_constraints = d3d11va_frames_get_constraints, + .frames_init = d3d11va_frames_init, + .frames_uninit = d3d11va_frames_uninit, + .frames_get_buffer = d3d11va_get_buffer, + .transfer_get_formats = d3d11va_transfer_get_formats, + .transfer_data_to = d3d11va_transfer_data, + .transfer_data_from = d3d11va_transfer_data, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_D3D11, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.h new file mode 100644 index 00000000..77d2d72f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_d3d11va.h @@ -0,0 +1,178 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_D3D11VA_H +#define AVUTIL_HWCONTEXT_D3D11VA_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_D3D11VA. + * + * The default pool implementation will be fixed-size if initial_pool_size is + * set (and allocate elements from an array texture). Otherwise it will allocate + * individual textures. Be aware that decoding requires a single array texture. + * + * Using sw_format==AV_PIX_FMT_YUV420P has special semantics, and maps to + * DXGI_FORMAT_420_OPAQUE. av_hwframe_transfer_data() is not supported for + * this format. Refer to MSDN for details. + * + * av_hwdevice_ctx_create() for this device type supports a key named "debug" + * for the AVDictionary entry. If this is set to any value, the device creation + * code will try to load various supported D3D debugging layers. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVD3D11VADeviceContext { + /** + * Device used for texture creation and access. This can also be used to + * set the libavcodec decoding device. + * + * Must be set by the user. This is the only mandatory field - the other + * device context fields are set from this and are available for convenience. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11Device *device; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11DeviceContext *device_context; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoDevice *video_device; + + /** + * If unset, this will be set from the device_context field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoContext *video_context; + + /** + * Callbacks for locking. They protect accesses to device_context and + * video_context calls. They also protect access to the internal staging + * texture (for av_hwframe_transfer_data() calls). They do NOT protect + * access to hwcontext or decoder state in general. + * + * If unset on init, the hwcontext implementation will set them to use an + * internal mutex. + * + * The underlying lock must be recursive. lock_ctx is for free use by the + * locking implementation. + */ + void (*lock)(void *lock_ctx); + void (*unlock)(void *lock_ctx); + void *lock_ctx; +} AVD3D11VADeviceContext; + +/** + * D3D11 frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + * + * This has no use outside of custom allocation, and AVFrame AVBufferRef do not + * necessarily point to an instance of this struct. + */ +typedef struct AVD3D11FrameDescriptor { + /** + * The texture in which the frame is located. The reference count is + * managed by the AVBufferRef, and destroying the reference will release + * the interface. + * + * Normally stored in AVFrame.data[0]. + */ + ID3D11Texture2D *texture; + + /** + * The index into the array texture element representing the frame, or 0 + * if the texture is not an array texture. + * + * Normally stored in AVFrame.data[1] (cast from intptr_t). + */ + intptr_t index; +} AVD3D11FrameDescriptor; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVD3D11VAFramesContext { + /** + * The canonical texture used for pool allocation. If this is set to NULL + * on init, the hwframes implementation will allocate and set an array + * texture if initial_pool_size > 0. + * + * The only situation when the API user should set this is: + * - the user wants to do manual pool allocation (setting + * AVHWFramesContext.pool), instead of letting AVHWFramesContext + * allocate the pool + * - of an array texture + * - and wants it to use it for decoding + * - this has to be done before calling av_hwframe_ctx_init() + * + * Deallocating the AVHWFramesContext will always release this interface, + * and it does not matter whether it was user-allocated. + * + * This is in particular used by the libavcodec D3D11VA hwaccel, which + * requires a single array texture. It will create ID3D11VideoDecoderOutputView + * objects for each array texture element on decoder initialization. + */ + ID3D11Texture2D *texture; + + /** + * D3D11_TEXTURE2D_DESC.BindFlags used for texture creation. The user must + * at least set D3D11_BIND_DECODER if the frames context is to be used for + * video decoding. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT BindFlags; + + /** + * D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT MiscFlags; + + /** + * In case if texture structure member above is not NULL contains the same texture + * pointer for all elements and different indexes into the array texture. + * In case if texture structure member above is NULL, all elements contains + * pointers to separate non-array textures and 0 indexes. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + AVD3D11FrameDescriptor *texture_infos; +} AVD3D11VAFramesContext; + +#endif /* AVUTIL_HWCONTEXT_D3D11VA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.c new file mode 100644 index 00000000..7a9fdbd2 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.c @@ -0,0 +1,323 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include + +/* This was introduced in version 4.6. And may not exist all without an + * optional package. So to prevent a hard dependency on needing the Linux + * kernel headers to compile, make this optional. */ +#if HAVE_LINUX_DMA_BUF_H +#include +#include +#endif + +#include +#include + +#include "avassert.h" +#include "hwcontext.h" +#include "hwcontext_drm.h" +#include "hwcontext_internal.h" +#include "imgutils.h" + + +static void drm_device_free(AVHWDeviceContext *hwdev) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + + close(hwctx->fd); +} + +static int drm_device_create(AVHWDeviceContext *hwdev, const char *device, + AVDictionary *opts, int flags) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + drmVersionPtr version; + + hwctx->fd = open(device, O_RDWR); + if (hwctx->fd < 0) + return AVERROR(errno); + + version = drmGetVersion(hwctx->fd); + if (!version) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get version information " + "from %s: probably not a DRM device?\n", device); + close(hwctx->fd); + return AVERROR(EINVAL); + } + + av_log(hwdev, AV_LOG_VERBOSE, "Opened DRM device %s: driver %s " + "version %d.%d.%d.\n", device, version->name, + version->version_major, version->version_minor, + version->version_patchlevel); + + drmFreeVersion(version); + + hwdev->free = &drm_device_free; + + return 0; +} + +static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = (uint8_t*)frame->buf[0]->data; + + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +typedef struct DRMMapping { + // Address and length of each mmap()ed region. + int nb_regions; + int sync_flags; + int object[AV_DRM_MAX_PLANES]; + void *address[AV_DRM_MAX_PLANES]; + size_t length[AV_DRM_MAX_PLANES]; +} DRMMapping; + +static void drm_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + DRMMapping *map = hwmap->priv; + + for (int i = 0; i < map->nb_regions; i++) { +#if HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags }; + ioctl(map->object[i], DMA_BUF_IOCTL_SYNC, &sync); +#endif + munmap(map->address[i], map->length[i]); + } + + av_free(map); +} + +static int drm_map_frame(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src, int flags) +{ + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0]; +#if HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync_start = { 0 }; +#endif + DRMMapping *map; + int err, i, p, plane; + int mmap_prot; + void *addr; + + map = av_mallocz(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + + mmap_prot = 0; + if (flags & AV_HWFRAME_MAP_READ) + mmap_prot |= PROT_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + mmap_prot |= PROT_WRITE; + +#if HAVE_LINUX_DMA_BUF_H + if (flags & AV_HWFRAME_MAP_READ) + map->sync_flags |= DMA_BUF_SYNC_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + map->sync_flags |= DMA_BUF_SYNC_WRITE; + sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags; +#endif + + av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES); + for (i = 0; i < desc->nb_objects; i++) { + addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED, + desc->objects[i].fd, 0); + if (addr == MAP_FAILED) { + err = AVERROR(errno); + av_log(hwfc, AV_LOG_ERROR, "Failed to map DRM object %d to " + "memory: %d.\n", desc->objects[i].fd, errno); + goto fail; + } + + map->address[i] = addr; + map->length[i] = desc->objects[i].size; + map->object[i] = desc->objects[i].fd; + +#if HAVE_LINUX_DMA_BUF_H + /* We're not checking for errors here because the kernel may not + * support the ioctl, in which case its okay to carry on */ + ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start); +#endif + } + map->nb_regions = i; + + plane = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + for (p = 0; p < layer->nb_planes; p++) { + dst->data[plane] = + (uint8_t*)map->address[layer->planes[p].object_index] + + layer->planes[p].offset; + dst->linesize[plane] = layer->planes[p].pitch; + ++plane; + } + } + av_assert0(plane <= AV_DRM_MAX_PLANES); + + dst->width = src->width; + dst->height = src->height; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &drm_unmap_frame, map); + if (err < 0) + goto fail; + + return 0; + +fail: + for (i = 0; i < desc->nb_objects; i++) { + if (map->address[i]) + munmap(map->address[i], map->length[i]); + } + av_free(map); + return err; +} + +static int drm_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *pix_fmts; + + pix_fmts = av_malloc_array(2, sizeof(*pix_fmts)); + if (!pix_fmts) + return AVERROR(ENOMEM); + + pix_fmts[0] = ctx->sw_format; + pix_fmts[1] = AV_PIX_FMT_NONE; + + *formats = pix_fmts; + return 0; +} + +static int drm_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = drm_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = drm_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (hwfc->sw_format != dst->format) + return AVERROR(ENOSYS); + + err = drm_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +const HWContextType ff_hwcontext_type_drm = { + .type = AV_HWDEVICE_TYPE_DRM, + .name = "DRM", + + .device_hwctx_size = sizeof(AVDRMDeviceContext), + + .device_create = &drm_device_create, + + .frames_get_buffer = &drm_get_buffer, + + .transfer_get_formats = &drm_transfer_get_formats, + .transfer_data_to = &drm_transfer_data_to, + .transfer_data_from = &drm_transfer_data_from, + .map_from = &drm_map_from, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_DRM_PRIME, + AV_PIX_FMT_NONE + }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.h new file mode 100644 index 00000000..42709f21 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_drm.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_DRM_H +#define AVUTIL_HWCONTEXT_DRM_H + +#include +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_DRM. + * + * Internal frame allocation is not currently supported - all frames + * must be allocated by the user. Thus AVHWFramesContext is always + * NULL, though this may change if support for frame allocation is + * added in future. + */ + +enum { + /** + * The maximum number of layers/planes in a DRM frame. + */ + AV_DRM_MAX_PLANES = 4 +}; + +/** + * DRM object descriptor. + * + * Describes a single DRM object, addressing it as a PRIME file + * descriptor. + */ +typedef struct AVDRMObjectDescriptor { + /** + * DRM PRIME fd for the object. + */ + int fd; + /** + * Total size of the object. + * + * (This includes any parts not which do not contain image data.) + */ + size_t size; + /** + * Format modifier applied to the object (DRM_FORMAT_MOD_*). + * + * If the format modifier is unknown then this should be set to + * DRM_FORMAT_MOD_INVALID. + */ + uint64_t format_modifier; +} AVDRMObjectDescriptor; + +/** + * DRM plane descriptor. + * + * Describes a single plane of a layer, which is contained within + * a single object. + */ +typedef struct AVDRMPlaneDescriptor { + /** + * Index of the object containing this plane in the objects + * array of the enclosing frame descriptor. + */ + int object_index; + /** + * Offset within that object of this plane. + */ + ptrdiff_t offset; + /** + * Pitch (linesize) of this plane. + */ + ptrdiff_t pitch; +} AVDRMPlaneDescriptor; + +/** + * DRM layer descriptor. + * + * Describes a single layer within a frame. This has the structure + * defined by its format, and will contain one or more planes. + */ +typedef struct AVDRMLayerDescriptor { + /** + * Format of the layer (DRM_FORMAT_*). + */ + uint32_t format; + /** + * Number of planes in the layer. + * + * This must match the number of planes required by format. + */ + int nb_planes; + /** + * Array of planes in this layer. + */ + AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]; +} AVDRMLayerDescriptor; + +/** + * DRM frame descriptor. + * + * This is used as the data pointer for AV_PIX_FMT_DRM_PRIME frames. + * It is also used by user-allocated frame pools - allocating in + * AVHWFramesContext.pool must return AVBufferRefs which contain + * an object of this type. + * + * The fields of this structure should be set such it can be + * imported directly by EGL using the EGL_EXT_image_dma_buf_import + * and EGL_EXT_image_dma_buf_import_modifiers extensions. + * (Note that the exact layout of a particular format may vary between + * platforms - we only specify that the same platform should be able + * to import it.) + * + * The total number of planes must not exceed AV_DRM_MAX_PLANES, and + * the order of the planes by increasing layer index followed by + * increasing plane index must be the same as the order which would + * be used for the data pointers in the equivalent software format. + */ +typedef struct AVDRMFrameDescriptor { + /** + * Number of DRM objects making up this frame. + */ + int nb_objects; + /** + * Array of objects making up the frame. + */ + AVDRMObjectDescriptor objects[AV_DRM_MAX_PLANES]; + /** + * Number of layers in the frame. + */ + int nb_layers; + /** + * Array of layers in the frame. + */ + AVDRMLayerDescriptor layers[AV_DRM_MAX_PLANES]; +} AVDRMFrameDescriptor; + +/** + * DRM device. + * + * Allocated as AVHWDeviceContext.hwctx. + */ +typedef struct AVDRMDeviceContext { + /** + * File descriptor of DRM device. + * + * This is used as the device to create frames on, and may also be + * used in some derivation and mapping operations. + * + * If no device is required, set to -1. + */ + int fd; +} AVDRMDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_DRM_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.c new file mode 100644 index 00000000..53d00fa8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.c @@ -0,0 +1,595 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define DXVA2API_USE_BITFIELDS +#define COBJMACROS + +#include +#include +#include + +#include "avassert.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_dxva2.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "compat/w32dlfcn.h" + +typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); +typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); +typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); + +#define FF_D3DCREATE_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | \ + D3DCREATE_MULTITHREADED | \ + D3DCREATE_FPU_PRESERVE) + +static const D3DPRESENT_PARAMETERS dxva2_present_params = { + .Windowed = TRUE, + .BackBufferWidth = 640, + .BackBufferHeight = 480, + .BackBufferCount = 0, + .SwapEffect = D3DSWAPEFFECT_DISCARD, + .Flags = D3DPRESENTFLAG_VIDEO, +}; + +typedef struct DXVA2Mapping { + uint32_t palette_dummy[256]; +} DXVA2Mapping; + +typedef struct DXVA2FramesContext { + IDirect3DSurface9 **surfaces_internal; + int nb_surfaces_used; + + HANDLE device_handle; + IDirectXVideoAccelerationService *service; + + D3DFORMAT format; +} DXVA2FramesContext; + +typedef struct DXVA2DevicePriv { + HMODULE d3dlib; + HMODULE dxva2lib; + + HANDLE device_handle; + + IDirect3D9 *d3d9; + IDirect3DDevice9 *d3d9device; +} DXVA2DevicePriv; + +static const struct { + D3DFORMAT d3d_format; + enum AVPixelFormat pix_fmt; +} supported_formats[] = { + { MKTAG('N', 'V', '1', '2'), AV_PIX_FMT_NV12 }, + { MKTAG('P', '0', '1', '0'), AV_PIX_FMT_P010 }, + { D3DFMT_P8, AV_PIX_FMT_PAL8 }, + { D3DFMT_A8R8G8B8, AV_PIX_FMT_BGRA }, +}; + +DEFINE_GUID(video_decoder_service, 0xfc51a551, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02); +DEFINE_GUID(video_processor_service, 0xfc51a552, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02); + +static void dxva2_frames_uninit(AVHWFramesContext *ctx) +{ + AVDXVA2DeviceContext *device_hwctx = ctx->device_ctx->hwctx; + AVDXVA2FramesContext *frames_hwctx = ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int i; + + if (frames_hwctx->decoder_to_release) + IDirectXVideoDecoder_Release(frames_hwctx->decoder_to_release); + + if (s->surfaces_internal) { + for (i = 0; i < frames_hwctx->nb_surfaces; i++) { + if (s->surfaces_internal[i]) + IDirect3DSurface9_Release(s->surfaces_internal[i]); + } + } + av_freep(&s->surfaces_internal); + + if (s->service) { + IDirectXVideoAccelerationService_Release(s->service); + s->service = NULL; + } + + if (s->device_handle != INVALID_HANDLE_VALUE) { + IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, s->device_handle); + s->device_handle = INVALID_HANDLE_VALUE; + } +} + +static void dxva2_pool_release_dummy(void *opaque, uint8_t *data) +{ + // important not to free anything here--data is a surface object + // associated with the call to CreateSurface(), and these surfaces are + // released in dxva2_frames_uninit() +} + +static AVBufferRef *dxva2_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + DXVA2FramesContext *s = ctx->internal->priv; + AVDXVA2FramesContext *hwctx = ctx->hwctx; + + if (s->nb_surfaces_used < hwctx->nb_surfaces) { + s->nb_surfaces_used++; + return av_buffer_create((uint8_t*)s->surfaces_internal[s->nb_surfaces_used - 1], + sizeof(*hwctx->surfaces), dxva2_pool_release_dummy, 0, 0); + } + + return NULL; +} + +static int dxva2_init_pool(AVHWFramesContext *ctx) +{ + AVDXVA2FramesContext *frames_hwctx = ctx->hwctx; + AVDXVA2DeviceContext *device_hwctx = ctx->device_ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int decode = (frames_hwctx->surface_type == DXVA2_VideoDecoderRenderTarget); + + int i; + HRESULT hr; + + if (ctx->initial_pool_size <= 0) + return 0; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr, &s->device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to open device handle\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, + s->device_handle, + decode ? &video_decoder_service : &video_processor_service, + (void **)&s->service); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create the video service\n"); + return AVERROR_UNKNOWN; + } + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i].pix_fmt) { + s->format = supported_formats[i].d3d_format; + break; + } + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(EINVAL); + } + + s->surfaces_internal = av_calloc(ctx->initial_pool_size, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + + hr = IDirectXVideoAccelerationService_CreateSurface(s->service, + ctx->width, ctx->height, + ctx->initial_pool_size - 1, + s->format, D3DPOOL_DEFAULT, 0, + frames_hwctx->surface_type, + s->surfaces_internal, NULL); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the surfaces\n"); + return AVERROR_UNKNOWN; + } + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(*s->surfaces_internal), + ctx, dxva2_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + frames_hwctx->surfaces = s->surfaces_internal; + frames_hwctx->nb_surfaces = ctx->initial_pool_size; + + return 0; +} + +static int dxva2_frames_init(AVHWFramesContext *ctx) +{ + AVDXVA2FramesContext *hwctx = ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int ret; + + if (hwctx->surface_type != DXVA2_VideoDecoderRenderTarget && + hwctx->surface_type != DXVA2_VideoProcessorRenderTarget) { + av_log(ctx, AV_LOG_ERROR, "Unknown surface type: %lu\n", + hwctx->surface_type); + return AVERROR(EINVAL); + } + + s->device_handle = INVALID_HANDLE_VALUE; + + /* init the frame pool if the caller didn't provide one */ + if (!ctx->pool) { + ret = dxva2_init_pool(ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n"); + return ret; + } + } + + return 0; +} + +static int dxva2_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_DXVA2_VLD; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int dxva2_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static void dxva2_unmap_frame(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) +{ + IDirect3DSurface9 *surface = (IDirect3DSurface9*)hwmap->source->data[3]; + IDirect3DSurface9_UnlockRect(surface); + av_freep(&hwmap->priv); +} + +static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, + int flags) +{ + IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3]; + DXVA2Mapping *map; + D3DSURFACE_DESC surfaceDesc; + D3DLOCKED_RECT LockedRect; + HRESULT hr; + int i, err, nb_planes; + int lock_flags = 0; + + nb_planes = av_pix_fmt_count_planes(dst->format); + + hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error getting a surface description\n"); + return AVERROR_UNKNOWN; + } + + if (!(flags & AV_HWFRAME_MAP_WRITE)) + lock_flags |= D3DLOCK_READONLY; + if (flags & AV_HWFRAME_MAP_OVERWRITE) + lock_flags |= D3DLOCK_DISCARD; + + hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, lock_flags); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n"); + return AVERROR_UNKNOWN; + } + + map = av_mallocz(sizeof(*map)); + if (!map) { + err = AVERROR(ENOMEM); + goto fail; + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + dxva2_unmap_frame, map); + if (err < 0) { + av_freep(&map); + goto fail; + } + + for (i = 0; i < nb_planes; i++) + dst->linesize[i] = LockedRect.Pitch; + + av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height, + (uint8_t*)LockedRect.pBits, dst->linesize); + + if (dst->format == AV_PIX_FMT_PAL8) + dst->data[1] = (uint8_t*)map->palette_dummy; + + return 0; +fail: + IDirect3DSurface9_UnlockRect(surface); + return err; +} + +static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVFrame *map; + int ret; + + if (src->format != ctx->sw_format) + return AVERROR(ENOSYS); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (ret < 0) + goto fail; + + av_image_copy(map->data, map->linesize, (const uint8_t **)src->data, src->linesize, + ctx->sw_format, src->width, src->height); + +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVFrame *map; + ptrdiff_t src_linesize[4], dst_linesize[4]; + int ret, i; + + if (dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, src, AV_HWFRAME_MAP_READ); + if (ret < 0) + goto fail; + + for (i = 0; i < 4; i++) { + dst_linesize[i] = dst->linesize[i]; + src_linesize[i] = map->linesize[i]; + } + av_image_copy_uc_from(dst->data, dst_linesize, (const uint8_t **)map->data, src_linesize, + ctx->sw_format, src->width, src->height); +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + int err; + + if (dst->format != AV_PIX_FMT_NONE && dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + dst->format = ctx->sw_format; + + err = dxva2_map_frame(ctx, dst, src, flags); + if (err < 0) + return err; + + err = av_frame_copy_props(dst, src); + if (err < 0) + return err; + + return 0; +} + +static void dxva2_device_free(AVHWDeviceContext *ctx) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv = ctx->user_opaque; + + if (hwctx->devmgr && priv->device_handle != INVALID_HANDLE_VALUE) + IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, priv->device_handle); + + if (hwctx->devmgr) + IDirect3DDeviceManager9_Release(hwctx->devmgr); + + if (priv->d3d9device) + IDirect3DDevice9_Release(priv->d3d9device); + + if (priv->d3d9) + IDirect3D9_Release(priv->d3d9); + + if (priv->d3dlib) + dlclose(priv->d3dlib); + + if (priv->dxva2lib) + dlclose(priv->dxva2lib); + + av_freep(&ctx->user_opaque); +} + +static int dxva2_device_create9(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODE d3ddm; + HRESULT hr; + pDirect3DCreate9 *createD3D = (pDirect3DCreate9 *)dlsym(priv->d3dlib, "Direct3DCreate9"); + if (!createD3D) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); + return AVERROR_UNKNOWN; + } + + priv->d3d9 = createD3D(D3D_SDK_VERSION); + if (!priv->d3d9) { + av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); + return AVERROR_UNKNOWN; + } + + IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); + + d3dpp.BackBufferFormat = d3ddm.Format; + + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, &priv->d3d9device); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODEEX modeex = {0}; + IDirect3D9Ex *d3d9ex = NULL; + IDirect3DDevice9Ex *exdev = NULL; + HRESULT hr; + pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)dlsym(priv->d3dlib, "Direct3DCreate9Ex"); + if (!createD3DEx) + return AVERROR(ENOSYS); + + hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + + modeex.Size = sizeof(D3DDISPLAYMODEEX); + hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + d3dpp.BackBufferFormat = modeex.Format; + + hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, NULL, &exdev); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); + priv->d3d9 = (IDirect3D9 *)d3d9ex; + priv->d3d9device = (IDirect3DDevice9 *)exdev; + return 0; +} + +static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv; + pCreateDeviceManager9 *createDeviceManager = NULL; + unsigned resetToken = 0; + UINT adapter = D3DADAPTER_DEFAULT; + HRESULT hr; + int err; + + if (device) + adapter = atoi(device); + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = dxva2_device_free; + + priv->device_handle = INVALID_HANDLE_VALUE; + + priv->d3dlib = dlopen("d3d9.dll", 0); + if (!priv->d3dlib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load D3D9 library\n"); + return AVERROR_UNKNOWN; + } + priv->dxva2lib = dlopen("dxva2.dll", 0); + if (!priv->dxva2lib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load DXVA2 library\n"); + return AVERROR_UNKNOWN; + } + + createDeviceManager = (pCreateDeviceManager9 *)dlsym(priv->dxva2lib, + "DXVA2CreateDirect3DDeviceManager9"); + if (!createDeviceManager) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n"); + return AVERROR_UNKNOWN; + } + + if (dxva2_device_create9ex(ctx, adapter) < 0) { + // Retry with "classic" d3d9 + err = dxva2_device_create9(ctx, adapter); + if (err < 0) + return err; + } + + hr = createDeviceManager(&resetToken, &hwctx->devmgr); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_ResetDevice(hwctx->devmgr, priv->d3d9device, resetToken); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind Direct3D device to device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &priv->device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to open device handle\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_dxva2 = { + .type = AV_HWDEVICE_TYPE_DXVA2, + .name = "DXVA2", + + .device_hwctx_size = sizeof(AVDXVA2DeviceContext), + .frames_hwctx_size = sizeof(AVDXVA2FramesContext), + .frames_priv_size = sizeof(DXVA2FramesContext), + + .device_create = dxva2_device_create, + .frames_init = dxva2_frames_init, + .frames_uninit = dxva2_frames_uninit, + .frames_get_buffer = dxva2_get_buffer, + .transfer_get_formats = dxva2_transfer_get_formats, + .transfer_data_to = dxva2_transfer_data_to, + .transfer_data_from = dxva2_transfer_data_from, + .map_from = dxva2_map_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.h new file mode 100644 index 00000000..e1b79bc0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_dxva2.h @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_DXVA2_H +#define AVUTIL_HWCONTEXT_DXVA2_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_DXVA2. + * + * Only fixed-size pools are supported. + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a pointer to IDirect3DSurface9. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVDXVA2DeviceContext { + IDirect3DDeviceManager9 *devmgr; +} AVDXVA2DeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVDXVA2FramesContext { + /** + * The surface type (e.g. DXVA2_VideoProcessorRenderTarget or + * DXVA2_VideoDecoderRenderTarget). Must be set by the caller. + */ + DWORD surface_type; + + /** + * The surface pool. When an external pool is not provided by the caller, + * this will be managed (allocated and filled on init, freed on uninit) by + * libavutil. + */ + IDirect3DSurface9 **surfaces; + int nb_surfaces; + + /** + * Certain drivers require the decoder to be destroyed before the surfaces. + * To allow internally managed pools to work properly in such cases, this + * field is provided. + * + * If it is non-NULL, libavutil will call IDirectXVideoDecoder_Release() on + * it just before the internal surface pool is freed. + * + * This is for convenience only. Some code uses other methods to manage the + * decoder reference. + */ + IDirectXVideoDecoder *decoder_to_release; +} AVDXVA2FramesContext; + +#endif /* AVUTIL_HWCONTEXT_DXVA2_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_internal.h new file mode 100644 index 00000000..e6266494 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_internal.h @@ -0,0 +1,178 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_INTERNAL_H +#define AVUTIL_HWCONTEXT_INTERNAL_H + +#include + +#include "buffer.h" +#include "hwcontext.h" +#include "frame.h" +#include "pixfmt.h" + +typedef struct HWContextType { + enum AVHWDeviceType type; + const char *name; + + /** + * An array of pixel formats supported by the AVHWFramesContext instances + * Terminated by AV_PIX_FMT_NONE. + */ + const enum AVPixelFormat *pix_fmts; + + /** + * size of the public hardware-specific context, + * i.e. AVHWDeviceContext.hwctx + */ + size_t device_hwctx_size; + /** + * size of the private data, i.e. + * AVHWDeviceInternal.priv + */ + size_t device_priv_size; + + /** + * Size of the hardware-specific device configuration. + * (Used to query hwframe constraints.) + */ + size_t device_hwconfig_size; + + /** + * size of the public frame pool hardware-specific context, + * i.e. AVHWFramesContext.hwctx + */ + size_t frames_hwctx_size; + /** + * size of the private data, i.e. + * AVHWFramesInternal.priv + */ + size_t frames_priv_size; + + int (*device_create)(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags); + int (*device_derive)(AVHWDeviceContext *dst_ctx, + AVHWDeviceContext *src_ctx, + AVDictionary *opts, int flags); + + int (*device_init)(AVHWDeviceContext *ctx); + void (*device_uninit)(AVHWDeviceContext *ctx); + + int (*frames_get_constraints)(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints); + + int (*frames_init)(AVHWFramesContext *ctx); + void (*frames_uninit)(AVHWFramesContext *ctx); + + int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame); + int (*transfer_get_formats)(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats); + int (*transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + int (*transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + + int (*map_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + int (*map_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + + int (*frames_derive_to)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); + int (*frames_derive_from)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); +} HWContextType; + +struct AVHWDeviceInternal { + const HWContextType *hw_type; + void *priv; + + /** + * For a derived device, a reference to the original device + * context it was derived from. + */ + AVBufferRef *source_device; +}; + +struct AVHWFramesInternal { + const HWContextType *hw_type; + void *priv; + + AVBufferPool *pool_internal; + + /** + * For a derived context, a reference to the original frames + * context it was derived from. + */ + AVBufferRef *source_frames; + /** + * Flags to apply to the mapping from the source to the derived + * frame context when trying to allocate in the derived context. + */ + int source_allocation_map_flags; +}; + +typedef struct HWMapDescriptor { + /** + * A reference to the original source of the mapping. + */ + AVFrame *source; + /** + * A reference to the hardware frames context in which this + * mapping was made. May be the same as source->hw_frames_ctx, + * but need not be. + */ + AVBufferRef *hw_frames_ctx; + /** + * Unmap function. + */ + void (*unmap)(AVHWFramesContext *ctx, + struct HWMapDescriptor *hwmap); + /** + * Hardware-specific private data associated with the mapping. + */ + void *priv; +} HWMapDescriptor; + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv); + +/** + * Replace the current hwmap of dst with the one from src, used for indirect + * mappings like VAAPI->(DRM)->OpenCL/Vulkan where a direct interop is missing + */ +int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src); + +extern const HWContextType ff_hwcontext_type_cuda; +extern const HWContextType ff_hwcontext_type_d3d11va; +extern const HWContextType ff_hwcontext_type_drm; +extern const HWContextType ff_hwcontext_type_dxva2; +extern const HWContextType ff_hwcontext_type_opencl; +extern const HWContextType ff_hwcontext_type_qsv; +extern const HWContextType ff_hwcontext_type_vaapi; +extern const HWContextType ff_hwcontext_type_vdpau; +extern const HWContextType ff_hwcontext_type_videotoolbox; +extern const HWContextType ff_hwcontext_type_mediacodec; +extern const HWContextType ff_hwcontext_type_vulkan; + +#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.c new file mode 100644 index 00000000..9ed6a871 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.c @@ -0,0 +1,121 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_mediacodec.h" + +typedef struct MediaCodecDeviceContext { + AVMediaCodecDeviceContext ctx; + + void *libmedia; + media_status_t (*create_surface)(ANativeWindow **surface); +} MediaCodecDeviceContext; + + +static int mc_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + const AVDictionaryEntry *entry = NULL; + MediaCodecDeviceContext *s = ctx->hwctx; + AVMediaCodecDeviceContext *dev = &s->ctx; + + if (device && device[0]) { + av_log(ctx, AV_LOG_ERROR, "Device selection unsupported.\n"); + return AVERROR_UNKNOWN; + } + + while ((entry = av_dict_iterate(opts, entry))) { + if (!strcmp(entry->key, "create_window")) + dev->create_window = atoi(entry->value); + } + + av_log(ctx, AV_LOG_DEBUG, "%s createPersistentInputSurface\n", + dev->create_window ? "Enable" : "Disable"); + + return 0; +} + +static int mc_device_init(AVHWDeviceContext *ctx) +{ + MediaCodecDeviceContext *s = ctx->hwctx; + AVMediaCodecDeviceContext *dev = (AVMediaCodecDeviceContext *)s; + ANativeWindow *native_window = NULL; + + if (dev->surface) + return 0; + + if (dev->native_window) + return 0; + + // For backward compatibility, don't return error for a dummy + // AVHWDeviceContext without surface or native_window. + if (!dev->create_window) + return 0; + + s->libmedia = dlopen("libmediandk.so", RTLD_NOW); + if (!s->libmedia) + return AVERROR_UNKNOWN; + + s->create_surface = dlsym(s->libmedia, "AMediaCodec_createPersistentInputSurface"); + if (!s->create_surface) + return AVERROR_UNKNOWN; + + s->create_surface(&native_window); + dev->native_window = native_window; + return 0; +} + +static void mc_device_uninit(AVHWDeviceContext *ctx) +{ + MediaCodecDeviceContext *s = ctx->hwctx; + AVMediaCodecDeviceContext *dev = ctx->hwctx; + if (!s->libmedia) + return; + + if (dev->native_window) { + ANativeWindow_release(dev->native_window); + dev->native_window = NULL; + } + dlclose(s->libmedia); + s->libmedia = NULL; +} + +const HWContextType ff_hwcontext_type_mediacodec = { + .type = AV_HWDEVICE_TYPE_MEDIACODEC, + .name = "mediacodec", + + .device_hwctx_size = sizeof(MediaCodecDeviceContext), + + .device_create = mc_device_create, + .device_init = mc_device_init, + .device_uninit = mc_device_uninit, + + .pix_fmts = (const enum AVPixelFormat[]){ + AV_PIX_FMT_MEDIACODEC, + AV_PIX_FMT_NONE + }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.h new file mode 100644 index 00000000..fc0263ca --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_mediacodec.h @@ -0,0 +1,61 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_MEDIACODEC_H +#define AVUTIL_HWCONTEXT_MEDIACODEC_H + +/** + * MediaCodec details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVMediaCodecDeviceContext { + /** + * android/view/Surface handle, to be filled by the user. + * + * This is the default surface used by decoders on this device. + */ + void *surface; + + /** + * Pointer to ANativeWindow. + * + * It both surface and native_window is NULL, try to create it + * automatically if create_window is true and OS support + * createPersistentInputSurface. + * + * It can be used as output surface for decoder and input surface for + * encoder. + */ + void *native_window; + + /** + * Enable createPersistentInputSurface automatically. + * + * Disabled by default. + * + * It can be enabled by setting this flag directly, or by setting + * AVDictionary of av_hwdevice_ctx_create(), with "create_window" as key. + * The second method is useful for ffmpeg cmdline, e.g., we can enable it + * via: + * -init_hw_device mediacodec=mediacodec,create_window=1 + */ + int create_window; +} AVMediaCodecDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.c new file mode 100644 index 00000000..247834aa --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.c @@ -0,0 +1,2962 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS + +#include + +#include "config.h" + +#include "avassert.h" +#include "avstring.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_opencl.h" +#include "mem.h" +#include "pixdesc.h" + +#if HAVE_OPENCL_VAAPI_BEIGNET +#include +#include +#include +#include +#include "hwcontext_vaapi.h" +#endif + +#if HAVE_OPENCL_DRM_BEIGNET +#include +#include +#include "hwcontext_drm.h" +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA +#if CONFIG_LIBMFX +#include +#endif +#include +#include +#include "hwcontext_vaapi.h" +#endif + +#if HAVE_OPENCL_DXVA2 +#define COBJMACROS +#include +#include +#include "hwcontext_dxva2.h" +#endif + +#if HAVE_OPENCL_D3D11 +#include +#include "hwcontext_d3d11va.h" +#endif + +#if HAVE_OPENCL_DRM_ARM +#include +#include +#include "hwcontext_drm.h" +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA && CONFIG_LIBMFX +extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, + enum AVHWDeviceType base_dev_typ, + void **base_handle); +#endif + + +typedef struct OpenCLDeviceContext { + // Default command queue to use for transfer/mapping operations on + // the device. If the user supplies one, this is a reference to it. + // Otherwise, it is newly-created. + cl_command_queue command_queue; + + // The platform the context exists on. This is needed to query and + // retrieve extension functions. + cl_platform_id platform_id; + + // Platform/device-specific functions. +#if HAVE_OPENCL_DRM_BEIGNET + int beignet_drm_mapping_usable; + clCreateImageFromFdINTEL_fn clCreateImageFromFdINTEL; +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + int qsv_mapping_usable; + clCreateFromVA_APIMediaSurfaceINTEL_fn + clCreateFromVA_APIMediaSurfaceINTEL; + clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn + clEnqueueAcquireVA_APIMediaSurfacesINTEL; + clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn + clEnqueueReleaseVA_APIMediaSurfacesINTEL; +#endif + +#if HAVE_OPENCL_DXVA2 + int dxva2_mapping_usable; + cl_dx9_media_adapter_type_khr dx9_media_adapter_type; + + clCreateFromDX9MediaSurfaceKHR_fn + clCreateFromDX9MediaSurfaceKHR; + clEnqueueAcquireDX9MediaSurfacesKHR_fn + clEnqueueAcquireDX9MediaSurfacesKHR; + clEnqueueReleaseDX9MediaSurfacesKHR_fn + clEnqueueReleaseDX9MediaSurfacesKHR; +#endif + +#if HAVE_OPENCL_D3D11 + int d3d11_mapping_usable; + clCreateFromD3D11Texture2DKHR_fn + clCreateFromD3D11Texture2DKHR; + clEnqueueAcquireD3D11ObjectsKHR_fn + clEnqueueAcquireD3D11ObjectsKHR; + clEnqueueReleaseD3D11ObjectsKHR_fn + clEnqueueReleaseD3D11ObjectsKHR; +#endif + +#if HAVE_OPENCL_DRM_ARM + int drm_arm_mapping_usable; +#endif +} OpenCLDeviceContext; + +typedef struct OpenCLFramesContext { + // Command queue used for transfer/mapping operations on this frames + // context. If the user supplies one, this is a reference to it. + // Otherwise, it is a reference to the default command queue for the + // device. + cl_command_queue command_queue; + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 + // For mapping APIs which have separate creation and acquire/release + // steps, this stores the OpenCL memory objects corresponding to each + // frame. + int nb_mapped_frames; + AVOpenCLFrameDescriptor *mapped_frames; +#endif +} OpenCLFramesContext; + + +static void CL_CALLBACK opencl_error_callback(const char *errinfo, + const void *private_info, + size_t cb, + void *user_data) +{ + AVHWDeviceContext *ctx = user_data; + av_log(ctx, AV_LOG_ERROR, "OpenCL error: %s\n", errinfo); +} + +static void opencl_device_free(AVHWDeviceContext *hwdev) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_int cle; + + cle = clReleaseContext(hwctx->context); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to release OpenCL " + "context: %d.\n", cle); + } +} + +static struct { + const char *key; + cl_platform_info name; +} opencl_platform_params[] = { + { "platform_profile", CL_PLATFORM_PROFILE }, + { "platform_version", CL_PLATFORM_VERSION }, + { "platform_name", CL_PLATFORM_NAME }, + { "platform_vendor", CL_PLATFORM_VENDOR }, + { "platform_extensions", CL_PLATFORM_EXTENSIONS }, +}; + +static struct { + const char *key; + cl_device_info name; +} opencl_device_params[] = { + { "device_name", CL_DEVICE_NAME }, + { "device_vendor", CL_DEVICE_VENDOR }, + { "driver_version", CL_DRIVER_VERSION }, + { "device_version", CL_DEVICE_VERSION }, + { "device_profile", CL_DEVICE_PROFILE }, + { "device_extensions", CL_DEVICE_EXTENSIONS }, +}; + +static struct { + const char *key; + cl_device_type type; +} opencl_device_types[] = { + { "cpu", CL_DEVICE_TYPE_CPU }, + { "gpu", CL_DEVICE_TYPE_GPU }, + { "accelerator", CL_DEVICE_TYPE_ACCELERATOR }, + { "custom", CL_DEVICE_TYPE_CUSTOM }, + { "default", CL_DEVICE_TYPE_DEFAULT }, + { "all", CL_DEVICE_TYPE_ALL }, +}; + +static char *opencl_get_platform_string(cl_platform_id platform_id, + cl_platform_info key) +{ + char *str; + size_t size; + cl_int cle; + cle = clGetPlatformInfo(platform_id, key, 0, NULL, &size); + if (cle != CL_SUCCESS) + return NULL; + str = av_malloc(size); + if (!str) + return NULL; + cle = clGetPlatformInfo(platform_id, key, size, str, &size); + if (cle != CL_SUCCESS) { + av_free(str); + return NULL; + } + av_assert0(strlen(str) + 1 == size); + return str; +} + +static char *opencl_get_device_string(cl_device_id device_id, + cl_device_info key) +{ + char *str; + size_t size; + cl_int cle; + cle = clGetDeviceInfo(device_id, key, 0, NULL, &size); + if (cle != CL_SUCCESS) + return NULL; + str = av_malloc(size); + if (!str) + return NULL; + cle = clGetDeviceInfo(device_id, key, size, str, &size); + if (cle != CL_SUCCESS) { + av_free(str); + return NULL; + } + av_assert0(strlen(str) + 1== size); + return str; +} + +static int opencl_check_platform_extension(cl_platform_id platform_id, + const char *name) +{ + char *str; + int found = 0; + str = opencl_get_platform_string(platform_id, + CL_PLATFORM_EXTENSIONS); + if (str && strstr(str, name)) + found = 1; + av_free(str); + return found; +} + +static int opencl_check_device_extension(cl_device_id device_id, + const char *name) +{ + char *str; + int found = 0; + str = opencl_get_device_string(device_id, + CL_DEVICE_EXTENSIONS); + if (str && strstr(str, name)) + found = 1; + av_free(str); + return found; +} + +static av_unused int opencl_check_extension(AVHWDeviceContext *hwdev, + const char *name) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + OpenCLDeviceContext *priv = hwdev->internal->priv; + + if (opencl_check_platform_extension(priv->platform_id, name)) { + av_log(hwdev, AV_LOG_DEBUG, + "%s found as platform extension.\n", name); + return 1; + } + + if (opencl_check_device_extension(hwctx->device_id, name)) { + av_log(hwdev, AV_LOG_DEBUG, + "%s found as device extension.\n", name); + return 1; + } + + return 0; +} + +static int opencl_enumerate_platforms(AVHWDeviceContext *hwdev, + cl_uint *nb_platforms, + cl_platform_id **platforms, + void *context) +{ + cl_int cle; + + cle = clGetPlatformIDs(0, NULL, nb_platforms); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of " + "OpenCL platforms: %d.\n", cle); + return AVERROR(ENODEV); + } + av_log(hwdev, AV_LOG_DEBUG, "%u OpenCL platforms found.\n", + *nb_platforms); + + *platforms = av_malloc_array(*nb_platforms, sizeof(**platforms)); + if (!*platforms) + return AVERROR(ENOMEM); + + cle = clGetPlatformIDs(*nb_platforms, *platforms, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of OpenCL " + "platforms: %d.\n", cle); + av_freep(platforms); + return AVERROR(ENODEV); + } + + return 0; +} + +static int opencl_filter_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + AVDictionary *opts = context; + const AVDictionaryEntry *param; + char *str; + int i, ret = 0; + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_platform_params); i++) { + param = av_dict_get(opts, opencl_platform_params[i].key, + NULL, 0); + if (!param) + continue; + + str = opencl_get_platform_string(platform_id, + opencl_platform_params[i].name); + if (!str) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query %s " + "of platform \"%s\".\n", + opencl_platform_params[i].key, platform_name); + return AVERROR_UNKNOWN; + } + if (!av_stristr(str, param->value)) { + av_log(hwdev, AV_LOG_DEBUG, "%s does not match (\"%s\").\n", + param->key, str); + ret = 1; + } + av_free(str); + } + + return ret; +} + +static int opencl_enumerate_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + cl_int cle; + + cle = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR(ENODEV); + } + av_log(hwdev, AV_LOG_DEBUG, "%u OpenCL devices found on " + "platform \"%s\".\n", *nb_devices, platform_name); + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR(ENODEV); + } + + return 0; +} + +static int opencl_filter_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + AVDictionary *opts = context; + const AVDictionaryEntry *param; + char *str; + int i, ret = 0; + + param = av_dict_get(opts, "device_type", NULL, 0); + if (param) { + cl_device_type match_type = 0, device_type; + cl_int cle; + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_device_types); i++) { + if (!strcmp(opencl_device_types[i].key, param->value)) { + match_type = opencl_device_types[i].type; + break; + } + } + if (!match_type) { + av_log(hwdev, AV_LOG_ERROR, "Unknown device type %s.\n", + param->value); + return AVERROR(EINVAL); + } + + cle = clGetDeviceInfo(device_id, CL_DEVICE_TYPE, + sizeof(device_type), &device_type, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query device type " + "of device \"%s\".\n", device_name); + return AVERROR_UNKNOWN; + } + + if (!(device_type & match_type)) { + av_log(hwdev, AV_LOG_DEBUG, "device_type does not match.\n"); + return 1; + } + } + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_device_params); i++) { + param = av_dict_get(opts, opencl_device_params[i].key, + NULL, 0); + if (!param) + continue; + + str = opencl_get_device_string(device_id, + opencl_device_params[i].name); + if (!str) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query %s " + "of device \"%s\".\n", + opencl_device_params[i].key, device_name); + return AVERROR_UNKNOWN; + } + if (!av_stristr(str, param->value)) { + av_log(hwdev, AV_LOG_DEBUG, "%s does not match (\"%s\").\n", + param->key, str); + ret = 1; + } + av_free(str); + } + + return ret; +} + +typedef struct OpenCLDeviceSelector { + int platform_index; + int device_index; + void *context; + int (*enumerate_platforms)(AVHWDeviceContext *hwdev, + cl_uint *nb_platforms, + cl_platform_id **platforms, + void *context); + int (*filter_platform) (AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context); + int (*enumerate_devices) (AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context); + int (*filter_device) (AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context); +} OpenCLDeviceSelector; + +static int opencl_device_create_internal(AVHWDeviceContext *hwdev, + const OpenCLDeviceSelector *selector, + cl_context_properties *props) +{ + cl_uint nb_platforms; + cl_platform_id *platforms = NULL; + cl_platform_id platform_id; + cl_uint nb_devices; + cl_device_id *devices = NULL; + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_int cle; + cl_context_properties default_props[3]; + char *platform_name_src = NULL, + *device_name_src = NULL; + int err, found, p, d; + + av_assert0(selector->enumerate_platforms && + selector->enumerate_devices); + + err = selector->enumerate_platforms(hwdev, &nb_platforms, &platforms, + selector->context); + if (err) + return err; + + found = 0; + for (p = 0; p < nb_platforms; p++) { + const char *platform_name; + + if (selector->platform_index >= 0 && + selector->platform_index != p) + continue; + + av_freep(&platform_name_src); + platform_name_src = opencl_get_platform_string(platforms[p], + CL_PLATFORM_NAME); + if (platform_name_src) + platform_name = platform_name_src; + else + platform_name = "Unknown Platform"; + + if (selector->filter_platform) { + err = selector->filter_platform(hwdev, platforms[p], + platform_name, + selector->context); + if (err < 0) + goto fail; + if (err > 0) + continue; + } + + err = selector->enumerate_devices(hwdev, platforms[p], platform_name, + &nb_devices, &devices, + selector->context); + if (err < 0) + continue; + + for (d = 0; d < nb_devices; d++) { + const char *device_name; + + if (selector->device_index >= 0 && + selector->device_index != d) + continue; + + av_freep(&device_name_src); + device_name_src = opencl_get_device_string(devices[d], + CL_DEVICE_NAME); + if (device_name_src) + device_name = device_name_src; + else + device_name = "Unknown Device"; + + if (selector->filter_device) { + err = selector->filter_device(hwdev, devices[d], + device_name, + selector->context); + if (err < 0) + goto fail; + if (err > 0) + continue; + } + + av_log(hwdev, AV_LOG_VERBOSE, "%d.%d: %s / %s\n", p, d, + platform_name, device_name); + + ++found; + platform_id = platforms[p]; + hwctx->device_id = devices[d]; + } + + av_freep(&devices); + } + + if (found == 0) { + av_log(hwdev, AV_LOG_ERROR, "No matching devices found.\n"); + err = AVERROR(ENODEV); + goto fail; + } + if (found > 1) { + av_log(hwdev, AV_LOG_ERROR, "More than one matching device found.\n"); + err = AVERROR(ENODEV); + goto fail; + } + + if (!props) { + props = default_props; + default_props[0] = CL_CONTEXT_PLATFORM; + default_props[1] = (intptr_t)platform_id; + default_props[2] = 0; + } else { + if (props[0] == CL_CONTEXT_PLATFORM && props[1] == 0) + props[1] = (intptr_t)platform_id; + } + + hwctx->context = clCreateContext(props, 1, &hwctx->device_id, + &opencl_error_callback, hwdev, &cle); + if (!hwctx->context) { + av_log(hwdev, AV_LOG_ERROR, "Failed to create OpenCL context: " + "%d.\n", cle); + err = AVERROR(ENODEV); + goto fail; + } + + hwdev->free = &opencl_device_free; + + err = 0; +fail: + av_freep(&platform_name_src); + av_freep(&device_name_src); + av_freep(&platforms); + av_freep(&devices); + return err; +} + +static int opencl_device_create(AVHWDeviceContext *hwdev, const char *device, + AVDictionary *opts, int flags) +{ + OpenCLDeviceSelector selector = { + .context = opts, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = &opencl_filter_device, + }; + + if (device && device[0]) { + // Match one or both indices for platform and device. + int d = -1, p = -1, ret; + if (device[0] == '.') + ret = sscanf(device, ".%d", &d); + else + ret = sscanf(device, "%d.%d", &p, &d); + if (ret < 1) { + av_log(hwdev, AV_LOG_ERROR, "Invalid OpenCL platform/device " + "index specification \"%s\".\n", device); + return AVERROR(EINVAL); + } + selector.platform_index = p; + selector.device_index = d; + } else { + selector.platform_index = -1; + selector.device_index = -1; + } + + return opencl_device_create_internal(hwdev, &selector, NULL); +} + +static int opencl_device_init(AVHWDeviceContext *hwdev) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + OpenCLDeviceContext *priv = hwdev->internal->priv; + cl_int cle; + + if (hwctx->command_queue) { + cle = clRetainCommandQueue(hwctx->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to retain external " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + priv->command_queue = hwctx->command_queue; + } else { + priv->command_queue = clCreateCommandQueue(hwctx->context, + hwctx->device_id, + 0, &cle); + if (!priv->command_queue) { + av_log(hwdev, AV_LOG_ERROR, "Failed to create internal " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + } + + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_PLATFORM, + sizeof(priv->platform_id), &priv->platform_id, + NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to determine the OpenCL " + "platform containing the device.\n"); + return AVERROR(EIO); + } + +#define CL_FUNC(name, desc) do { \ + if (fail) \ + break; \ + priv->name = clGetExtensionFunctionAddressForPlatform( \ + priv->platform_id, #name); \ + if (!priv->name) { \ + av_log(hwdev, AV_LOG_VERBOSE, \ + desc " function not found (%s).\n", #name); \ + fail = 1; \ + } else { \ + av_log(hwdev, AV_LOG_VERBOSE, \ + desc " function found (%s).\n", #name); \ + } \ + } while (0) + +#if HAVE_OPENCL_DRM_BEIGNET + { + int fail = 0; + + CL_FUNC(clCreateImageFromFdINTEL, + "Beignet DRM to OpenCL image mapping"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "Beignet DRM to OpenCL " + "mapping not usable.\n"); + priv->beignet_drm_mapping_usable = 0; + } else { + priv->beignet_drm_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + { + size_t props_size; + cl_context_properties *props = NULL; + VADisplay va_display; + const char *va_ext = "cl_intel_va_api_media_sharing"; + int i, fail = 0; + + if (!opencl_check_extension(hwdev, va_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for QSV to OpenCL mapping.\n", va_ext); + goto no_qsv; + } + + cle = clGetContextInfo(hwctx->context, CL_CONTEXT_PROPERTIES, + 0, NULL, &props_size); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_VERBOSE, "Failed to get context " + "properties: %d.\n", cle); + goto no_qsv; + } + if (props_size == 0) { + av_log(hwdev, AV_LOG_VERBOSE, "Media sharing must be " + "enabled on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + + props = av_malloc(props_size); + if (!props) + return AVERROR(ENOMEM); + + cle = clGetContextInfo(hwctx->context, CL_CONTEXT_PROPERTIES, + props_size, props, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_VERBOSE, "Failed to get context " + "properties: %d.\n", cle); + goto no_qsv; + } + + va_display = NULL; + for (i = 0; i < (props_size / sizeof(*props) - 1); i++) { + if (props[i] == CL_CONTEXT_VA_API_DISPLAY_INTEL) { + va_display = (VADisplay)(intptr_t)props[i+1]; + break; + } + } + if (!va_display) { + av_log(hwdev, AV_LOG_VERBOSE, "Media sharing must be " + "enabled on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + if (!vaDisplayIsValid(va_display)) { + av_log(hwdev, AV_LOG_VERBOSE, "A valid VADisplay is " + "required on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + + CL_FUNC(clCreateFromVA_APIMediaSurfaceINTEL, + "Intel QSV to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireVA_APIMediaSurfacesINTEL, + "Intel QSV in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseVA_APIMediaSurfacesINTEL, + "Intel QSV in OpenCL release"); + + if (fail) { + no_qsv: + av_log(hwdev, AV_LOG_WARNING, "QSV to OpenCL mapping " + "not usable.\n"); + priv->qsv_mapping_usable = 0; + } else { + priv->qsv_mapping_usable = 1; + } + av_free(props); + } +#endif + +#if HAVE_OPENCL_DXVA2 + { + int fail = 0; + + CL_FUNC(clCreateFromDX9MediaSurfaceKHR, + "DXVA2 to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireDX9MediaSurfacesKHR, + "DXVA2 in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseDX9MediaSurfacesKHR, + "DXVA2 in OpenCL release"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "DXVA2 to OpenCL mapping " + "not usable.\n"); + priv->dxva2_mapping_usable = 0; + } else { + priv->dx9_media_adapter_type = CL_ADAPTER_D3D9EX_KHR; + priv->dxva2_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_D3D11 + { + const char *d3d11_ext = "cl_khr_d3d11_sharing"; + const char *nv12_ext = "cl_intel_d3d11_nv12_media_sharing"; + int fail = 0; + + if (!opencl_check_extension(hwdev, d3d11_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for D3D11 to OpenCL mapping.\n", d3d11_ext); + fail = 1; + } else if (!opencl_check_extension(hwdev, nv12_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension may be " + "required for D3D11 to OpenCL mapping.\n", nv12_ext); + // Not fatal. + } + + CL_FUNC(clCreateFromD3D11Texture2DKHR, + "D3D11 to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireD3D11ObjectsKHR, + "D3D11 in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseD3D11ObjectsKHR, + "D3D11 in OpenCL release"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "D3D11 to OpenCL mapping " + "not usable.\n"); + priv->d3d11_mapping_usable = 0; + } else { + priv->d3d11_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_DRM_ARM + { + const char *drm_arm_ext = "cl_arm_import_memory"; + const char *image_ext = "cl_khr_image2d_from_buffer"; + int fail = 0; + + if (!opencl_check_extension(hwdev, drm_arm_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for DRM to OpenCL mapping on ARM.\n", + drm_arm_ext); + fail = 1; + } + if (!opencl_check_extension(hwdev, image_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for DRM to OpenCL mapping on ARM.\n", + image_ext); + fail = 1; + } + + // clImportMemoryARM() is linked statically. + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "DRM to OpenCL mapping on ARM " + "not usable.\n"); + priv->drm_arm_mapping_usable = 0; + } else { + priv->drm_arm_mapping_usable = 1; + } + } +#endif + +#undef CL_FUNC + + return 0; +} + +static void opencl_device_uninit(AVHWDeviceContext *hwdev) +{ + OpenCLDeviceContext *priv = hwdev->internal->priv; + cl_int cle; + + if (priv->command_queue) { + cle = clReleaseCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to release internal " + "command queue reference: %d.\n", cle); + } + priv->command_queue = NULL; + } +} + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA +static int opencl_filter_intel_media_vaapi_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + // This doesn't exist as a platform extension, so just test whether + // the function we will use for device enumeration exists. + + if (!clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL")) { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not export the " + "VAAPI device enumeration function.\n", platform_name); + return 1; + } else { + return 0; + } +} + +static int opencl_enumerate_intel_media_vaapi_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + VADisplay va_display = context; + clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn + clGetDeviceIDsFromVA_APIMediaAdapterINTEL; + cl_int cle; + + clGetDeviceIDsFromVA_APIMediaAdapterINTEL = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL"); + if (!clGetDeviceIDsFromVA_APIMediaAdapterINTEL) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromVA_APIMediaAdapterINTEL( + platform_id, CL_VA_API_DISPLAY_INTEL, va_display, + CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No VAAPI-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromVA_APIMediaAdapterINTEL( + platform_id, CL_VA_API_DISPLAY_INTEL, va_display, + CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of VAAPI-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int opencl_filter_intel_media_vaapi_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + const char *va_ext = "cl_intel_va_api_media_sharing"; + + if (opencl_check_device_extension(device_id, va_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Device %s does not support the " + "%s extension.\n", device_name, va_ext); + return 1; + } +} +#endif + +#if HAVE_OPENCL_DXVA2 +static int opencl_filter_dxva2_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *dx9_ext = "cl_khr_dx9_media_sharing"; + + if (opencl_check_platform_extension(platform_id, dx9_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, dx9_ext); + return 1; + } +} + +static int opencl_enumerate_dxva2_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + IDirect3DDevice9 *device = context; + clGetDeviceIDsFromDX9MediaAdapterKHR_fn + clGetDeviceIDsFromDX9MediaAdapterKHR; + cl_dx9_media_adapter_type_khr media_adapter_type = CL_ADAPTER_D3D9EX_KHR; + cl_int cle; + + clGetDeviceIDsFromDX9MediaAdapterKHR = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromDX9MediaAdapterKHR"); + if (!clGetDeviceIDsFromDX9MediaAdapterKHR) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromDX9MediaAdapterKHR().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromDX9MediaAdapterKHR( + platform_id, 1, &media_adapter_type, (void**)&device, + CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No DXVA2-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromDX9MediaAdapterKHR( + platform_id, 1, &media_adapter_type, (void**)&device, + CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of DXVA2-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_D3D11 +static int opencl_filter_d3d11_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *d3d11_ext = "cl_khr_d3d11_sharing"; + + if (opencl_check_platform_extension(platform_id, d3d11_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, d3d11_ext); + return 1; + } +} + +static int opencl_enumerate_d3d11_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + ID3D11Device *device = context; + clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR; + cl_int cle; + + clGetDeviceIDsFromD3D11KHR = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromD3D11KHR"); + if (!clGetDeviceIDsFromD3D11KHR) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromD3D11KHR().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromD3D11KHR(platform_id, + CL_D3D11_DEVICE_KHR, device, + CL_PREFERRED_DEVICES_FOR_D3D11_KHR, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No D3D11-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromD3D11KHR(platform_id, + CL_D3D11_DEVICE_KHR, device, + CL_PREFERRED_DEVICES_FOR_D3D11_KHR, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of D3D11-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 +static int opencl_filter_gpu_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + cl_device_type device_type; + cl_int cle; + + cle = clGetDeviceInfo(device_id, CL_DEVICE_TYPE, + sizeof(device_type), &device_type, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query device type " + "of device \"%s\".\n", device_name); + return AVERROR_UNKNOWN; + } + if (!(device_type & CL_DEVICE_TYPE_GPU)) { + av_log(hwdev, AV_LOG_DEBUG, "Device %s skipped (not GPU).\n", + device_name); + return 1; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_DRM_ARM +static int opencl_filter_drm_arm_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *drm_arm_ext = "cl_arm_import_memory"; + + if (opencl_check_platform_extension(platform_id, drm_arm_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, drm_arm_ext); + return 1; + } +} + +static int opencl_filter_drm_arm_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + const char *drm_arm_ext = "cl_arm_import_memory"; + + if (opencl_check_device_extension(device_id, drm_arm_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Device %s does not support the " + "%s extension.\n", device_name, drm_arm_ext); + return 1; + } +} +#endif + +static int opencl_device_derive(AVHWDeviceContext *hwdev, + AVHWDeviceContext *src_ctx, AVDictionary *opts, + int flags) +{ + int err; + switch (src_ctx->type) { + +#if HAVE_OPENCL_DRM_BEIGNET + case AV_HWDEVICE_TYPE_DRM: + case AV_HWDEVICE_TYPE_VAAPI: + { + // Surface mapping works via DRM PRIME fds with no special + // initialisation required in advance. This just finds the + // Beignet ICD by name. + AVDictionary *selector_opts = NULL; + + err = av_dict_set(&selector_opts, "platform_vendor", "Intel", 0); + if (err >= 0) + err = av_dict_set(&selector_opts, "platform_version", "beignet", 0); + if (err >= 0) { + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = 0, + .context = selector_opts, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = NULL, + }; + err = opencl_device_create_internal(hwdev, &selector, NULL); + } + av_dict_free(&selector_opts); + } + break; +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + // The generic code automatically attempts to derive from all + // ancestors of the given device, so we can ignore QSV devices here + // and just consider the inner VAAPI device it was derived from. + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIDeviceContext *src_hwctx = src_ctx->hwctx; + cl_context_properties props[7] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_VA_API_DISPLAY_INTEL, + (intptr_t)src_hwctx->display, + CL_CONTEXT_INTEROP_USER_SYNC, + CL_FALSE, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = src_hwctx->display, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_intel_media_vaapi_platform, + .enumerate_devices = &opencl_enumerate_intel_media_vaapi_devices, + .filter_device = &opencl_filter_intel_media_vaapi_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + } + break; +#endif + +#if HAVE_OPENCL_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2DeviceContext *src_hwctx = src_ctx->hwctx; + IDirect3DDevice9 *device; + HANDLE device_handle; + HRESULT hr; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(src_hwctx->devmgr, + &device_handle); + if (FAILED(hr)) { + av_log(hwdev, AV_LOG_ERROR, "Failed to open device handle " + "for Direct3D9 device: %lx.\n", (unsigned long)hr); + err = AVERROR_UNKNOWN; + break; + } + + hr = IDirect3DDeviceManager9_LockDevice(src_hwctx->devmgr, + device_handle, + &device, FALSE); + if (SUCCEEDED(hr)) { + cl_context_properties props[5] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_ADAPTER_D3D9EX_KHR, + (intptr_t)device, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = device, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_dxva2_platform, + .enumerate_devices = &opencl_enumerate_dxva2_devices, + .filter_device = &opencl_filter_gpu_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + + IDirect3DDeviceManager9_UnlockDevice(src_hwctx->devmgr, + device_handle, FALSE); + } else { + av_log(hwdev, AV_LOG_ERROR, "Failed to lock device handle " + "for Direct3D9 device: %lx.\n", (unsigned long)hr); + err = AVERROR_UNKNOWN; + } + + IDirect3DDeviceManager9_CloseDeviceHandle(src_hwctx->devmgr, + device_handle); + } + break; +#endif + +#if HAVE_OPENCL_D3D11 + case AV_HWDEVICE_TYPE_D3D11VA: + { + AVD3D11VADeviceContext *src_hwctx = src_ctx->hwctx; + cl_context_properties props[5] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_D3D11_DEVICE_KHR, + (intptr_t)src_hwctx->device, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = src_hwctx->device, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_d3d11_platform, + .enumerate_devices = &opencl_enumerate_d3d11_devices, + .filter_device = &opencl_filter_gpu_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + } + break; +#endif + +#if HAVE_OPENCL_DRM_ARM + case AV_HWDEVICE_TYPE_DRM: + { + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = NULL, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_drm_arm_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = &opencl_filter_drm_arm_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, NULL); + } + break; +#endif + + default: + err = AVERROR(ENOSYS); + break; + } + + return err; +} + +static int opencl_get_plane_format(enum AVPixelFormat pixfmt, + int plane, int width, int height, + cl_image_format *image_format, + cl_image_desc *image_desc) +{ + const AVPixFmtDescriptor *desc; + const AVComponentDescriptor *comp; + int channels = 0, order = 0, depth = 0, step = 0; + int wsub, hsub, alpha; + int c; + + if (plane >= AV_NUM_DATA_POINTERS) + return AVERROR(ENOENT); + + desc = av_pix_fmt_desc_get(pixfmt); + + // Only normal images are allowed. + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_HWACCEL | + AV_PIX_FMT_FLAG_PAL)) + return AVERROR(EINVAL); + + wsub = 1 << desc->log2_chroma_w; + hsub = 1 << desc->log2_chroma_h; + // Subsampled components must be exact. + if (width & wsub - 1 || height & hsub - 1) + return AVERROR(EINVAL); + + for (c = 0; c < desc->nb_components; c++) { + comp = &desc->comp[c]; + if (comp->plane != plane) + continue; + // The step size must be a power of two. + if (comp->step != 1 && comp->step != 2 && + comp->step != 4 && comp->step != 8) + return AVERROR(EINVAL); + // The bits in each component must be packed in the + // most-significant-bits of the relevant bytes. + if (comp->shift + comp->depth != 8 && + comp->shift + comp->depth != 16 && + comp->shift + comp->depth != 32) + return AVERROR(EINVAL); + // The depth must not vary between components. + if (depth && comp->depth != depth) + return AVERROR(EINVAL); + // If a single data element crosses multiple bytes then + // it must match the native endianness. + if (comp->depth > 8 && + HAVE_BIGENDIAN == !(desc->flags & AV_PIX_FMT_FLAG_BE)) + return AVERROR(EINVAL); + // A single data element must not contain multiple samples + // from the same component. + if (step && comp->step != step) + return AVERROR(EINVAL); + + depth = comp->depth; + order = order * 10 + comp->offset / ((depth + 7) / 8) + 1; + step = comp->step; + alpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA && + c == desc->nb_components - 1); + ++channels; + } + if (channels == 0) + return AVERROR(ENOENT); + + memset(image_format, 0, sizeof(*image_format)); + memset(image_desc, 0, sizeof(*image_desc)); + image_desc->image_type = CL_MEM_OBJECT_IMAGE2D; + + if (plane == 0 || alpha) { + image_desc->image_width = width; + image_desc->image_height = height; + image_desc->image_row_pitch = step * width; + } else { + image_desc->image_width = width / wsub; + image_desc->image_height = height / hsub; + image_desc->image_row_pitch = step * width / wsub; + } + + if (depth <= 8) { + image_format->image_channel_data_type = CL_UNORM_INT8; + } else { + if (depth <= 16) + image_format->image_channel_data_type = CL_UNORM_INT16; + else if (depth == 32) + image_format->image_channel_data_type = CL_FLOAT; + else + return AVERROR(EINVAL); + } + +#define CHANNEL_ORDER(order, type) \ + case order: image_format->image_channel_order = type; break; + switch (order) { + CHANNEL_ORDER(1, CL_R); + CHANNEL_ORDER(12, CL_RG); + CHANNEL_ORDER(1234, CL_RGBA); + CHANNEL_ORDER(2341, CL_ARGB); + CHANNEL_ORDER(3214, CL_BGRA); +#ifdef CL_ABGR + CHANNEL_ORDER(4321, CL_ABGR); +#endif + default: + return AVERROR(EINVAL); + } +#undef CHANNEL_ORDER + + return 0; +} + +static int opencl_frames_get_constraints(AVHWDeviceContext *hwdev, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_uint nb_image_formats; + cl_image_format *image_formats = NULL; + cl_int cle; + enum AVPixelFormat pix_fmt; + int err, pix_fmts_found; + size_t max_width, max_height; + + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_IMAGE2D_MAX_WIDTH, + sizeof(max_width), &max_width, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query maximum " + "supported image width: %d.\n", cle); + } else { + constraints->max_width = max_width; + } + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_IMAGE2D_MAX_HEIGHT, + sizeof(max_height), &max_height, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query maximum " + "supported image height: %d.\n", cle); + } else { + constraints->max_height = max_height; + } + av_log(hwdev, AV_LOG_DEBUG, "Maximum supported image size %dx%d.\n", + constraints->max_width, constraints->max_height); + + cle = clGetSupportedImageFormats(hwctx->context, + CL_MEM_READ_WRITE, + CL_MEM_OBJECT_IMAGE2D, + 0, NULL, &nb_image_formats); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query supported " + "image formats: %d.\n", cle); + err = AVERROR(ENOSYS); + goto fail; + } + if (nb_image_formats == 0) { + av_log(hwdev, AV_LOG_ERROR, "No image support in OpenCL " + "driver (zero supported image formats).\n"); + err = AVERROR(ENOSYS); + goto fail; + } + + image_formats = + av_malloc_array(nb_image_formats, sizeof(*image_formats)); + if (!image_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + + cle = clGetSupportedImageFormats(hwctx->context, + CL_MEM_READ_WRITE, + CL_MEM_OBJECT_IMAGE2D, + nb_image_formats, + image_formats, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query supported " + "image formats: %d.\n", cle); + err = AVERROR(ENOSYS); + goto fail; + } + + pix_fmts_found = 0; + for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) { + cl_image_format image_format; + cl_image_desc image_desc; + int plane, i; + + for (plane = 0;; plane++) { + err = opencl_get_plane_format(pix_fmt, plane, 0, 0, + &image_format, + &image_desc); + if (err < 0) + break; + + for (i = 0; i < nb_image_formats; i++) { + if (image_formats[i].image_channel_order == + image_format.image_channel_order && + image_formats[i].image_channel_data_type == + image_format.image_channel_data_type) + break; + } + if (i == nb_image_formats) { + err = AVERROR(EINVAL); + break; + } + } + if (err != AVERROR(ENOENT)) + continue; + + av_log(hwdev, AV_LOG_DEBUG, "Format %s supported.\n", + av_get_pix_fmt_name(pix_fmt)); + + err = av_reallocp_array(&constraints->valid_sw_formats, + pix_fmts_found + 2, + sizeof(*constraints->valid_sw_formats)); + if (err < 0) + goto fail; + constraints->valid_sw_formats[pix_fmts_found] = pix_fmt; + constraints->valid_sw_formats[pix_fmts_found + 1] = + AV_PIX_FMT_NONE; + ++pix_fmts_found; + } + + av_freep(&image_formats); + + constraints->valid_hw_formats = + av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + constraints->valid_hw_formats[0] = AV_PIX_FMT_OPENCL; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; + +fail: + av_freep(&image_formats); + return err; +} + +static void opencl_pool_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *hwfc = opaque; + AVOpenCLFrameDescriptor *desc = (AVOpenCLFrameDescriptor*)data; + cl_int cle; + int p; + + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release plane %d: " + "%d.\n", p, cle); + } + } + + av_free(desc); +} + +static AVBufferRef *opencl_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *hwfc = opaque; + AVOpenCLDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVOpenCLFrameDescriptor *desc; + cl_int cle; + cl_mem image; + cl_image_format image_format; + cl_image_desc image_desc; + int err, p; + AVBufferRef *ref; + + desc = av_mallocz(sizeof(*desc)); + if (!desc) + return NULL; + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + hwfc->width, hwfc->height, + &image_format, &image_desc); + if (err == AVERROR(ENOENT)) + break; + if (err < 0) + goto fail; + + // For generic image objects, the pitch is determined by the + // implementation. + image_desc.image_row_pitch = 0; + + image = clCreateImage(hwctx->context, CL_MEM_READ_WRITE, + &image_format, &image_desc, NULL, &cle); + if (!image) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create image for " + "plane %d: %d.\n", p, cle); + goto fail; + } + + desc->planes[p] = image; + } + + desc->nb_planes = p; + + ref = av_buffer_create((uint8_t*)desc, sizeof(*desc), + &opencl_pool_free, hwfc, 0); + if (!ref) + goto fail; + + return ref; + +fail: + for (p = 0; desc->planes[p]; p++) + clReleaseMemObject(desc->planes[p]); + av_free(desc); + return NULL; +} + +static int opencl_frames_init_command_queue(AVHWFramesContext *hwfc) +{ + AVOpenCLFramesContext *hwctx = hwfc->hwctx; + OpenCLDeviceContext *devpriv = hwfc->device_ctx->internal->priv; + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_int cle; + + priv->command_queue = hwctx->command_queue ? hwctx->command_queue + : devpriv->command_queue; + cle = clRetainCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to retain frame " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + + return 0; +} + +static int opencl_frames_init(AVHWFramesContext *hwfc) +{ + if (!hwfc->pool) { + hwfc->internal->pool_internal = + av_buffer_pool_init2(sizeof(cl_mem), hwfc, + &opencl_pool_alloc, NULL); + if (!hwfc->internal->pool_internal) + return AVERROR(ENOMEM); + } + + return opencl_frames_init_command_queue(hwfc); +} + +static void opencl_frames_uninit(AVHWFramesContext *hwfc) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_int cle; + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 + int i, p; + for (i = 0; i < priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release mapped " + "frame object (frame %d plane %d): %d.\n", + i, p, cle); + } + } + } + av_freep(&priv->mapped_frames); +#endif + + if (priv->command_queue) { + cle = clReleaseCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release frame " + "command queue: %d.\n", cle); + } + priv->command_queue = NULL; + } +} + +static int opencl_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + AVOpenCLFrameDescriptor *desc; + int p; + + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + desc = (AVOpenCLFrameDescriptor*)frame->buf[0]->data; + + for (p = 0; p < desc->nb_planes; p++) + frame->data[p] = (uint8_t*)desc->planes[p]; + + frame->format = AV_PIX_FMT_OPENCL; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +static int opencl_transfer_get_formats(AVHWFramesContext *hwfc, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = hwfc->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + return 0; +} + +static int opencl_wait_events(AVHWFramesContext *hwfc, + cl_event *events, int nb_events) +{ + cl_int cle; + int i; + + cle = clWaitForEvents(nb_events, events); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to wait for event " + "completion: %d.\n", cle); + return AVERROR(EIO); + } + + for (i = 0; i < nb_events; i++) { + cle = clReleaseEvent(events[i]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release " + "event: %d.\n", cle); + } + } + + return 0; +} + +static int opencl_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + if (dst->format != hwfc->sw_format) + return AVERROR(EINVAL); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err < 0) { + if (err == AVERROR(ENOENT)) + err = 0; + break; + } + + if (!dst->data[p]) { + av_log(hwfc, AV_LOG_ERROR, "Plane %d missing on " + "destination frame for transfer.\n", p); + err = AVERROR(EINVAL); + break; + } + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + cle = clEnqueueReadImage(priv->command_queue, + (cl_mem)src->data[p], + CL_FALSE, origin, region, + dst->linesize[p], 0, + dst->data[p], + 0, NULL, &events[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to enqueue read of " + "OpenCL image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + break; + } + } + + opencl_wait_events(hwfc, events, p); + + return err; +} + +static int opencl_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + if (src->format != hwfc->sw_format) + return AVERROR(EINVAL); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err < 0) { + if (err == AVERROR(ENOENT)) + err = 0; + break; + } + + if (!src->data[p]) { + av_log(hwfc, AV_LOG_ERROR, "Plane %d missing on " + "source frame for transfer.\n", p); + err = AVERROR(EINVAL); + break; + } + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + cle = clEnqueueWriteImage(priv->command_queue, + (cl_mem)dst->data[p], + CL_FALSE, origin, region, + src->linesize[p], 0, + src->data[p], + 0, NULL, &events[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to enqueue write of " + "OpenCL image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + break; + } + } + + opencl_wait_events(hwfc, events, p); + + return err; +} + +typedef struct OpenCLMapping { + // The mapped addresses for each plane. + // The destination frame is not available when we unmap, so these + // need to be stored separately. + void *address[AV_NUM_DATA_POINTERS]; +} OpenCLMapping; + +static void opencl_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + OpenCLMapping *map = hwmap->priv; + cl_event events[AV_NUM_DATA_POINTERS]; + int p, e; + cl_int cle; + + for (p = e = 0; p < FF_ARRAY_ELEMS(map->address); p++) { + if (!map->address[p]) + break; + + cle = clEnqueueUnmapMemObject(priv->command_queue, + (cl_mem)hwmap->source->data[p], + map->address[p], + 0, NULL, &events[e]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to unmap OpenCL " + "image plane %d: %d.\n", p, cle); + } + ++e; + } + + opencl_wait_events(hwfc, events, e); + + av_free(map); +} + +static int opencl_map_frame(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_map_flags map_flags; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + OpenCLMapping *map; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + size_t row_pitch; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + av_assert0(hwfc->sw_format == dst->format); + + if (flags & AV_HWFRAME_MAP_OVERWRITE && + !(flags & AV_HWFRAME_MAP_READ)) { + // This is mutually exclusive with the read/write flags, so + // there is no way to map with read here. + map_flags = CL_MAP_WRITE_INVALIDATE_REGION; + } else { + map_flags = 0; + if (flags & AV_HWFRAME_MAP_READ) + map_flags |= CL_MAP_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + map_flags |= CL_MAP_WRITE; + } + + map = av_mallocz(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err == AVERROR(ENOENT)) + break; + if (err < 0) + goto fail; + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + map->address[p] = + clEnqueueMapImage(priv->command_queue, + (cl_mem)src->data[p], + CL_FALSE, map_flags, origin, region, + &row_pitch, NULL, 0, NULL, + &events[p], &cle); + if (!map->address[p]) { + av_log(hwfc, AV_LOG_ERROR, "Failed to map OpenCL " + "image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = map->address[p]; + + av_log(hwfc, AV_LOG_DEBUG, "Map plane %d (%p -> %p).\n", + p, src->data[p], dst->data[p]); + } + + err = opencl_wait_events(hwfc, events, p); + if (err < 0) + goto fail; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &opencl_unmap_frame, map); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < AV_NUM_DATA_POINTERS; p++) { + if (!map->address[p]) + break; + clEnqueueUnmapMemObject(priv->command_queue, + (cl_mem)src->data[p], + map->address[p], + 0, NULL, &events[p]); + } + if (p > 0) + opencl_wait_events(hwfc, events, p); + av_freep(&map); + return err; +} + +#if HAVE_OPENCL_DRM_BEIGNET + +typedef struct DRMBeignetToOpenCLMapping { + AVFrame *drm_frame; + AVDRMFrameDescriptor *drm_desc; + + AVOpenCLFrameDescriptor frame; +} DRMBeignetToOpenCLMapping; + +static void opencl_unmap_from_drm_beignet(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + DRMBeignetToOpenCLMapping *mapping = hwmap->priv; + cl_int cle; + int i; + + for (i = 0; i < mapping->frame.nb_planes; i++) { + cle = clReleaseMemObject(mapping->frame.planes[i]); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release CL image " + "of plane %d of DRM frame: %d.\n", i, cle); + } + } + + av_free(mapping); +} + +static int opencl_map_from_drm_beignet(AVHWFramesContext *dst_fc, + AVFrame *dst, const AVFrame *src, + int flags) +{ + AVOpenCLDeviceContext *hwctx = dst_fc->device_ctx->hwctx; + OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; + DRMBeignetToOpenCLMapping *mapping; + const AVDRMFrameDescriptor *desc; + cl_int cle; + int err, i, j, p; + + desc = (const AVDRMFrameDescriptor*)src->data[0]; + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + p = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + for (j = 0; j < layer->nb_planes; j++) { + const AVDRMPlaneDescriptor *plane = &layer->planes[j]; + const AVDRMObjectDescriptor *object = + &desc->objects[plane->object_index]; + + cl_import_image_info_intel image_info = { + .fd = object->fd, + .size = object->size, + .type = CL_MEM_OBJECT_IMAGE2D, + .offset = plane->offset, + .row_pitch = plane->pitch, + }; + cl_image_desc image_desc; + + err = opencl_get_plane_format(dst_fc->sw_format, p, + src->width, src->height, + &image_info.fmt, + &image_desc); + if (err < 0) { + av_log(dst_fc, AV_LOG_ERROR, "DRM frame layer %d " + "plane %d is not representable in OpenCL: %d.\n", + i, j, err); + goto fail; + } + image_info.width = image_desc.image_width; + image_info.height = image_desc.image_height; + + mapping->frame.planes[p] = + priv->clCreateImageFromFdINTEL(hwctx->context, + &image_info, &cle); + if (!mapping->frame.planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image " + "from layer %d plane %d of DRM frame: %d.\n", + i, j, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = (uint8_t*)mapping->frame.planes[p]; + mapping->frame.nb_planes = ++p; + } + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_drm_beignet, + mapping); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < mapping->frame.nb_planes; p++) { + if (mapping->frame.planes[p]) + clReleaseMemObject(mapping->frame.planes[p]); + } + av_free(mapping); + memset(dst->data, 0, sizeof(dst->data)); + return err; +} + +#if HAVE_OPENCL_VAAPI_BEIGNET + +static int opencl_map_from_vaapi(AVHWFramesContext *dst_fc, + AVFrame *dst, const AVFrame *src, + int flags) +{ + AVFrame *tmp; + int err; + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + tmp->format = AV_PIX_FMT_DRM_PRIME; + + err = av_hwframe_map(tmp, src, flags); + if (err < 0) + goto fail; + + err = opencl_map_from_drm_beignet(dst_fc, dst, tmp, flags); + if (err < 0) + goto fail; + + err = ff_hwframe_map_replace(dst, src); + +fail: + av_frame_free(&tmp); + return err; +} + +#endif /* HAVE_OPENCL_VAAPI_BEIGNET */ +#endif /* HAVE_OPENCL_DRM_BEIGNET */ + +static inline cl_mem_flags opencl_mem_flags_for_mapping(int map_flags) +{ + if ((map_flags & AV_HWFRAME_MAP_READ) && + (map_flags & AV_HWFRAME_MAP_WRITE)) + return CL_MEM_READ_WRITE; + else if (map_flags & AV_HWFRAME_MAP_READ) + return CL_MEM_READ_ONLY; + else if (map_flags & AV_HWFRAME_MAP_WRITE) + return CL_MEM_WRITE_ONLY; + else + return 0; +} + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + +static void opencl_unmap_from_qsv(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_event event; + cl_int cle; + int p; + + av_log(dst_fc, AV_LOG_DEBUG, "Unmap QSV/VAAPI surface from OpenCL.\n"); + + cle = device_priv->clEnqueueReleaseVA_APIMediaSurfacesINTEL( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handles: %d.\n", cle); + } + + opencl_wait_events(dst_fc, &event, 1); + + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release CL " + "image of plane %d of QSV/VAAPI surface: %d\n", + p, cle); + } + } + + av_free(desc); +} + +static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + VASurfaceID va_surface; + cl_mem_flags cl_flags; + cl_event event; + cl_int cle; + int err, p; + +#if CONFIG_LIBMFX + if (src->format == AV_PIX_FMT_QSV) { + void *base_handle; + mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3]; + err = ff_qsv_get_surface_base_handle(mfx_surface, + AV_HWDEVICE_TYPE_VAAPI, + &base_handle); + if (err < 0) + return err; + va_surface = *(VASurfaceID *)base_handle; + } else +#endif + if (src->format == AV_PIX_FMT_VAAPI) { + va_surface = (VASurfaceID)(uintptr_t)src->data[3]; + } else { + return AVERROR(ENOSYS); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + av_log(src_fc, AV_LOG_DEBUG, "Map QSV/VAAPI surface %#x to " + "OpenCL.\n", va_surface); + + desc = av_mallocz(sizeof(*desc)); + if (!desc) + return AVERROR(ENOMEM); + + // The cl_intel_va_api_media_sharing extension only supports NV12 + // surfaces, so for now there are always exactly two planes. + desc->nb_planes = 2; + + for (p = 0; p < desc->nb_planes; p++) { + desc->planes[p] = + device_priv->clCreateFromVA_APIMediaSurfaceINTEL( + dst_dev->context, cl_flags, &va_surface, p, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of QSV/VAAPI surface " + "%#x: %d.\n", p, va_surface, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = (uint8_t*)desc->planes[p]; + } + + cle = device_priv->clEnqueueAcquireVA_APIMediaSurfacesINTEL( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handles: %d.\n", cle); + err = AVERROR(EIO); + goto fail; + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_qsv, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < desc->nb_planes; p++) + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + av_freep(&desc); + memset(dst->data, 0, sizeof(dst->data)); + return err; +} + +#endif + +#if HAVE_OPENCL_DXVA2 + +static void opencl_unmap_from_dxva2(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->device_ctx->internal->priv; + cl_event event; + cl_int cle; + + av_log(dst_fc, AV_LOG_DEBUG, "Unmap DXVA2 surface from OpenCL.\n"); + + cle = device_priv->clEnqueueReleaseDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handle: %d.\n", cle); + return; + } + + opencl_wait_events(dst_fc, &event, 1); +} + +static int opencl_map_from_dxva2(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVDXVA2FramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + cl_event event; + cl_int cle; + int err, i; + + av_log(dst_fc, AV_LOG_DEBUG, "Map DXVA2 surface %p to " + "OpenCL.\n", src->data[3]); + + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + if (src_hwctx->surfaces[i] == (IDirect3DSurface9*)src->data[3]) + break; + } + if (i >= src_hwctx->nb_surfaces) { + av_log(dst_fc, AV_LOG_ERROR, "Trying to map from a surface which " + "is not in the mapped frames context.\n"); + return AVERROR(EINVAL); + } + + desc = &frames_priv->mapped_frames[i]; + + cle = device_priv->clEnqueueAcquireDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handle: %d.\n", cle); + return AVERROR(EIO); + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + for (i = 0; i < desc->nb_planes; i++) + dst->data[i] = (uint8_t*)desc->planes[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_dxva2, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + cle = device_priv->clEnqueueReleaseDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle == CL_SUCCESS) + opencl_wait_events(dst_fc, &event, 1); + memset(dst->data, 0, sizeof(dst->data)); + return err; +} + +static int opencl_frames_derive_from_dxva2(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + AVDXVA2FramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_mem_flags cl_flags; + cl_int cle; + int err, i, p, nb_planes; + + if (src_fc->sw_format != AV_PIX_FMT_NV12) { + av_log(dst_fc, AV_LOG_ERROR, "Only NV12 textures are supported " + "for DXVA2 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + nb_planes = 2; + + if (src_fc->initial_pool_size == 0) { + av_log(dst_fc, AV_LOG_ERROR, "Only fixed-size pools are supported " + "for DXVA2 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + frames_priv->nb_mapped_frames = src_hwctx->nb_surfaces; + + frames_priv->mapped_frames = + av_calloc(frames_priv->nb_mapped_frames, + sizeof(*frames_priv->mapped_frames)); + if (!frames_priv->mapped_frames) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + cl_dx9_surface_info_khr surface_info = { + .resource = src_hwctx->surfaces[i], + .shared_handle = NULL, + }; + desc->nb_planes = nb_planes; + for (p = 0; p < nb_planes; p++) { + desc->planes[p] = + device_priv->clCreateFromDX9MediaSurfaceKHR( + dst_dev->context, cl_flags, + device_priv->dx9_media_adapter_type, + &surface_info, p, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of DXVA2 surface %d: %d.\n", + p, i, cle); + err = AVERROR(EIO); + goto fail; + } + } + } + + return 0; + +fail: + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + } + } + av_freep(&frames_priv->mapped_frames); + frames_priv->nb_mapped_frames = 0; + return err; +} + +#endif + +#if HAVE_OPENCL_D3D11 + +static void opencl_unmap_from_d3d11(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->device_ctx->internal->priv; + cl_event event; + cl_int cle; + + cle = device_priv->clEnqueueReleaseD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handle: %d.\n", cle); + } + + opencl_wait_events(dst_fc, &event, 1); +} + +static int opencl_map_from_d3d11(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + cl_event event; + cl_int cle; + int err, index, i; + + index = (intptr_t)src->data[1]; + if (index >= frames_priv->nb_mapped_frames) { + av_log(dst_fc, AV_LOG_ERROR, "Texture array index out of range for " + "mapping: %d >= %d.\n", index, frames_priv->nb_mapped_frames); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map D3D11 texture %d to OpenCL.\n", + index); + + desc = &frames_priv->mapped_frames[index]; + + cle = device_priv->clEnqueueAcquireD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handle: %d.\n", cle); + return AVERROR(EIO); + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + for (i = 0; i < desc->nb_planes; i++) + dst->data[i] = (uint8_t*)desc->planes[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_d3d11, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + cle = device_priv->clEnqueueReleaseD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle == CL_SUCCESS) + opencl_wait_events(dst_fc, &event, 1); + memset(dst->data, 0, sizeof(dst->data)); + return err; +} + +static int opencl_frames_derive_from_d3d11(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + AVD3D11VAFramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_mem_flags cl_flags; + cl_int cle; + int err, i, p, nb_planes; + + if (src_fc->sw_format != AV_PIX_FMT_NV12) { + av_log(dst_fc, AV_LOG_ERROR, "Only NV12 textures are supported " + "for D3D11 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + nb_planes = 2; + + if (src_fc->initial_pool_size == 0) { + av_log(dst_fc, AV_LOG_ERROR, "Only fixed-size pools are supported " + "for D3D11 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + frames_priv->nb_mapped_frames = src_fc->initial_pool_size; + + frames_priv->mapped_frames = + av_calloc(frames_priv->nb_mapped_frames, + sizeof(*frames_priv->mapped_frames)); + if (!frames_priv->mapped_frames) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + desc->nb_planes = nb_planes; + for (p = 0; p < nb_planes; p++) { + UINT subresource = 2 * i + p; + + desc->planes[p] = + device_priv->clCreateFromD3D11Texture2DKHR( + dst_dev->context, cl_flags, src_hwctx->texture, + subresource, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of D3D texture " + "index %d (subresource %u): %d.\n", + p, i, (unsigned int)subresource, cle); + err = AVERROR(EIO); + goto fail; + } + } + } + + return 0; + +fail: + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + } + } + av_freep(&frames_priv->mapped_frames); + frames_priv->nb_mapped_frames = 0; + return err; +} + +#endif + +#if HAVE_OPENCL_DRM_ARM + +typedef struct DRMARMtoOpenCLMapping { + int nb_objects; + cl_mem object_buffers[AV_DRM_MAX_PLANES]; + int nb_planes; + cl_mem plane_images[AV_DRM_MAX_PLANES]; +} DRMARMtoOpenCLMapping; + +static void opencl_unmap_from_drm_arm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + DRMARMtoOpenCLMapping *mapping = hwmap->priv; + int i; + + for (i = 0; i < mapping->nb_planes; i++) + clReleaseMemObject(mapping->plane_images[i]); + + for (i = 0; i < mapping->nb_objects; i++) + clReleaseMemObject(mapping->object_buffers[i]); + + av_free(mapping); +} + +static int opencl_map_from_drm_arm(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + DRMARMtoOpenCLMapping *mapping = NULL; + cl_mem_flags cl_flags; + const cl_import_properties_arm props[3] = { + CL_IMPORT_TYPE_ARM, CL_IMPORT_TYPE_DMA_BUF_ARM, 0, + }; + cl_int cle; + int err, i, j; + + desc = (const AVDRMFrameDescriptor*)src->data[0]; + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + mapping->nb_objects = desc->nb_objects; + for (i = 0; i < desc->nb_objects; i++) { + int fd = desc->objects[i].fd; + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM PRIME fd %d to OpenCL.\n", fd); + + if (desc->objects[i].format_modifier) { + av_log(dst_fc, AV_LOG_DEBUG, "Warning: object %d fd %d has " + "nonzero format modifier %"PRId64", result may not " + "be as expected.\n", i, fd, + desc->objects[i].format_modifier); + } + + mapping->object_buffers[i] = + clImportMemoryARM(dst_dev->context, cl_flags, props, + &fd, desc->objects[i].size, &cle); + if (!mapping->object_buffers[i]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL buffer " + "from object %d (fd %d, size %"SIZE_SPECIFIER") of DRM frame: %d.\n", + i, fd, desc->objects[i].size, cle); + err = AVERROR(EIO); + goto fail; + } + } + + mapping->nb_planes = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + + for (j = 0; j < layer->nb_planes; j++) { + const AVDRMPlaneDescriptor *plane = &layer->planes[j]; + cl_mem plane_buffer; + cl_image_format image_format; + cl_image_desc image_desc; + cl_buffer_region region; + int p = mapping->nb_planes; + + err = opencl_get_plane_format(src_fc->sw_format, p, + src_fc->width, src_fc->height, + &image_format, &image_desc); + if (err < 0) { + av_log(dst_fc, AV_LOG_ERROR, "Invalid plane %d (DRM " + "layer %d plane %d): %d.\n", p, i, j, err); + goto fail; + } + + region.origin = plane->offset; + region.size = image_desc.image_row_pitch * + image_desc.image_height; + + plane_buffer = + clCreateSubBuffer(mapping->object_buffers[plane->object_index], + cl_flags, + CL_BUFFER_CREATE_TYPE_REGION, + ®ion, &cle); + if (!plane_buffer) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create sub-buffer " + "for plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + image_desc.buffer = plane_buffer; + + mapping->plane_images[p] = + clCreateImage(dst_dev->context, cl_flags, + &image_format, &image_desc, NULL, &cle); + + // Unreference the sub-buffer immediately - we don't need it + // directly and a reference is held by the image. + clReleaseMemObject(plane_buffer); + + if (!mapping->plane_images[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create image " + "for plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + ++mapping->nb_planes; + } + } + + for (i = 0; i < mapping->nb_planes; i++) + dst->data[i] = (uint8_t*)mapping->plane_images[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_drm_arm, mapping); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (i = 0; i < mapping->nb_planes; i++) { + clReleaseMemObject(mapping->plane_images[i]); + } + for (i = 0; i < mapping->nb_objects; i++) { + if (mapping->object_buffers[i]) + clReleaseMemObject(mapping->object_buffers[i]); + } + av_free(mapping); + memset(dst->data, 0, sizeof(dst->data)); + return err; +} + +#endif + +static int opencl_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_assert0(src->format == AV_PIX_FMT_OPENCL); + if (hwfc->sw_format != dst->format) + return AVERROR(ENOSYS); + return opencl_map_frame(hwfc, dst, src, flags); +} + +static int opencl_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_unused OpenCLDeviceContext *priv = hwfc->device_ctx->internal->priv; + av_assert0(dst->format == AV_PIX_FMT_OPENCL); + switch (src->format) { +#if HAVE_OPENCL_DRM_BEIGNET + case AV_PIX_FMT_DRM_PRIME: + if (priv->beignet_drm_mapping_usable) + return opencl_map_from_drm_beignet(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_VAAPI_BEIGNET + case AV_PIX_FMT_VAAPI: + if (priv->beignet_drm_mapping_usable) + return opencl_map_from_vaapi(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + case AV_PIX_FMT_QSV: + case AV_PIX_FMT_VAAPI: + if (priv->qsv_mapping_usable) + return opencl_map_from_qsv(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_DXVA2 + case AV_PIX_FMT_DXVA2_VLD: + if (priv->dxva2_mapping_usable) + return opencl_map_from_dxva2(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_D3D11 + case AV_PIX_FMT_D3D11: + if (priv->d3d11_mapping_usable) + return opencl_map_from_d3d11(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_DRM_ARM + case AV_PIX_FMT_DRM_PRIME: + if (priv->drm_arm_mapping_usable) + return opencl_map_from_drm_arm(hwfc, dst, src, flags); +#endif + } + return AVERROR(ENOSYS); +} + +static int opencl_frames_derive_to(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + av_unused OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; + switch (src_fc->device_ctx->type) { +#if HAVE_OPENCL_DRM_BEIGNET + case AV_HWDEVICE_TYPE_DRM: + if (!priv->beignet_drm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_VAAPI_BEIGNET + case AV_HWDEVICE_TYPE_VAAPI: + if (!priv->beignet_drm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + case AV_HWDEVICE_TYPE_QSV: + case AV_HWDEVICE_TYPE_VAAPI: + if (!priv->qsv_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + if (!priv->dxva2_mapping_usable) + return AVERROR(ENOSYS); + { + int err; + err = opencl_frames_derive_from_dxva2(dst_fc, src_fc, flags); + if (err < 0) + return err; + } + break; +#endif +#if HAVE_OPENCL_D3D11 + case AV_HWDEVICE_TYPE_D3D11VA: + if (!priv->d3d11_mapping_usable) + return AVERROR(ENOSYS); + { + int err; + err = opencl_frames_derive_from_d3d11(dst_fc, src_fc, flags); + if (err < 0) + return err; + } + break; +#endif +#if HAVE_OPENCL_DRM_ARM + case AV_HWDEVICE_TYPE_DRM: + if (!priv->drm_arm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif + default: + return AVERROR(ENOSYS); + } + return opencl_frames_init_command_queue(dst_fc); +} + +const HWContextType ff_hwcontext_type_opencl = { + .type = AV_HWDEVICE_TYPE_OPENCL, + .name = "OpenCL", + + .device_hwctx_size = sizeof(AVOpenCLDeviceContext), + .device_priv_size = sizeof(OpenCLDeviceContext), + .frames_hwctx_size = sizeof(AVOpenCLFramesContext), + .frames_priv_size = sizeof(OpenCLFramesContext), + + .device_create = &opencl_device_create, + .device_derive = &opencl_device_derive, + .device_init = &opencl_device_init, + .device_uninit = &opencl_device_uninit, + + .frames_get_constraints = &opencl_frames_get_constraints, + .frames_init = &opencl_frames_init, + .frames_uninit = &opencl_frames_uninit, + .frames_get_buffer = &opencl_get_buffer, + + .transfer_get_formats = &opencl_transfer_get_formats, + .transfer_data_to = &opencl_transfer_data_to, + .transfer_data_from = &opencl_transfer_data_from, + + .map_from = &opencl_map_from, + .map_to = &opencl_map_to, + .frames_derive_to = &opencl_frames_derive_to, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_OPENCL, + AV_PIX_FMT_NONE + }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.h new file mode 100644 index 00000000..ef54486c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_opencl.h @@ -0,0 +1,100 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_OPENCL_H +#define AVUTIL_HWCONTEXT_OPENCL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "frame.h" + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_OPENCL. + * + * Pools allocated internally are always dynamic, and are primarily intended + * to be used in OpenCL-only cases. If interoperation is required, it is + * typically required to allocate frames in the other API and then map the + * frames context to OpenCL with av_hwframe_ctx_create_derived(). + */ + +/** + * OpenCL frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + */ +typedef struct AVOpenCLFrameDescriptor { + /** + * Number of planes in the frame. + */ + int nb_planes; + /** + * OpenCL image2d objects for each plane of the frame. + */ + cl_mem planes[AV_NUM_DATA_POINTERS]; +} AVOpenCLFrameDescriptor; + +/** + * OpenCL device details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVOpenCLDeviceContext { + /** + * The primary device ID of the device. If multiple OpenCL devices + * are associated with the context then this is the one which will + * be used for all operations internal to FFmpeg. + */ + cl_device_id device_id; + /** + * The OpenCL context which will contain all operations and frames on + * this device. + */ + cl_context context; + /** + * The default command queue for this device, which will be used by all + * frames contexts which do not have their own command queue. If not + * intialised by the user, a default queue will be created on the + * primary device. + */ + cl_command_queue command_queue; +} AVOpenCLDeviceContext; + +/** + * OpenCL-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVOpenCLFramesContext { + /** + * The command queue used for internal asynchronous operations on this + * device (av_hwframe_transfer_data(), av_hwframe_map()). + * + * If this is not set, the command queue from the associated device is + * used instead. + */ + cl_command_queue command_queue; +} AVOpenCLFramesContext; + +#endif /* AVUTIL_HWCONTEXT_OPENCL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.c new file mode 100644 index 00000000..ec0f72b3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.c @@ -0,0 +1,2226 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include + +#include "config.h" + +#if HAVE_PTHREADS +#include +#endif + +#define COBJMACROS +#if CONFIG_VAAPI +#include "hwcontext_vaapi.h" +#endif +#if CONFIG_D3D11VA +#include "hwcontext_d3d11va.h" +#endif +#if CONFIG_DXVA2 +#include "hwcontext_dxva2.h" +#endif + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_qsv.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" +#include "time.h" +#include "imgutils.h" +#include "avassert.h" + +#define QSV_VERSION_ATLEAST(MAJOR, MINOR) \ + (MFX_VERSION_MAJOR > (MAJOR) || \ + MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) + +#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) +#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) +#define QSV_HAVE_OPAQUE !QSV_ONEVPL + +#if QSV_ONEVPL +#include +#else +#define MFXUnload(a) do { } while(0) +#endif + +typedef struct QSVDevicePriv { + AVBufferRef *child_device_ctx; +} QSVDevicePriv; + +typedef struct QSVDeviceContext { + mfxHDL handle; + mfxHandleType handle_type; + mfxVersion ver; + mfxIMPL impl; + + enum AVHWDeviceType child_device_type; + enum AVPixelFormat child_pix_fmt; +} QSVDeviceContext; + +typedef struct QSVFramesContext { + mfxSession session_download; + atomic_int session_download_init; + mfxSession session_upload; + atomic_int session_upload_init; +#if HAVE_PTHREADS + pthread_mutex_t session_lock; +#endif + + AVBufferRef *child_frames_ref; + mfxFrameSurface1 *surfaces_internal; + mfxHDLPair *handle_pairs_internal; + int nb_surfaces_used; + + // used in the frame allocator for non-opaque surfaces + mfxMemId *mem_ids; +#if QSV_HAVE_OPAQUE + // used in the opaque alloc request for opaque surfaces + mfxFrameSurface1 **surface_ptrs; + + mfxExtOpaqueSurfaceAlloc opaque_alloc; + mfxExtBuffer *ext_buffers[1]; +#endif + AVFrame realigned_upload_frame; + AVFrame realigned_download_frame; +} QSVFramesContext; + +static const struct { + enum AVPixelFormat pix_fmt; + uint32_t fourcc; + uint16_t mfx_shift; +} supported_pixel_formats[] = { + { AV_PIX_FMT_NV12, MFX_FOURCC_NV12, 0 }, + { AV_PIX_FMT_BGRA, MFX_FOURCC_RGB4, 0 }, + { AV_PIX_FMT_P010, MFX_FOURCC_P010, 1 }, + { AV_PIX_FMT_PAL8, MFX_FOURCC_P8, 0 }, +#if CONFIG_VAAPI + { AV_PIX_FMT_YUYV422, + MFX_FOURCC_YUY2, 0 }, + { AV_PIX_FMT_Y210, + MFX_FOURCC_Y210, 1 }, + // VUYX is used for VAAPI child device, + // the SDK only delares support for AYUV + { AV_PIX_FMT_VUYX, + MFX_FOURCC_AYUV, 0 }, + // XV30 is used for VAAPI child device, + // the SDK only delares support for Y410 + { AV_PIX_FMT_XV30, + MFX_FOURCC_Y410, 0 }, +#if QSV_VERSION_ATLEAST(1, 31) + // P012 is used for VAAPI child device, + // the SDK only delares support for P016 + { AV_PIX_FMT_P012, + MFX_FOURCC_P016, 1 }, + // Y212 is used for VAAPI child device, + // the SDK only delares support for Y216 + { AV_PIX_FMT_Y212, + MFX_FOURCC_Y216, 1 }, + // XV36 is used for VAAPI child device, + // the SDK only delares support for Y416 + { AV_PIX_FMT_XV36, + MFX_FOURCC_Y416, 1 }, +#endif +#endif +}; + +extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, + enum AVHWDeviceType base_dev_type, + void **base_handle); + +/** + * Caller needs to allocate enough space for base_handle pointer. + **/ +int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, + enum AVHWDeviceType base_dev_type, + void **base_handle) +{ + mfxHDLPair *handle_pair; + handle_pair = surf->Data.MemId; + switch (base_dev_type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + base_handle[0] = handle_pair->first; + return 0; +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + base_handle[0] = handle_pair->first; + base_handle[1] = handle_pair->second; + return 0; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + base_handle[0] = handle_pair->first; + return 0; +#endif + } + return AVERROR(EINVAL); +} + +static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { + if (supported_pixel_formats[i].pix_fmt == pix_fmt) + return supported_pixel_formats[i].fourcc; + } + return 0; +} + +static uint16_t qsv_shift_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + for (int i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { + if (supported_pixel_formats[i].pix_fmt == pix_fmt) + return supported_pixel_formats[i].mfx_shift; + } + + return 0; +} + +#if CONFIG_D3D11VA +static uint32_t qsv_get_d3d11va_bind_flags(int mem_type) +{ + uint32_t bind_flags = 0; + + if ((mem_type & MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET) && (mem_type & MFX_MEMTYPE_INTERNAL_FRAME)) + bind_flags = D3D11_BIND_DECODER | D3D11_BIND_VIDEO_ENCODER; + else + bind_flags = D3D11_BIND_DECODER; + + if ((MFX_MEMTYPE_FROM_VPPOUT & mem_type) || (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & mem_type)) + bind_flags = D3D11_BIND_RENDER_TARGET; + + return bind_flags; +} +#endif + +static int qsv_fill_border(AVFrame *dst, const AVFrame *src) +{ + const AVPixFmtDescriptor *desc; + int i, planes_nb = 0; + if (dst->format != src->format) + return AVERROR(EINVAL); + + desc = av_pix_fmt_desc_get(dst->format); + + for (i = 0; i < desc->nb_components; i++) + planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1); + + for (i = 0; i < planes_nb; i++) { + int sheight, dheight, y; + ptrdiff_t swidth = av_image_get_linesize(src->format, + src->width, + i); + ptrdiff_t dwidth = av_image_get_linesize(dst->format, + dst->width, + i); + const AVComponentDescriptor comp = desc->comp[i]; + if (swidth < 0 || dwidth < 0) { + av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n"); + return AVERROR(EINVAL); + } + sheight = src->height; + dheight = dst->height; + if (i) { + sheight = AV_CEIL_RSHIFT(src->height, desc->log2_chroma_h); + dheight = AV_CEIL_RSHIFT(dst->height, desc->log2_chroma_h); + } + //fill right padding + for (y = 0; y < sheight; y++) { + void *line_ptr = dst->data[i] + y*dst->linesize[i] + swidth; + av_memcpy_backptr(line_ptr, + comp.depth > 8 ? 2 : 1, + dwidth - swidth); + } + //fill bottom padding + for (y = sheight; y < dheight; y++) { + memcpy(dst->data[i]+y*dst->linesize[i], + dst->data[i]+(sheight-1)*dst->linesize[i], + dwidth); + } + } + return 0; +} + +static int qsv_device_init(AVHWDeviceContext *ctx) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + QSVDeviceContext *s = ctx->internal->priv; + int hw_handle_supported = 0; + mfxHandleType handle_type; + enum AVHWDeviceType device_type; + enum AVPixelFormat pix_fmt; + mfxStatus err; + + err = MFXQueryIMPL(hwctx->session, &s->impl); + if (err == MFX_ERR_NONE) + err = MFXQueryVersion(hwctx->session, &s->ver); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); + return AVERROR_UNKNOWN; + } + + if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(s->impl)) { +#if CONFIG_VAAPI + handle_type = MFX_HANDLE_VA_DISPLAY; + device_type = AV_HWDEVICE_TYPE_VAAPI; + pix_fmt = AV_PIX_FMT_VAAPI; + hw_handle_supported = 1; +#endif + } else if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(s->impl)) { +#if CONFIG_D3D11VA + handle_type = MFX_HANDLE_D3D11_DEVICE; + device_type = AV_HWDEVICE_TYPE_D3D11VA; + pix_fmt = AV_PIX_FMT_D3D11; + hw_handle_supported = 1; +#endif + } else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(s->impl)) { +#if CONFIG_DXVA2 + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; + device_type = AV_HWDEVICE_TYPE_DXVA2; + pix_fmt = AV_PIX_FMT_DXVA2_VLD; + hw_handle_supported = 1; +#endif + } + + if (hw_handle_supported) { + err = MFXVideoCORE_GetHandle(hwctx->session, handle_type, &s->handle); + if (err == MFX_ERR_NONE) { + s->handle_type = handle_type; + s->child_device_type = device_type; + s->child_pix_fmt = pix_fmt; + } + } + if (!s->handle) { + av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved " + "from the session\n"); + } + return 0; +} + +static void qsv_frames_uninit(AVHWFramesContext *ctx) +{ + QSVFramesContext *s = ctx->internal->priv; + + if (s->session_download) { + MFXVideoVPP_Close(s->session_download); + MFXClose(s->session_download); + } + s->session_download = NULL; + s->session_download_init = 0; + + if (s->session_upload) { + MFXVideoVPP_Close(s->session_upload); + MFXClose(s->session_upload); + } + s->session_upload = NULL; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_destroy(&s->session_lock); +#endif + + av_freep(&s->mem_ids); +#if QSV_HAVE_OPAQUE + av_freep(&s->surface_ptrs); +#endif + av_freep(&s->surfaces_internal); + av_freep(&s->handle_pairs_internal); + av_frame_unref(&s->realigned_upload_frame); + av_frame_unref(&s->realigned_download_frame); + av_buffer_unref(&s->child_frames_ref); +} + +static void qsv_pool_release_dummy(void *opaque, uint8_t *data) +{ +} + +static AVBufferRef *qsv_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *hwctx = ctx->hwctx; + + if (s->nb_surfaces_used < hwctx->nb_surfaces) { + s->nb_surfaces_used++; + return av_buffer_create((uint8_t*)(s->surfaces_internal + s->nb_surfaces_used - 1), + sizeof(*hwctx->surfaces), qsv_pool_release_dummy, NULL, 0); + } + + return NULL; +} + +static int qsv_init_child_ctx(AVHWFramesContext *ctx) +{ + AVQSVFramesContext *hwctx = ctx->hwctx; + QSVFramesContext *s = ctx->internal->priv; + QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; + + AVBufferRef *child_device_ref = NULL; + AVBufferRef *child_frames_ref = NULL; + + AVHWDeviceContext *child_device_ctx; + AVHWFramesContext *child_frames_ctx; + + int i, ret = 0; + + if (!device_priv->handle) { + av_log(ctx, AV_LOG_ERROR, + "Cannot create a non-opaque internal surface pool without " + "a hardware handle\n"); + return AVERROR(EINVAL); + } + + child_device_ref = av_hwdevice_ctx_alloc(device_priv->child_device_type); + if (!child_device_ref) + return AVERROR(ENOMEM); + child_device_ctx = (AVHWDeviceContext*)child_device_ref->data; + +#if CONFIG_VAAPI + if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) { + AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; + child_device_hwctx->display = (VADisplay)device_priv->handle; + } +#endif +#if CONFIG_D3D11VA + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { + AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx; + ID3D11Device_AddRef((ID3D11Device*)device_priv->handle); + child_device_hwctx->device = (ID3D11Device*)device_priv->handle; + } +#endif +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; + child_device_hwctx->devmgr = (IDirect3DDeviceManager9*)device_priv->handle; + } +#endif + + ret = av_hwdevice_ctx_init(child_device_ref); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a child device context\n"); + goto fail; + } + + child_frames_ref = av_hwframe_ctx_alloc(child_device_ref); + if (!child_frames_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + child_frames_ctx = (AVHWFramesContext*)child_frames_ref->data; + + child_frames_ctx->format = device_priv->child_pix_fmt; + child_frames_ctx->sw_format = ctx->sw_format; + child_frames_ctx->initial_pool_size = ctx->initial_pool_size; + child_frames_ctx->width = FFALIGN(ctx->width, 16); + child_frames_ctx->height = FFALIGN(ctx->height, 16); + +#if CONFIG_D3D11VA + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { + AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + if (hwctx->frame_type == 0) + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + if (hwctx->frame_type & MFX_MEMTYPE_SHARED_RESOURCE) + child_frames_hwctx->MiscFlags = D3D11_RESOURCE_MISC_SHARED; + child_frames_hwctx->BindFlags = qsv_get_d3d11va_bind_flags(hwctx->frame_type); + } +#endif +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + if (hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) + child_frames_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget; + else + child_frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; + } +#endif + + ret = av_hwframe_ctx_init(child_frames_ref); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a child frames context\n"); + goto fail; + } + +#if CONFIG_VAAPI + if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) { + AVVAAPIFramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + for (i = 0; i < ctx->initial_pool_size; i++) { + s->handle_pairs_internal[i].first = child_frames_hwctx->surface_ids + i; + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } +#endif +#if CONFIG_D3D11VA + if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { + AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + for (i = 0; i < ctx->initial_pool_size; i++) { + s->handle_pairs_internal[i].first = (mfxMemId)child_frames_hwctx->texture_infos[i].texture; + if(child_frames_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) { + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + } else { + s->handle_pairs_internal[i].second = (mfxMemId)child_frames_hwctx->texture_infos[i].index; + } + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + if (child_frames_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) { + hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + } else { + hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + } +#endif +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + for (i = 0; i < ctx->initial_pool_size; i++) { + s->handle_pairs_internal[i].first = (mfxMemId)child_frames_hwctx->surfaces[i]; + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + if (child_frames_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + else + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } +#endif + + s->child_frames_ref = child_frames_ref; + child_frames_ref = NULL; + +fail: + av_buffer_unref(&child_device_ref); + av_buffer_unref(&child_frames_ref); + return ret; +} + +static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf) +{ + const AVPixFmtDescriptor *desc; + uint32_t fourcc; + + desc = av_pix_fmt_desc_get(ctx->sw_format); + if (!desc) + return AVERROR(EINVAL); + + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); + if (!fourcc) + return AVERROR(EINVAL); + + surf->Info.BitDepthLuma = desc->comp[0].depth; + surf->Info.BitDepthChroma = desc->comp[0].depth; + surf->Info.Shift = qsv_shift_from_pix_fmt(ctx->sw_format); + + if (desc->log2_chroma_w && desc->log2_chroma_h) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + else if (desc->log2_chroma_w) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; + else + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; + + surf->Info.FourCC = fourcc; + surf->Info.Width = FFALIGN(ctx->width, 16); + surf->Info.CropW = ctx->width; + surf->Info.Height = FFALIGN(ctx->height, 16); + surf->Info.CropH = ctx->height; + surf->Info.FrameRateExtN = 25; + surf->Info.FrameRateExtD = 1; + surf->Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + + return 0; +} + +static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) +{ + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + + int i, ret = 0; + + if (ctx->initial_pool_size <= 0) { + av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n"); + return AVERROR(EINVAL); + } + + s->handle_pairs_internal = av_calloc(ctx->initial_pool_size, + sizeof(*s->handle_pairs_internal)); + if (!s->handle_pairs_internal) + return AVERROR(ENOMEM); + + s->surfaces_internal = av_calloc(ctx->initial_pool_size, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + + for (i = 0; i < ctx->initial_pool_size; i++) { + ret = qsv_init_surface(ctx, &s->surfaces_internal[i]); + if (ret < 0) + return ret; + } + +#if QSV_HAVE_OPAQUE + if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { + ret = qsv_init_child_ctx(ctx); + if (ret < 0) + return ret; + } +#else + ret = qsv_init_child_ctx(ctx); + if (ret < 0) + return ret; +#endif + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1), + ctx, qsv_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + frames_hwctx->surfaces = s->surfaces_internal; + frames_hwctx->nb_surfaces = ctx->initial_pool_size; + + return 0; +} + +static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, + mfxFrameAllocResponse *resp) +{ + AVHWFramesContext *ctx = pthis; + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *hwctx = ctx->hwctx; + mfxFrameInfo *i = &req->Info; + mfxFrameInfo *i1 = &hwctx->surfaces[0].Info; + + if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || + !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || + !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) + return MFX_ERR_UNSUPPORTED; + if (i->Width > i1->Width || i->Height > i1->Height || + i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) { + av_log(ctx, AV_LOG_ERROR, "Mismatching surface properties in an " + "allocation request: %dx%d %d %d vs %dx%d %d %d\n", + i->Width, i->Height, i->FourCC, i->ChromaFormat, + i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat); + return MFX_ERR_UNSUPPORTED; + } + + resp->mids = s->mem_ids; + resp->NumFrameActual = hwctx->nb_surfaces; + + return MFX_ERR_NONE; +} + +static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) +{ + return MFX_ERR_NONE; +} + +static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) +{ + mfxHDLPair *pair_dst = (mfxHDLPair*)hdl; + mfxHDLPair *pair_src = (mfxHDLPair*)mid; + + pair_dst->first = pair_src->first; + + if (pair_src->second != (mfxMemId)MFX_INFINITE) + pair_dst->second = pair_src->second; + return MFX_ERR_NONE; +} + +#if QSV_ONEVPL + +static int qsv_d3d11_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ +#if CONFIG_D3D11VA + mfxStatus sts; + IDXGIAdapter *pDXGIAdapter; + DXGI_ADAPTER_DESC adapterDesc; + IDXGIDevice *pDXGIDevice = NULL; + HRESULT hr; + ID3D11Device *device = handle; + mfxVariant impl_value; + + hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void**)&pDXGIDevice); + if (SUCCEEDED(hr)) { + hr = IDXGIDevice_GetAdapter(pDXGIDevice, &pDXGIAdapter); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDXGIDevice_GetAdapter %d\n", hr); + goto fail; + } + + hr = IDXGIAdapter_GetDesc(pDXGIAdapter, &adapterDesc); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDXGIAdapter_GetDesc %d\n", hr); + goto fail; + } + } else { + av_log(ctx, AV_LOG_ERROR, "Error ID3D11Device_QueryInterface %d\n", hr); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = adapterDesc.DeviceId; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceID property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_PTR; + impl_value.Data.Ptr = &adapterDesc.AdapterLuid; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceLUID property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = 0x0001; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.LUIDDeviceNodeMask", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "LUIDDeviceNodeMask property: %d.\n", sts); + goto fail; + } + + return 0; + +fail: +#endif + return AVERROR_UNKNOWN; +} + +static int qsv_d3d9_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ + int ret = AVERROR_UNKNOWN; +#if CONFIG_DXVA2 + mfxStatus sts; + IDirect3DDeviceManager9* devmgr = handle; + IDirect3DDevice9Ex *device = NULL; + HANDLE device_handle = 0; + IDirect3D9Ex *d3d9ex = NULL; + LUID luid; + D3DDEVICE_CREATION_PARAMETERS params; + HRESULT hr; + mfxVariant impl_value; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(devmgr, &device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error OpenDeviceHandle %d\n", hr); + goto fail; + } + + hr = IDirect3DDeviceManager9_LockDevice(devmgr, device_handle, &device, TRUE); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error LockDevice %d\n", hr); + goto fail; + } + + hr = IDirect3DDevice9Ex_GetCreationParameters(device, ¶ms); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9_GetCreationParameters %d\n", hr); + goto unlock; + } + + hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9ex); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr); + goto unlock; + } + + hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, params.AdapterOrdinal, &luid); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr); + goto unlock; + } + + impl_value.Type = MFX_VARIANT_TYPE_PTR; + impl_value.Data.Ptr = &luid; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceLUID property: %d.\n", sts); + goto unlock; + } + + ret = 0; + +unlock: + IDirect3DDeviceManager9_UnlockDevice(devmgr, device_handle, FALSE); +fail: +#endif + return ret; +} + +static int qsv_va_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ +#if CONFIG_VAAPI +#if VA_CHECK_VERSION(1, 15, 0) + mfxStatus sts; + VADisplay dpy = handle; + VAStatus vas; + VADisplayAttribute attr = { + .type = VADisplayPCIID, + }; + mfxVariant impl_value; + + vas = vaGetDisplayAttributes(dpy, &attr, 1); + if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED) { + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = (attr.value & 0xFFFF); + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceID property: %d.\n", sts); + goto fail; + } + } else { + av_log(ctx, AV_LOG_ERROR, "libva: Failed to get device id from the driver. Please " + "consider to upgrade the driver to support VA-API 1.15.0\n"); + goto fail; + } + + return 0; + +fail: +#else + av_log(ctx, AV_LOG_ERROR, "libva: This version of libva doesn't support retrieving " + "the device information from the driver. Please consider to upgrade libva to " + "support VA-API 1.15.0\n"); +#endif +#endif + return AVERROR_UNKNOWN; +} + +static int qsv_new_mfx_loader(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + void **ploader) +{ + mfxStatus sts; + mfxLoader loader = NULL; + mfxConfig cfg; + mfxVariant impl_value; + + *ploader = NULL; + loader = MFXLoad(); + if (!loader) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX loader\n"); + goto fail; + } + + /* Create configurations for implementation */ + cfg = MFXCreateConfig(loader); + if (!cfg) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX configuration\n"); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ? + MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.Impl", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = pver->Version; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.ApiVersion.Version", + impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = 0x8086; // Intel device only + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.VendorID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "VendorID property: %d.\n", sts); + goto fail; + } + + if (MFX_HANDLE_VA_DISPLAY == handle_type) { + if (handle && qsv_va_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI; + } else if (MFX_HANDLE_D3D9_DEVICE_MANAGER == handle_type) { + if (handle && qsv_d3d9_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9; + } else { + if (handle && qsv_d3d11_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.AccelerationMode", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "AccelerationMode property: %d.\n", sts); + goto fail; + } + + *ploader = loader; + + return 0; + +fail: + if (loader) + MFXUnload(loader); + + return AVERROR_UNKNOWN; +} + +static int qsv_create_mfx_session_from_loader(void *ctx, mfxLoader loader, mfxSession *psession) +{ + mfxStatus sts; + mfxSession session = NULL; + uint32_t impl_idx = 0; + mfxVersion ver; + + while (1) { + /* Enumerate all implementations */ + mfxImplDescription *impl_desc; + + sts = MFXEnumImplementations(loader, impl_idx, + MFX_IMPLCAPS_IMPLDESCSTRUCTURE, + (mfxHDL *)&impl_desc); + /* Failed to find an available implementation */ + if (sts == MFX_ERR_NOT_FOUND) + break; + else if (sts != MFX_ERR_NONE) { + impl_idx++; + continue; + } + + sts = MFXCreateSession(loader, impl_idx, &session); + MFXDispReleaseImplDescription(loader, impl_desc); + if (sts == MFX_ERR_NONE) + break; + + impl_idx++; + } + + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX session: %d.\n", sts); + goto fail; + } + + sts = MFXQueryVersion(session, &ver); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying a MFX session: %d.\n", sts); + goto fail; + } + + av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation " + "version is %d.%d\n", ver.Major, ver.Minor); + + *psession = session; + + return 0; + +fail: + if (session) + MFXClose(session); + + return AVERROR_UNKNOWN; +} + +static int qsv_create_mfx_session(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + mfxSession *psession, + void **ploader) +{ + mfxLoader loader = NULL; + + av_log(ctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session, API version is " + "%d.%d, the required implementation version is %d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor); + + if (handle_type != MFX_HANDLE_VA_DISPLAY && + handle_type != MFX_HANDLE_D3D9_DEVICE_MANAGER && + handle_type != MFX_HANDLE_D3D11_DEVICE) { + av_log(ctx, AV_LOG_ERROR, + "Invalid MFX device handle type\n"); + return AVERROR(EXDEV); + } + + *psession = NULL; + + if (!*ploader) { + if (qsv_new_mfx_loader(ctx, handle, handle_type, implementation, pver, (void **)&loader)) + goto fail; + + av_assert0(loader); + } else + loader = *ploader; // Use the input mfxLoader to create mfx session + + if (qsv_create_mfx_session_from_loader(ctx, loader, psession)) + goto fail; + + if (!*ploader) + *ploader = loader; + + return 0; + +fail: + if (!*ploader && loader) + MFXUnload(loader); + + return AVERROR_UNKNOWN; +} + +#else + +static int qsv_create_mfx_session(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + mfxSession *psession, + void **ploader) +{ + mfxVersion ver; + mfxStatus sts; + mfxSession session = NULL; + + av_log(ctx, AV_LOG_VERBOSE, + "Use Intel(R) Media SDK to create MFX session, API version is " + "%d.%d, the required implementation version is %d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor); + + *ploader = NULL; + *psession = NULL; + ver = *pver; + sts = MFXInit(implementation, &ver, &session); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " + "%d.\n", sts); + goto fail; + } + + sts = MFXQueryVersion(session, &ver); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: " + "%d.\n", sts); + goto fail; + } + + av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation " + "version is %d.%d\n", ver.Major, ver.Minor); + + MFXClose(session); + + sts = MFXInit(implementation, &ver, &session); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " + "%d.\n", sts); + goto fail; + } + + *psession = session; + + return 0; + +fail: + if (session) + MFXClose(session); + + return AVERROR_UNKNOWN; +} + +#endif + +static int qsv_init_internal_session(AVHWFramesContext *ctx, + mfxSession *session, int upload) +{ + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; + int opaque = 0; + + mfxFrameAllocator frame_allocator = { + .pthis = ctx, + .Alloc = frame_alloc, + .Lock = frame_lock, + .Unlock = frame_unlock, + .GetHDL = frame_get_hdl, + .Free = frame_free, + }; + + mfxVideoParam par; + mfxStatus err; + int ret = AVERROR_UNKNOWN; + AVQSVDeviceContext *hwctx = ctx->device_ctx->hwctx; + /* hwctx->loader is non-NULL for oneVPL user and NULL for non-oneVPL user */ + void **loader = &hwctx->loader; + +#if QSV_HAVE_OPAQUE + QSVFramesContext *s = ctx->internal->priv; + opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); +#endif + + ret = qsv_create_mfx_session(ctx, device_priv->handle, device_priv->handle_type, + device_priv->impl, &device_priv->ver, session, loader); + if (ret) + goto fail; + + if (device_priv->handle) { + err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type, + device_priv->handle); + if (err != MFX_ERR_NONE) { + ret = AVERROR_UNKNOWN; + goto fail; + } + } + + if (!opaque) { + err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator); + if (err != MFX_ERR_NONE) { + ret = AVERROR_UNKNOWN; + goto fail; + } + } + + memset(&par, 0, sizeof(par)); + + if (!opaque) { + par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY : + MFX_IOPATTERN_IN_VIDEO_MEMORY; + } +#if QSV_HAVE_OPAQUE + else { + par.ExtParam = s->ext_buffers; + par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); + par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY : + MFX_IOPATTERN_IN_OPAQUE_MEMORY; + } +#endif + + par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY : + MFX_IOPATTERN_OUT_SYSTEM_MEMORY; + par.AsyncDepth = 1; + + par.vpp.In = frames_hwctx->surfaces[0].Info; + + /* Apparently VPP requires the frame rate to be set to some value, otherwise + * init will fail (probably for the framerate conversion filter). Since we + * are only doing data upload/download here, we just invent an arbitrary + * value */ + par.vpp.In.FrameRateExtN = 25; + par.vpp.In.FrameRateExtD = 1; + par.vpp.Out = par.vpp.In; + + err = MFXVideoVPP_Init(*session, &par); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session." + "Surface upload/download will not be possible\n"); + + ret = AVERROR_UNKNOWN; + goto fail; + } + + return 0; + +fail: + if (*session) + MFXClose(*session); + + *session = NULL; + + return ret; +} + +static int qsv_frames_init(AVHWFramesContext *ctx) +{ + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + + int opaque = 0; + + uint32_t fourcc; + int i, ret; + +#if QSV_HAVE_OPAQUE + opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); +#endif + + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); + if (!fourcc) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); + return AVERROR(ENOSYS); + } + + if (!ctx->pool) { + ret = qsv_init_pool(ctx, fourcc); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n"); + return ret; + } + } + + if (!opaque) { + s->mem_ids = av_calloc(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids)); + if (!s->mem_ids) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_hwctx->nb_surfaces; i++) + s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId; + } +#if QSV_HAVE_OPAQUE + else { + s->surface_ptrs = av_calloc(frames_hwctx->nb_surfaces, + sizeof(*s->surface_ptrs)); + if (!s->surface_ptrs) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_hwctx->nb_surfaces; i++) + s->surface_ptrs[i] = frames_hwctx->surfaces + i; + + s->opaque_alloc.In.Surfaces = s->surface_ptrs; + s->opaque_alloc.In.NumSurface = frames_hwctx->nb_surfaces; + s->opaque_alloc.In.Type = frames_hwctx->frame_type; + + s->opaque_alloc.Out = s->opaque_alloc.In; + + s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; + s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); + + s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; + } +#endif + + s->session_download = NULL; + s->session_upload = NULL; + + s->session_download_init = 0; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_init(&s->session_lock, NULL); +#endif + + return 0; +} + +static int qsv_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_QSV; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int qsv_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int qsv_frames_derive_from(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags) +{ + AVQSVFramesContext *src_hwctx = src_ctx->hwctx; + int i; + + switch (dst_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIFramesContext *dst_hwctx = dst_ctx->hwctx; + dst_hwctx->surface_ids = av_calloc(src_hwctx->nb_surfaces, + sizeof(*dst_hwctx->surface_ids)); + if (!dst_hwctx->surface_ids) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId; + dst_hwctx->surface_ids[i] = *(VASurfaceID*)pair->first; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + } + break; +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + { + D3D11_TEXTURE2D_DESC texDesc; + dst_ctx->initial_pool_size = src_ctx->initial_pool_size; + AVD3D11VAFramesContext *dst_hwctx = dst_ctx->hwctx; + dst_hwctx->texture_infos = av_calloc(src_hwctx->nb_surfaces, + sizeof(*dst_hwctx->texture_infos)); + if (!dst_hwctx->texture_infos) + return AVERROR(ENOMEM); + if (src_hwctx->frame_type & MFX_MEMTYPE_SHARED_RESOURCE) + dst_hwctx->MiscFlags = D3D11_RESOURCE_MISC_SHARED; + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId; + dst_hwctx->texture_infos[i].texture = (ID3D11Texture2D*)pair->first; + dst_hwctx->texture_infos[i].index = pair->second == (mfxMemId)MFX_INFINITE ? (intptr_t)0 : (intptr_t)pair->second; + } + ID3D11Texture2D_GetDesc(dst_hwctx->texture_infos[0].texture, &texDesc); + dst_hwctx->BindFlags = texDesc.BindFlags; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2FramesContext *dst_hwctx = dst_ctx->hwctx; + dst_hwctx->surfaces = av_calloc(src_hwctx->nb_surfaces, + sizeof(*dst_hwctx->surfaces)); + if (!dst_hwctx->surfaces) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId; + dst_hwctx->surfaces[i] = (IDirect3DSurface9*)pair->first; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + if (src_hwctx->frame_type == MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) + dst_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; + else + dst_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget; + } + break; +#endif + default: + return AVERROR(ENOSYS); + } + + return 0; +} + +static int qsv_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3]; + AVHWFramesContext *child_frames_ctx; + const AVPixFmtDescriptor *desc; + uint8_t *child_data; + AVFrame *dummy; + int ret = 0; + + if (!s->child_frames_ref) + return AVERROR(ENOSYS); + child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + + switch (child_frames_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId; + /* pair->first is *VASurfaceID while data[3] in vaapi frame is VASurfaceID, so + * we need this casting for vaapi. + * Add intptr_t to force cast from VASurfaceID(uint) type to pointer(long) type + * to avoid compile warning */ + child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)pair->first; + break; + } +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + { + mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId; + child_data = pair->first; + break; + } +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId; + child_data = pair->first; + break; + } +#endif + default: + return AVERROR(ENOSYS); + } + + if (dst->format == child_frames_ctx->format) { + ret = ff_hwframe_map_create(s->child_frames_ref, + dst, src, NULL, NULL); + if (ret < 0) + return ret; + + dst->width = src->width; + dst->height = src->height; + + if (child_frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { + mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId; + dst->data[0] = pair->first; + dst->data[1] = pair->second == (mfxMemId)MFX_INFINITE ? (uint8_t *)0 : pair->second; + } else { + dst->data[3] = child_data; + } + + return 0; + } + + desc = av_pix_fmt_desc_get(dst->format); + if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // This only supports mapping to software. + return AVERROR(ENOSYS); + } + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->buf[0] = av_buffer_ref(src->buf[0]); + dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref); + if (!dummy->buf[0] || !dummy->hw_frames_ctx) + goto fail; + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + + if (child_frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) { + mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId; + dummy->data[0] = pair->first; + dummy->data[1] = pair->second == (mfxMemId)MFX_INFINITE ? (uint8_t *)0 : pair->second; + } else { + dummy->data[3] = child_data; + } + + ret = av_hwframe_map(dst, dummy, flags); + +fail: + av_frame_free(&dummy); + + return ret; +} + +static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + AVHWFramesContext *child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + int download = !!src->hw_frames_ctx; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)(download ? src->data[3] : dst->data[3]); + + AVFrame *dummy; + int ret; + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + dummy->buf[0] = download ? src->buf[0] : dst->buf[0]; + dummy->data[3] = surf->Data.MemId; + dummy->hw_frames_ctx = s->child_frames_ref; + + ret = download ? av_hwframe_transfer_data(dst, dummy, 0) : + av_hwframe_transfer_data(dummy, src, 0); + + dummy->buf[0] = NULL; + dummy->data[3] = NULL; + dummy->hw_frames_ctx = NULL; + + av_frame_free(&dummy); + + return ret; +} + +static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface) +{ + switch (frame->format) { + case AV_PIX_FMT_NV12: + case AV_PIX_FMT_P010: + case AV_PIX_FMT_P012: + surface->Data.Y = frame->data[0]; + surface->Data.UV = frame->data[1]; + break; + + case AV_PIX_FMT_YUV420P: + surface->Data.Y = frame->data[0]; + surface->Data.U = frame->data[1]; + surface->Data.V = frame->data[2]; + break; + + case AV_PIX_FMT_BGRA: + surface->Data.B = frame->data[0]; + surface->Data.G = frame->data[0] + 1; + surface->Data.R = frame->data[0] + 2; + surface->Data.A = frame->data[0] + 3; + break; +#if CONFIG_VAAPI + case AV_PIX_FMT_YUYV422: + surface->Data.Y = frame->data[0]; + surface->Data.U = frame->data[0] + 1; + surface->Data.V = frame->data[0] + 3; + break; + + case AV_PIX_FMT_Y210: + case AV_PIX_FMT_Y212: + surface->Data.Y16 = (mfxU16 *)frame->data[0]; + surface->Data.U16 = (mfxU16 *)frame->data[0] + 1; + surface->Data.V16 = (mfxU16 *)frame->data[0] + 3; + break; + case AV_PIX_FMT_VUYX: + surface->Data.V = frame->data[0]; + surface->Data.U = frame->data[0] + 1; + surface->Data.Y = frame->data[0] + 2; + // Only set Data.A to a valid address, the SDK doesn't + // use the value from the frame. + surface->Data.A = frame->data[0] + 3; + break; + case AV_PIX_FMT_XV30: + surface->Data.U = frame->data[0]; + break; + case AV_PIX_FMT_XV36: + surface->Data.U = frame->data[0]; + surface->Data.Y = frame->data[0] + 2; + surface->Data.V = frame->data[0] + 4; + // Only set Data.A to a valid address, the SDK doesn't + // use the value from the frame. + surface->Data.A = frame->data[0] + 6; + break; +#endif + default: + return MFX_ERR_UNSUPPORTED; + } + surface->Data.Pitch = frame->linesize[0]; + surface->Data.TimeStamp = frame->pts; + + return 0; +} + +static int qsv_internal_session_check_init(AVHWFramesContext *ctx, int upload) +{ + QSVFramesContext *s = ctx->internal->priv; + atomic_int *inited = upload ? &s->session_upload_init : &s->session_download_init; + mfxSession *session = upload ? &s->session_upload : &s->session_download; + int ret = 0; + + if (atomic_load(inited)) + return 0; + +#if HAVE_PTHREADS + pthread_mutex_lock(&s->session_lock); +#endif + + if (!atomic_load(inited)) { + ret = qsv_init_internal_session(ctx, session, upload); + atomic_store(inited, 1); + } + +#if HAVE_PTHREADS + pthread_mutex_unlock(&s->session_lock); +#endif + + return ret; +} + +static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 out = {{ 0 }}; + mfxFrameSurface1 *in = (mfxFrameSurface1*)src->data[3]; + + mfxSyncPoint sync = NULL; + mfxStatus err; + int ret = 0; + /* download to temp frame if the output is not padded as libmfx requires */ + AVFrame *tmp_frame = &s->realigned_download_frame; + AVFrame *dst_frame; + int realigned = 0; + + ret = qsv_internal_session_check_init(ctx, 0); + if (ret < 0) + return ret; + + /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 16. + * Height must be a multiple of 16 for progressive frame sequence and a + * multiple of 32 otherwise.", so allign all frames to 16 before downloading. */ + if (dst->height & 15 || dst->linesize[0] & 15) { + realigned = 1; + if (tmp_frame->format != dst->format || + tmp_frame->width != FFALIGN(dst->linesize[0], 16) || + tmp_frame->height != FFALIGN(dst->height, 16)) { + av_frame_unref(tmp_frame); + + tmp_frame->format = dst->format; + tmp_frame->width = FFALIGN(dst->linesize[0], 16); + tmp_frame->height = FFALIGN(dst->height, 16); + ret = av_frame_get_buffer(tmp_frame, 0); + if (ret < 0) + return ret; + } + } + + dst_frame = realigned ? tmp_frame : dst; + + if (!s->session_download) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst_frame, src); + + av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n"); + return AVERROR(ENOSYS); + } + + out.Info = in->Info; + map_frame_to_surface(dst_frame, &out); + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err < 0 || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error downloading the surface\n"); + return AVERROR_UNKNOWN; + } + + do { + err = MFXVideoCORE_SyncOperation(s->session_download, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); + return AVERROR_UNKNOWN; + } + + if (realigned) { + tmp_frame->width = dst->width; + tmp_frame->height = dst->height; + ret = av_frame_copy(dst, tmp_frame); + tmp_frame->width = FFALIGN(dst->linesize[0], 16); + tmp_frame->height = FFALIGN(dst->height, 16); + if (ret < 0) + return ret; + } + + return 0; +} + +static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 in = {{ 0 }}; + mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3]; + mfxFrameInfo tmp_info; + + mfxSyncPoint sync = NULL; + mfxStatus err; + int ret = 0; + /* make a copy if the input is not padded as libmfx requires */ + AVFrame *tmp_frame = &s->realigned_upload_frame; + const AVFrame *src_frame; + int realigned = 0; + + ret = qsv_internal_session_check_init(ctx, 1); + if (ret < 0) + return ret; + + /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 16. + * Height must be a multiple of 16 for progressive frame sequence and a + * multiple of 32 otherwise.", so allign all frames to 16 before uploading. */ + if (src->height & 15 || src->linesize[0] & 15) { + realigned = 1; + if (tmp_frame->format != src->format || + tmp_frame->width != FFALIGN(src->width, 16) || + tmp_frame->height != FFALIGN(src->height, 16)) { + av_frame_unref(tmp_frame); + + tmp_frame->format = src->format; + tmp_frame->width = FFALIGN(src->width, 16); + tmp_frame->height = FFALIGN(src->height, 16); + ret = av_frame_get_buffer(tmp_frame, 0); + if (ret < 0) + return ret; + } + ret = av_frame_copy(tmp_frame, src); + if (ret < 0) { + av_frame_unref(tmp_frame); + return ret; + } + ret = qsv_fill_border(tmp_frame, src); + if (ret < 0) { + av_frame_unref(tmp_frame); + return ret; + } + + tmp_info = out->Info; + out->Info.CropW = FFMIN(out->Info.Width, tmp_frame->width); + out->Info.CropH = FFMIN(out->Info.Height, tmp_frame->height); + } + + src_frame = realigned ? tmp_frame : src; + + if (!s->session_upload) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst, src_frame); + + av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n"); + return AVERROR(ENOSYS); + } + + in.Info = out->Info; + map_frame_to_surface(src_frame, &in); + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session_upload, &in, out, NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err < 0 || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error uploading the surface\n"); + return AVERROR_UNKNOWN; + } + + do { + err = MFXVideoCORE_SyncOperation(s->session_upload, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation\n"); + return AVERROR_UNKNOWN; + } + + if (realigned) { + out->Info.CropW = tmp_info.CropW; + out->Info.CropH = tmp_info.CropH; + } + + return 0; +} + +static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags) +{ + QSVFramesContext *s = dst_ctx->internal->priv; + AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx; + int i; + + if (src_ctx->initial_pool_size == 0) { + av_log(dst_ctx, AV_LOG_ERROR, "Only fixed-size pools can be " + "mapped to QSV frames.\n"); + return AVERROR(EINVAL); + } + + switch (src_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx; + s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size, + sizeof(*s->handle_pairs_internal)); + if (!s->handle_pairs_internal) + return AVERROR(ENOMEM); + s->surfaces_internal = av_calloc(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->handle_pairs_internal[i].first = src_hwctx->surface_ids + i; + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + { + AVD3D11VAFramesContext *src_hwctx = src_ctx->hwctx; + s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size, + sizeof(*s->handle_pairs_internal)); + if (!s->handle_pairs_internal) + return AVERROR(ENOMEM); + s->surfaces_internal = av_calloc(src_ctx->initial_pool_size, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_ctx->initial_pool_size; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->handle_pairs_internal[i].first = (mfxMemId)src_hwctx->texture_infos[i].texture; + if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) { + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + } else { + s->handle_pairs_internal[i].second = (mfxMemId)src_hwctx->texture_infos[i].index; + } + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + dst_hwctx->nb_surfaces = src_ctx->initial_pool_size; + if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) { + dst_hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + } else { + dst_hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx; + s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size, + sizeof(*s->handle_pairs_internal)); + if (!s->handle_pairs_internal) + return AVERROR(ENOMEM); + s->surfaces_internal = av_calloc(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->handle_pairs_internal[i].first = (mfxMemId)src_hwctx->surfaces[i]; + s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE; + s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i]; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + else + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif + default: + return AVERROR(ENOSYS); + } + + dst_hwctx->surfaces = s->surfaces_internal; + + return 0; +} + +static int qsv_map_to(AVHWFramesContext *dst_ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + AVQSVFramesContext *hwctx = dst_ctx->hwctx; + int i, err, index = -1; + + for (i = 0; i < hwctx->nb_surfaces && index < 0; i++) { + switch(src->format) { +#if CONFIG_VAAPI + case AV_PIX_FMT_VAAPI: + { + mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId; + if (*(VASurfaceID*)pair->first == (VASurfaceID)src->data[3]) { + index = i; + break; + } + } +#endif +#if CONFIG_D3D11VA + case AV_PIX_FMT_D3D11: + { + mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId; + if (pair->first == src->data[0] + && (pair->second == src->data[1] + || (pair->second == (mfxMemId)MFX_INFINITE && src->data[1] == (uint8_t *)0))) { + index = i; + break; + } + } +#endif +#if CONFIG_DXVA2 + case AV_PIX_FMT_DXVA2_VLD: + { + mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId; + if (pair->first == src->data[3]) { + index = i; + break; + } + } +#endif + } + } + if (index < 0) { + av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which " + "is not in the mapped frames context.\n"); + return AVERROR(EINVAL); + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, + dst, src, NULL, NULL); + if (err) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)&hwctx->surfaces[index]; + + return 0; +} + +static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_pixel_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) + constraints->valid_sw_formats[i] = supported_pixel_formats[i].pix_fmt; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_pixel_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_QSV; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void qsv_device_free(AVHWDeviceContext *ctx) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + QSVDevicePriv *priv = ctx->user_opaque; + + if (hwctx->session) + MFXClose(hwctx->session); + + if (hwctx->loader) + MFXUnload(hwctx->loader); + av_buffer_unref(&priv->child_device_ctx); + av_freep(&priv); +} + +static mfxIMPL choose_implementation(const char *device, enum AVHWDeviceType child_device_type) +{ + static const struct { + const char *name; + mfxIMPL impl; + } impl_map[] = { + { "auto", MFX_IMPL_AUTO }, + { "sw", MFX_IMPL_SOFTWARE }, + { "hw", MFX_IMPL_HARDWARE }, + { "auto_any", MFX_IMPL_AUTO_ANY }, + { "hw_any", MFX_IMPL_HARDWARE_ANY }, + { "hw2", MFX_IMPL_HARDWARE2 }, + { "hw3", MFX_IMPL_HARDWARE3 }, + { "hw4", MFX_IMPL_HARDWARE4 }, + }; + + mfxIMPL impl = MFX_IMPL_AUTO_ANY; + int i; + + if (device) { + for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++) + if (!strcmp(device, impl_map[i].name)) { + impl = impl_map[i].impl; + break; + } + if (i == FF_ARRAY_ELEMS(impl_map)) + impl = strtol(device, NULL, 0); + } + + if (impl != MFX_IMPL_SOFTWARE) { + if (child_device_type == AV_HWDEVICE_TYPE_D3D11VA) + impl |= MFX_IMPL_VIA_D3D11; + else if (child_device_type == AV_HWDEVICE_TYPE_DXVA2) + impl |= MFX_IMPL_VIA_D3D9; + } + + return impl; +} + +static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, + mfxIMPL implementation, + AVHWDeviceContext *child_device_ctx, + int flags) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + + mfxVersion ver = { { 3, 1 } }; + mfxHDL handle; + mfxHandleType handle_type; + mfxStatus err; + int ret; + + switch (child_device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; + handle_type = MFX_HANDLE_VA_DISPLAY; + handle = (mfxHDL)child_device_hwctx->display; + } + break; +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + { + AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx; + handle_type = MFX_HANDLE_D3D11_DEVICE; + handle = (mfxHDL)child_device_hwctx->device; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; + handle = (mfxHDL)child_device_hwctx->devmgr; + } + break; +#endif + default: + ret = AVERROR(ENOSYS); + goto fail; + } + + ret = qsv_create_mfx_session(ctx, handle, handle_type, implementation, &ver, + &hwctx->session, &hwctx->loader); + if (ret) + goto fail; + + err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: " + "%d\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + return 0; + +fail: + if (hwctx->session) + MFXClose(hwctx->session); + + if (hwctx->loader) + MFXUnload(hwctx->loader); + + hwctx->session = NULL; + hwctx->loader = NULL; + return ret; +} + +static int qsv_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *child_device_ctx, + AVDictionary *opts, int flags) +{ + mfxIMPL impl; + impl = choose_implementation("hw_any", child_device_ctx->type); + return qsv_device_derive_from_child(ctx, impl, + child_device_ctx, flags); +} + +static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + QSVDevicePriv *priv; + enum AVHWDeviceType child_device_type; + AVHWDeviceContext *child_device; + AVDictionary *child_device_opts; + AVDictionaryEntry *e; + + mfxIMPL impl; + int ret; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = qsv_device_free; + + e = av_dict_get(opts, "child_device_type", NULL, 0); + if (e) { + child_device_type = av_hwdevice_find_type_by_name(e->value); + if (child_device_type == AV_HWDEVICE_TYPE_NONE) { + av_log(ctx, AV_LOG_ERROR, "Unknown child device type " + "\"%s\".\n", e->value); + return AVERROR(EINVAL); + } + } else if (CONFIG_VAAPI) { + child_device_type = AV_HWDEVICE_TYPE_VAAPI; +#if QSV_ONEVPL + } else if (CONFIG_D3D11VA) { // Use D3D11 by default if d3d11va is enabled + av_log(ctx, AV_LOG_VERBOSE, + "Defaulting child_device_type to AV_HWDEVICE_TYPE_D3D11VA for oneVPL." + "Please explicitly set child device type via \"-init_hw_device\" " + "option if needed.\n"); + child_device_type = AV_HWDEVICE_TYPE_D3D11VA; + } else if (CONFIG_DXVA2) { + child_device_type = AV_HWDEVICE_TYPE_DXVA2; +#else + } else if (CONFIG_DXVA2) { + av_log(NULL, AV_LOG_WARNING, + "WARNING: defaulting child_device_type to AV_HWDEVICE_TYPE_DXVA2 for compatibility " + "with old commandlines. This behaviour will be removed " + "in the future. Please explicitly set device type via \"-init_hw_device\" option.\n"); + child_device_type = AV_HWDEVICE_TYPE_DXVA2; + } else if (CONFIG_D3D11VA) { + child_device_type = AV_HWDEVICE_TYPE_D3D11VA; +#endif + } else { + av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n"); + return AVERROR(ENOSYS); + } + + child_device_opts = NULL; + switch (child_device_type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + // libmfx does not actually implement VAAPI properly, rather it + // depends on the specific behaviour of a matching iHD driver when + // used on recent Intel hardware. Set options to the VAAPI device + // creation so that we should pick a usable setup by default if + // possible, even when multiple devices and drivers are available. + av_dict_set(&child_device_opts, "kernel_driver", "i915", 0); + av_dict_set(&child_device_opts, "driver", "iHD", 0); + } + break; +#endif +#if CONFIG_D3D11VA + case AV_HWDEVICE_TYPE_D3D11VA: + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: +#if QSV_ONEVPL + { + av_log(ctx, AV_LOG_VERBOSE, + "d3d11va is not available or child device type is set to dxva2 " + "explicitly for oneVPL.\n"); + } +#endif + break; +#endif + default: + { + av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n"); + return AVERROR(ENOSYS); + } + break; + } + + e = av_dict_get(opts, "child_device", NULL, 0); + ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type, + e ? e->value : NULL, child_device_opts, 0); + + av_dict_free(&child_device_opts); + if (ret < 0) + return ret; + + child_device = (AVHWDeviceContext*)priv->child_device_ctx->data; + + impl = choose_implementation(device, child_device_type); + + return qsv_device_derive_from_child(ctx, impl, child_device, 0); +} + +const HWContextType ff_hwcontext_type_qsv = { + .type = AV_HWDEVICE_TYPE_QSV, + .name = "QSV", + + .device_hwctx_size = sizeof(AVQSVDeviceContext), + .device_priv_size = sizeof(QSVDeviceContext), + .frames_hwctx_size = sizeof(AVQSVFramesContext), + .frames_priv_size = sizeof(QSVFramesContext), + + .device_create = qsv_device_create, + .device_derive = qsv_device_derive, + .device_init = qsv_device_init, + .frames_get_constraints = qsv_frames_get_constraints, + .frames_init = qsv_frames_init, + .frames_uninit = qsv_frames_uninit, + .frames_get_buffer = qsv_get_buffer, + .transfer_get_formats = qsv_transfer_get_formats, + .transfer_data_to = qsv_transfer_data_to, + .transfer_data_from = qsv_transfer_data_from, + .map_to = qsv_map_to, + .map_from = qsv_map_from, + .frames_derive_to = qsv_frames_derive_to, + .frames_derive_from = qsv_frames_derive_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.h new file mode 100644 index 00000000..e2dba8ad --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_qsv.h @@ -0,0 +1,64 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_QSV_H +#define AVUTIL_HWCONTEXT_QSV_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_QSV. + * + * This API does not support dynamic frame pools. AVHWFramesContext.pool must + * contain AVBufferRefs whose data pointer points to an mfxFrameSurface1 struct. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVQSVDeviceContext { + mfxSession session; + /** + * The mfxLoader handle used for mfxSession creation + * + * This field is only available for oneVPL user. For non-oneVPL user, this + * field must be set to NULL. + * + * Filled by the user before calling av_hwdevice_ctx_init() and should be + * cast to mfxLoader handle. Deallocating the AVHWDeviceContext will always + * release this interface. + */ + void *loader; +} AVQSVDeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVQSVFramesContext { + mfxFrameSurface1 *surfaces; + int nb_surfaces; + + /** + * A combination of MFX_MEMTYPE_* describing the frame pool. + */ + int frame_type; +} AVQSVFramesContext; + +#endif /* AVUTIL_HWCONTEXT_QSV_H */ + diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_stub.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_stub.c new file mode 100644 index 00000000..13a9a748 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_stub.c @@ -0,0 +1,41 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if !CONFIG_VULKAN +#include +#include "pixfmt.h" + +// ISO C forbids forward references to enum types, this is the next best thing +// since enum values are never really used. +typedef enum { NEVER_USED } VkFormat; +typedef struct AVVkFrame AVVkFrame; +const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p); +AVVkFrame *av_vk_frame_alloc(void); + +const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p) +{ + return NULL; +} + +AVVkFrame *av_vk_frame_alloc(void) +{ + return NULL; +} +#endif /* CONFIG_VULKAN */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.c new file mode 100644 index 00000000..938bd544 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.c @@ -0,0 +1,1937 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if HAVE_VAAPI_X11 +# include +#endif +#if HAVE_VAAPI_DRM +# include +#endif + +#if CONFIG_LIBDRM +# include +# include +# include +# ifndef DRM_FORMAT_MOD_INVALID +# define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +# endif +#endif + +#include +#if HAVE_UNISTD_H +# include +#endif + + +#include "avassert.h" +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_drm.h" +#include "hwcontext_internal.h" +#include "hwcontext_vaapi.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" + + +typedef struct VAAPIDevicePriv { +#if HAVE_VAAPI_X11 + Display *x11_display; +#endif + + int drm_fd; +} VAAPIDevicePriv; + +typedef struct VAAPISurfaceFormat { + enum AVPixelFormat pix_fmt; + VAImageFormat image_format; +} VAAPISurfaceFormat; + +typedef struct VAAPIDeviceContext { + // Surface formats which can be used with this device. + VAAPISurfaceFormat *formats; + int nb_formats; +} VAAPIDeviceContext; + +typedef struct VAAPIFramesContext { + // Surface attributes set at create time. + VASurfaceAttrib *attributes; + int nb_attributes; + // RT format of the underlying surface (Intel driver ignores this anyway). + unsigned int rt_format; + // Whether vaDeriveImage works. + int derive_works; + // Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for + // surface imports. + int prime_2_import_unsupported; +} VAAPIFramesContext; + +typedef struct VAAPIMapping { + // Handle to the derived or copied image which is mapped. + VAImage image; + // The mapping flags actually used. + int flags; +} VAAPIMapping; + +typedef struct VAAPIFormat { + unsigned int fourcc; + unsigned int rt_format; + enum AVPixelFormat pix_fmt; + int chroma_planes_swapped; +} VAAPIFormatDescriptor; + +#define MAP(va, rt, av, swap_uv) { \ + VA_FOURCC_ ## va, \ + VA_RT_FORMAT_ ## rt, \ + AV_PIX_FMT_ ## av, \ + swap_uv, \ + } +// The map fourcc <-> pix_fmt isn't bijective because of the annoying U/V +// plane swap cases. The frame handling below tries to hide these. +static const VAAPIFormatDescriptor vaapi_format_map[] = { + MAP(NV12, YUV420, NV12, 0), +#ifdef VA_FOURCC_I420 + MAP(I420, YUV420, YUV420P, 0), +#endif + MAP(YV12, YUV420, YUV420P, 1), + MAP(IYUV, YUV420, YUV420P, 0), + MAP(422H, YUV422, YUV422P, 0), +#ifdef VA_FOURCC_YV16 + MAP(YV16, YUV422, YUV422P, 1), +#endif + MAP(UYVY, YUV422, UYVY422, 0), + MAP(YUY2, YUV422, YUYV422, 0), +#ifdef VA_FOURCC_Y210 + MAP(Y210, YUV422_10, Y210, 0), +#endif +#ifdef VA_FOURCC_Y212 + MAP(Y212, YUV422_12, Y212, 0), +#endif + MAP(411P, YUV411, YUV411P, 0), + MAP(422V, YUV422, YUV440P, 0), + MAP(444P, YUV444, YUV444P, 0), +#ifdef VA_FOURCC_XYUV + MAP(XYUV, YUV444, VUYX, 0), +#endif + MAP(Y800, YUV400, GRAY8, 0), +#ifdef VA_FOURCC_P010 + MAP(P010, YUV420_10BPP, P010, 0), +#endif +#ifdef VA_FOURCC_P012 + MAP(P012, YUV420_12, P012, 0), +#endif + MAP(BGRA, RGB32, BGRA, 0), + MAP(BGRX, RGB32, BGR0, 0), + MAP(RGBA, RGB32, RGBA, 0), + MAP(RGBX, RGB32, RGB0, 0), +#ifdef VA_FOURCC_ABGR + MAP(ABGR, RGB32, ABGR, 0), + MAP(XBGR, RGB32, 0BGR, 0), +#endif + MAP(ARGB, RGB32, ARGB, 0), + MAP(XRGB, RGB32, 0RGB, 0), +#ifdef VA_FOURCC_X2R10G10B10 + MAP(X2R10G10B10, RGB32_10, X2RGB10, 0), +#endif +#ifdef VA_FOURCC_Y410 + // libva doesn't include a fourcc for XV30 and the driver only declares + // support for Y410, so we must fudge the mapping here. + MAP(Y410, YUV444_10, XV30, 0), +#endif +#ifdef VA_FOURCC_Y412 + // libva doesn't include a fourcc for XV36 and the driver only declares + // support for Y412, so we must fudge the mapping here. + MAP(Y412, YUV444_12, XV36, 0), +#endif +}; +#undef MAP + +static const VAAPIFormatDescriptor * + vaapi_format_from_fourcc(unsigned int fourcc) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) + if (vaapi_format_map[i].fourcc == fourcc) + return &vaapi_format_map[i]; + return NULL; +} + +static const VAAPIFormatDescriptor * + vaapi_format_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) + if (vaapi_format_map[i].pix_fmt == pix_fmt) + return &vaapi_format_map[i]; + return NULL; +} + +static enum AVPixelFormat vaapi_pix_fmt_from_fourcc(unsigned int fourcc) +{ + const VAAPIFormatDescriptor *desc; + desc = vaapi_format_from_fourcc(fourcc); + if (desc) + return desc->pix_fmt; + else + return AV_PIX_FMT_NONE; +} + +static int vaapi_get_image_format(AVHWDeviceContext *hwdev, + enum AVPixelFormat pix_fmt, + VAImageFormat **image_format) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + int i; + + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == pix_fmt) { + if (image_format) + *image_format = &ctx->formats[i].image_format; + return 0; + } + } + return AVERROR(EINVAL); +} + +static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVVAAPIDeviceContext *hwctx = hwdev->hwctx; + const AVVAAPIHWConfig *config = hwconfig; + VAAPIDeviceContext *ctx = hwdev->internal->priv; + VASurfaceAttrib *attr_list = NULL; + VAStatus vas; + enum AVPixelFormat pix_fmt; + unsigned int fourcc; + int err, i, j, attr_count, pix_fmt_count; + + if (config && + !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { + attr_count = 0; + vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, + 0, &attr_count); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + + attr_list = av_malloc(attr_count * sizeof(*attr_list)); + if (!attr_list) { + err = AVERROR(ENOMEM); + goto fail; + } + + vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, + attr_list, &attr_count); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + + pix_fmt_count = 0; + for (i = 0; i < attr_count; i++) { + switch (attr_list[i].type) { + case VASurfaceAttribPixelFormat: + fourcc = attr_list[i].value.value.i; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + if (pix_fmt != AV_PIX_FMT_NONE) { + ++pix_fmt_count; + } else { + // Something unsupported - ignore. + } + break; + case VASurfaceAttribMinWidth: + constraints->min_width = attr_list[i].value.value.i; + break; + case VASurfaceAttribMinHeight: + constraints->min_height = attr_list[i].value.value.i; + break; + case VASurfaceAttribMaxWidth: + constraints->max_width = attr_list[i].value.value.i; + break; + case VASurfaceAttribMaxHeight: + constraints->max_height = attr_list[i].value.value.i; + break; + } + } + if (pix_fmt_count == 0) { + // Nothing usable found. Presumably there exists something which + // works, so leave the set null to indicate unknown. + constraints->valid_sw_formats = NULL; + } else { + constraints->valid_sw_formats = av_malloc_array(pix_fmt_count + 1, + sizeof(pix_fmt)); + if (!constraints->valid_sw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + + for (i = j = 0; i < attr_count; i++) { + int k; + + if (attr_list[i].type != VASurfaceAttribPixelFormat) + continue; + fourcc = attr_list[i].value.value.i; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + + if (pix_fmt == AV_PIX_FMT_NONE) + continue; + + for (k = 0; k < j; k++) { + if (constraints->valid_sw_formats[k] == pix_fmt) + break; + } + + if (k == j) + constraints->valid_sw_formats[j++] = pix_fmt; + } + constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; + } + } else { + // No configuration supplied. + // Return the full set of image formats known by the implementation. + constraints->valid_sw_formats = av_malloc_array(ctx->nb_formats + 1, + sizeof(pix_fmt)); + if (!constraints->valid_sw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + for (i = j = 0; i < ctx->nb_formats; i++) { + int k; + + for (k = 0; k < j; k++) { + if (constraints->valid_sw_formats[k] == ctx->formats[i].pix_fmt) + break; + } + + if (k == j) + constraints->valid_sw_formats[j++] = ctx->formats[i].pix_fmt; + } + + constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; + } + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt)); + if (!constraints->valid_hw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + constraints->valid_hw_formats[0] = AV_PIX_FMT_VAAPI; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + err = 0; +fail: + av_freep(&attr_list); + return err; +} + +static const struct { + const char *friendly_name; + const char *match_string; + unsigned int quirks; +} vaapi_driver_quirks_table[] = { +#if !VA_CHECK_VERSION(1, 0, 0) + // The i965 driver did not conform before version 2.0. + { + "Intel i965 (Quick Sync)", + "i965", + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS, + }, +#endif + { + "Intel iHD", + "ubit", + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE, + }, + { + "VDPAU wrapper", + "Splitted-Desktop Systems VDPAU backend for VA-API", + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES, + }, +}; + +static int vaapi_device_init(AVHWDeviceContext *hwdev) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + AVVAAPIDeviceContext *hwctx = hwdev->hwctx; + VAImageFormat *image_list = NULL; + VAStatus vas; + const char *vendor_string; + int err, i, image_count; + enum AVPixelFormat pix_fmt; + unsigned int fourcc; + + image_count = vaMaxNumImageFormats(hwctx->display); + if (image_count <= 0) { + err = AVERROR(EIO); + goto fail; + } + image_list = av_malloc(image_count * sizeof(*image_list)); + if (!image_list) { + err = AVERROR(ENOMEM); + goto fail; + } + vas = vaQueryImageFormats(hwctx->display, image_list, &image_count); + if (vas != VA_STATUS_SUCCESS) { + err = AVERROR(EIO); + goto fail; + } + + ctx->formats = av_malloc(image_count * sizeof(*ctx->formats)); + if (!ctx->formats) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->nb_formats = 0; + for (i = 0; i < image_count; i++) { + fourcc = image_list[i].fourcc; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + if (pix_fmt == AV_PIX_FMT_NONE) { + av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> unknown.\n", + fourcc); + } else { + av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n", + fourcc, av_get_pix_fmt_name(pix_fmt)); + ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt; + ctx->formats[ctx->nb_formats].image_format = image_list[i]; + ++ctx->nb_formats; + } + } + + vendor_string = vaQueryVendorString(hwctx->display); + if (vendor_string) + av_log(hwdev, AV_LOG_VERBOSE, "VAAPI driver: %s.\n", vendor_string); + + if (hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_USER_SET) { + av_log(hwdev, AV_LOG_VERBOSE, "Using quirks set by user (%#x).\n", + hwctx->driver_quirks); + } else { + // Detect the driver in use and set quirk flags if necessary. + hwctx->driver_quirks = 0; + if (vendor_string) { + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table); i++) { + if (strstr(vendor_string, + vaapi_driver_quirks_table[i].match_string)) { + av_log(hwdev, AV_LOG_VERBOSE, "Matched driver string " + "as known nonstandard driver \"%s\", setting " + "quirks (%#x).\n", + vaapi_driver_quirks_table[i].friendly_name, + vaapi_driver_quirks_table[i].quirks); + hwctx->driver_quirks |= + vaapi_driver_quirks_table[i].quirks; + break; + } + } + if (!(i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table))) { + av_log(hwdev, AV_LOG_VERBOSE, "Driver not found in known " + "nonstandard list, using standard behaviour.\n"); + } + } else { + av_log(hwdev, AV_LOG_VERBOSE, "Driver has no vendor string, " + "assuming standard behaviour.\n"); + } + } + + av_free(image_list); + return 0; +fail: + av_freep(&ctx->formats); + av_free(image_list); + return err; +} + +static void vaapi_device_uninit(AVHWDeviceContext *hwdev) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + + av_freep(&ctx->formats); +} + +static void vaapi_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *hwfc = opaque; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)data; + + vas = vaDestroySurfaces(hwctx->display, &surface_id, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy surface %#x: " + "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } +} + +static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *hwfc = opaque; + VAAPIFramesContext *ctx = hwfc->internal->priv; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VASurfaceID surface_id; + VAStatus vas; + AVBufferRef *ref; + + if (hwfc->initial_pool_size > 0 && + avfc->nb_surfaces >= hwfc->initial_pool_size) + return NULL; + + vas = vaCreateSurfaces(hwctx->display, ctx->rt_format, + hwfc->width, hwfc->height, + &surface_id, 1, + ctx->attributes, ctx->nb_attributes); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create surface: " + "%d (%s).\n", vas, vaErrorStr(vas)); + return NULL; + } + av_log(hwfc, AV_LOG_DEBUG, "Created surface %#x.\n", surface_id); + + ref = av_buffer_create((uint8_t*)(uintptr_t)surface_id, + sizeof(surface_id), &vaapi_buffer_free, + hwfc, AV_BUFFER_FLAG_READONLY); + if (!ref) { + vaDestroySurfaces(hwctx->display, &surface_id, 1); + return NULL; + } + + if (hwfc->initial_pool_size > 0) { + // This is a fixed-size pool, so we must still be in the initial + // allocation sequence. + av_assert0(avfc->nb_surfaces < hwfc->initial_pool_size); + avfc->surface_ids[avfc->nb_surfaces] = surface_id; + ++avfc->nb_surfaces; + } + + return ref; +} + +static int vaapi_frames_init(AVHWFramesContext *hwfc) +{ + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + const VAAPIFormatDescriptor *desc; + VAImageFormat *expected_format; + AVBufferRef *test_surface = NULL; + VASurfaceID test_surface_id; + VAImage test_image; + VAStatus vas; + int err, i; + + desc = vaapi_format_from_pix_fmt(hwfc->sw_format); + if (!desc) { + av_log(hwfc, AV_LOG_ERROR, "Unsupported format: %s.\n", + av_get_pix_fmt_name(hwfc->sw_format)); + return AVERROR(EINVAL); + } + + if (!hwfc->pool) { + if (!(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { + int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); + int need_pixel_format = 1; + for (i = 0; i < avfc->nb_attributes; i++) { + if (avfc->attributes[i].type == VASurfaceAttribMemoryType) + need_memory_type = 0; + if (avfc->attributes[i].type == VASurfaceAttribPixelFormat) + need_pixel_format = 0; + } + ctx->nb_attributes = + avfc->nb_attributes + need_memory_type + need_pixel_format; + + ctx->attributes = av_malloc(ctx->nb_attributes * + sizeof(*ctx->attributes)); + if (!ctx->attributes) { + err = AVERROR(ENOMEM); + goto fail; + } + + for (i = 0; i < avfc->nb_attributes; i++) + ctx->attributes[i] = avfc->attributes[i]; + if (need_memory_type) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA, + }; + } + if (need_pixel_format) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribPixelFormat, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = desc->fourcc, + }; + } + av_assert0(i == ctx->nb_attributes); + } else { + ctx->attributes = NULL; + ctx->nb_attributes = 0; + } + + ctx->rt_format = desc->rt_format; + + if (hwfc->initial_pool_size > 0) { + // This pool will be usable as a render target, so we need to store + // all of the surface IDs somewhere that vaCreateContext() calls + // will be able to access them. + avfc->nb_surfaces = 0; + avfc->surface_ids = av_malloc(hwfc->initial_pool_size * + sizeof(*avfc->surface_ids)); + if (!avfc->surface_ids) { + err = AVERROR(ENOMEM); + goto fail; + } + } else { + // This pool allows dynamic sizing, and will not be usable as a + // render target. + avfc->nb_surfaces = 0; + avfc->surface_ids = NULL; + } + + hwfc->internal->pool_internal = + av_buffer_pool_init2(sizeof(VASurfaceID), hwfc, + &vaapi_pool_alloc, NULL); + if (!hwfc->internal->pool_internal) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create VAAPI surface pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } + + // Allocate a single surface to test whether vaDeriveImage() is going + // to work for the specific configuration. + if (hwfc->pool) { + test_surface = av_buffer_pool_get(hwfc->pool); + if (!test_surface) { + av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from " + "user-configured buffer pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } else { + test_surface = av_buffer_pool_get(hwfc->internal->pool_internal); + if (!test_surface) { + av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from " + "internal buffer pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } + test_surface_id = (VASurfaceID)(uintptr_t)test_surface->data; + + ctx->derive_works = 0; + + err = vaapi_get_image_format(hwfc->device_ctx, + hwfc->sw_format, &expected_format); + if (err == 0) { + vas = vaDeriveImage(hwctx->display, test_surface_id, &test_image); + if (vas == VA_STATUS_SUCCESS) { + if (expected_format->fourcc == test_image.format.fourcc) { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping possible.\n"); + ctx->derive_works = 1; + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "derived image format %08x does not match " + "expected format %08x.\n", + expected_format->fourcc, test_image.format.fourcc); + } + vaDestroyImage(hwctx->display, test_image.image_id); + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "deriving image does not work: " + "%d (%s).\n", vas, vaErrorStr(vas)); + } + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "image format is not supported.\n"); + } + + av_buffer_unref(&test_surface); + return 0; + +fail: + av_buffer_unref(&test_surface); + av_freep(&avfc->surface_ids); + av_freep(&ctx->attributes); + return err; +} + +static void vaapi_frames_uninit(AVHWFramesContext *hwfc) +{ + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + + av_freep(&avfc->surface_ids); + av_freep(&ctx->attributes); +} + +static int vaapi_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VAAPI; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + VAAPIDeviceContext *ctx = hwfc->device_ctx->internal->priv; + enum AVPixelFormat *pix_fmts; + int i, k, sw_format_available; + + sw_format_available = 0; + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == hwfc->sw_format) + sw_format_available = 1; + } + + pix_fmts = av_malloc((ctx->nb_formats + 1) * sizeof(*pix_fmts)); + if (!pix_fmts) + return AVERROR(ENOMEM); + + if (sw_format_available) { + pix_fmts[0] = hwfc->sw_format; + k = 1; + } else { + k = 0; + } + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == hwfc->sw_format) + continue; + av_assert0(k < ctx->nb_formats); + pix_fmts[k++] = ctx->formats[i].pix_fmt; + } + pix_fmts[k] = AV_PIX_FMT_NONE; + + *formats = pix_fmts; + return 0; +} + +static void vaapi_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIMapping *map = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap surface %#x.\n", surface_id); + + vas = vaUnmapBuffer(hwctx->display, map->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to unmap image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + + if ((map->flags & AV_HWFRAME_MAP_WRITE) && + !(map->flags & AV_HWFRAME_MAP_DIRECT)) { + vas = vaPutImage(hwctx->display, surface_id, map->image.image_id, + 0, 0, hwfc->width, hwfc->height, + 0, 0, hwfc->width, hwfc->height); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to write image to surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + } + + vas = vaDestroyImage(hwctx->display, map->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + + av_free(map); +} + +static int vaapi_map_frame(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + VASurfaceID surface_id; + const VAAPIFormatDescriptor *desc; + VAImageFormat *image_format; + VAAPIMapping *map; + VAStatus vas; + void *address = NULL; + int err, i; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id); + + if (!ctx->derive_works && (flags & AV_HWFRAME_MAP_DIRECT)) { + // Requested direct mapping but it is not possible. + return AVERROR(EINVAL); + } + if (dst->format == AV_PIX_FMT_NONE) + dst->format = hwfc->sw_format; + if (dst->format != hwfc->sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) { + // Requested direct mapping but the formats do not match. + return AVERROR(EINVAL); + } + + err = vaapi_get_image_format(hwfc->device_ctx, dst->format, &image_format); + if (err < 0) { + // Requested format is not a valid output format. + return AVERROR(EINVAL); + } + + map = av_malloc(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + map->flags = flags; + map->image.image_id = VA_INVALID_ID; + + vas = vaSyncSurface(hwctx->display, surface_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to sync surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + // The memory which we map using derive need not be connected to the CPU + // in a way conducive to fast access. On Gen7-Gen9 Intel graphics, the + // memory is mappable but not cached, so normal memcpy()-like access is + // very slow to read it (but writing is ok). It is possible to read much + // faster with a copy routine which is aware of the limitation, but we + // assume for now that the user is not aware of that and would therefore + // prefer not to be given direct-mapped memory if they request read access. + if (ctx->derive_works && dst->format == hwfc->sw_format && + ((flags & AV_HWFRAME_MAP_DIRECT) || !(flags & AV_HWFRAME_MAP_READ))) { + vas = vaDeriveImage(hwctx->display, surface_id, &map->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + if (map->image.format.fourcc != image_format->fourcc) { + av_log(hwfc, AV_LOG_ERROR, "Derive image of surface %#x " + "is in wrong format: expected %#08x, got %#08x.\n", + surface_id, image_format->fourcc, map->image.format.fourcc); + err = AVERROR(EIO); + goto fail; + } + map->flags |= AV_HWFRAME_MAP_DIRECT; + } else { + vas = vaCreateImage(hwctx->display, image_format, + hwfc->width, hwfc->height, &map->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create image for " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + if (!(flags & AV_HWFRAME_MAP_OVERWRITE)) { + vas = vaGetImage(hwctx->display, surface_id, 0, 0, + hwfc->width, hwfc->height, map->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to read image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + } + } + + vas = vaMapBuffer(hwctx->display, map->image.buf, &address); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to map image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_frame, map); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + for (i = 0; i < map->image.num_planes; i++) { + dst->data[i] = (uint8_t*)address + map->image.offsets[i]; + dst->linesize[i] = map->image.pitches[i]; + } + + desc = vaapi_format_from_fourcc(map->image.format.fourcc); + if (desc && desc->chroma_planes_swapped) { + // Chroma planes are YVU rather than YUV, so swap them. + FFSWAP(uint8_t*, dst->data[1], dst->data[2]); + } + + return 0; + +fail: + if (map) { + if (address) + vaUnmapBuffer(hwctx->display, map->image.buf); + if (map->image.image_id != VA_INVALID_ID) + vaDestroyImage(hwctx->display, map->image.image_id); + av_free(map); + } + return err; +} + +static int vaapi_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = vaapi_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = vaapi_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vaapi_map_to_memory(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (dst->format != AV_PIX_FMT_NONE) { + err = vaapi_get_image_format(hwfc->device_ctx, dst->format, NULL); + if (err < 0) + return AVERROR(ENOSYS); + } + + err = vaapi_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +#if CONFIG_LIBDRM + +#define DRM_MAP(va, layers, ...) { \ + VA_FOURCC_ ## va, \ + layers, \ + { __VA_ARGS__ } \ + } +static const struct { + uint32_t va_fourcc; + int nb_layer_formats; + uint32_t layer_formats[AV_DRM_MAX_PLANES]; +} vaapi_drm_format_map[] = { +#ifdef DRM_FORMAT_R8 + DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88), + DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_GR88), +#endif + DRM_MAP(NV12, 1, DRM_FORMAT_NV12), +#if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) + DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), +#endif +#if defined(VA_FOURCC_P012) && defined(DRM_FORMAT_R16) + DRM_MAP(P012, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), +#endif + DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888), + DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888), + DRM_MAP(RGBA, 1, DRM_FORMAT_ABGR8888), + DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888), +#ifdef VA_FOURCC_ABGR + DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888), + DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888), +#endif + DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888), +#if defined(VA_FOURCC_XYUV) && defined(DRM_FORMAT_XYUV8888) + DRM_MAP(XYUV, 1, DRM_FORMAT_XYUV8888), +#endif +#if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU2101010) + DRM_MAP(Y410, 1, DRM_FORMAT_XVYU2101010), +#endif +#if defined(VA_FOURCC_Y412) && defined(DRM_FORMAT_XVYU12_16161616) + DRM_MAP(Y412, 1, DRM_FORMAT_XVYU12_16161616), +#endif +}; +#undef DRM_MAP + +static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->priv; + + av_log(dst_fc, AV_LOG_DEBUG, "Destroy surface %#x.\n", surface_id); + + vaDestroySurfaces(dst_dev->display, &surface_id, 1); +} + +static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if VA_CHECK_VERSION(1, 1, 0) + VAAPIFramesContext *src_vafc = src_fc->internal->priv; + int use_prime2; +#else + int k; +#endif + AVHWFramesContext *dst_fc = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + const VAAPIFormatDescriptor *format_desc; + VASurfaceID surface_id; + VAStatus vas = VA_STATUS_SUCCESS; + uint32_t va_fourcc; + int err, i, j; + +#if !VA_CHECK_VERSION(1, 1, 0) + unsigned long buffer_handle; + VASurfaceAttribExternalBuffers buffer_desc; + VASurfaceAttrib attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &buffer_desc, + } + }; +#endif + + desc = (AVDRMFrameDescriptor*)src->data[0]; + + if (desc->nb_objects != 1) { + av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " + "made from a single DRM object.\n"); + return AVERROR(EINVAL); + } + + va_fourcc = 0; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) + continue; + for (j = 0; j < desc->nb_layers; j++) { + if (desc->layers[j].format != + vaapi_drm_format_map[i].layer_formats[j]) + break; + } + if (j != desc->nb_layers) + continue; + va_fourcc = vaapi_drm_format_map[i].va_fourcc; + break; + } + if (!va_fourcc) { + av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " + "by VAAPI.\n"); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " + "%08x.\n", desc->objects[0].fd, va_fourcc); + + format_desc = vaapi_format_from_fourcc(va_fourcc); + av_assert0(format_desc); + +#if VA_CHECK_VERSION(1, 1, 0) + use_prime2 = !src_vafc->prime_2_import_unsupported && + desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID; + if (use_prime2) { + VADRMPRIMESurfaceDescriptor prime_desc; + VASurfaceAttrib prime_attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &prime_desc, + } + }; + prime_desc.fourcc = va_fourcc; + prime_desc.width = src_fc->width; + prime_desc.height = src_fc->height; + prime_desc.num_objects = desc->nb_objects; + for (i = 0; i < desc->nb_objects; ++i) { + prime_desc.objects[i].fd = desc->objects[i].fd; + prime_desc.objects[i].size = desc->objects[i].size; + prime_desc.objects[i].drm_format_modifier = + desc->objects[i].format_modifier; + } + + prime_desc.num_layers = desc->nb_layers; + for (i = 0; i < desc->nb_layers; ++i) { + prime_desc.layers[i].drm_format = desc->layers[i].format; + prime_desc.layers[i].num_planes = desc->layers[i].nb_planes; + for (j = 0; j < desc->layers[i].nb_planes; ++j) { + prime_desc.layers[i].object_index[j] = + desc->layers[i].planes[j].object_index; + prime_desc.layers[i].offset[j] = desc->layers[i].planes[j].offset; + prime_desc.layers[i].pitch[j] = desc->layers[i].planes[j].pitch; + } + + if (format_desc->chroma_planes_swapped && + desc->layers[i].nb_planes == 3) { + FFSWAP(uint32_t, prime_desc.layers[i].pitch[1], + prime_desc.layers[i].pitch[2]); + FFSWAP(uint32_t, prime_desc.layers[i].offset[1], + prime_desc.layers[i].offset[2]); + } + } + + /* + * We can query for PRIME_2 support with vaQuerySurfaceAttributes, but that + * that needs the config_id which we don't have here . Both Intel and + * Gallium seem to do the correct error checks, so lets just try the + * PRIME_2 import first. + */ + vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format, + src->width, src->height, &surface_id, 1, + prime_attrs, FF_ARRAY_ELEMS(prime_attrs)); + if (vas != VA_STATUS_SUCCESS) + src_vafc->prime_2_import_unsupported = 1; + } + + if (!use_prime2 || vas != VA_STATUS_SUCCESS) { + int k; + unsigned long buffer_handle; + VASurfaceAttribExternalBuffers buffer_desc; + VASurfaceAttrib buffer_attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &buffer_desc, + } + }; + + buffer_handle = desc->objects[0].fd; + buffer_desc.pixel_format = va_fourcc; + buffer_desc.width = src_fc->width; + buffer_desc.height = src_fc->height; + buffer_desc.data_size = desc->objects[0].size; + buffer_desc.buffers = &buffer_handle; + buffer_desc.num_buffers = 1; + buffer_desc.flags = 0; + + k = 0; + for (i = 0; i < desc->nb_layers; i++) { + for (j = 0; j < desc->layers[i].nb_planes; j++) { + buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch; + buffer_desc.offsets[k] = desc->layers[i].planes[j].offset; + ++k; + } + } + buffer_desc.num_planes = k; + + if (format_desc->chroma_planes_swapped && + buffer_desc.num_planes == 3) { + FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]); + FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]); + } + + vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format, + src->width, src->height, + &surface_id, 1, + buffer_attrs, FF_ARRAY_ELEMS(buffer_attrs)); + } +#else + buffer_handle = desc->objects[0].fd; + buffer_desc.pixel_format = va_fourcc; + buffer_desc.width = src_fc->width; + buffer_desc.height = src_fc->height; + buffer_desc.data_size = desc->objects[0].size; + buffer_desc.buffers = &buffer_handle; + buffer_desc.num_buffers = 1; + buffer_desc.flags = 0; + + k = 0; + for (i = 0; i < desc->nb_layers; i++) { + for (j = 0; j < desc->layers[i].nb_planes; j++) { + buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch; + buffer_desc.offsets[k] = desc->layers[i].planes[j].offset; + ++k; + } + } + buffer_desc.num_planes = k; + + if (format_desc->chroma_planes_swapped && + buffer_desc.num_planes == 3) { + FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]); + FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]); + } + + vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format, + src->width, src->height, + &surface_id, 1, + attrs, FF_ARRAY_ELEMS(attrs)); +#endif + if (vas != VA_STATUS_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM " + "object: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(dst_fc, AV_LOG_DEBUG, "Create surface %#x.\n", surface_id); + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &vaapi_unmap_from_drm, + (void*)(uintptr_t)surface_id); + if (err < 0) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)(uintptr_t)surface_id; + + av_log(dst_fc, AV_LOG_DEBUG, "Mapped DRM object %d to " + "surface %#x.\n", desc->objects[0].fd, surface_id); + + return 0; +} + +#if VA_CHECK_VERSION(1, 1, 0) +static void vaapi_unmap_to_drm_esh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVDRMFrameDescriptor *drm_desc = hwmap->priv; + int i; + + for (i = 0; i < drm_desc->nb_objects; i++) + close(drm_desc->objects[i].fd); + + av_freep(&drm_desc); +} + +static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VASurfaceID surface_id; + VAStatus vas; + VADRMPRIMESurfaceDescriptor va_desc; + AVDRMFrameDescriptor *drm_desc = NULL; + uint32_t export_flags; + int err, i, j; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + + export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS; + if (flags & AV_HWFRAME_MAP_READ) + export_flags |= VA_EXPORT_SURFACE_READ_ONLY; + if (flags & AV_HWFRAME_MAP_WRITE) + export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY; + + vas = vaExportSurfaceHandle(hwctx->display, surface_id, + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + export_flags, &va_desc); + if (vas != VA_STATUS_SUCCESS) { + if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) + return AVERROR(ENOSYS); + av_log(hwfc, AV_LOG_ERROR, "Failed to export surface %#x: " + "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + drm_desc = av_mallocz(sizeof(*drm_desc)); + if (!drm_desc) { + err = AVERROR(ENOMEM); + goto fail; + } + + // By some bizarre coincidence, these structures are very similar... + drm_desc->nb_objects = va_desc.num_objects; + for (i = 0; i < va_desc.num_objects; i++) { + drm_desc->objects[i].fd = va_desc.objects[i].fd; + drm_desc->objects[i].size = va_desc.objects[i].size; + drm_desc->objects[i].format_modifier = + va_desc.objects[i].drm_format_modifier; + } + drm_desc->nb_layers = va_desc.num_layers; + for (i = 0; i < va_desc.num_layers; i++) { + drm_desc->layers[i].format = va_desc.layers[i].drm_format; + drm_desc->layers[i].nb_planes = va_desc.layers[i].num_planes; + for (j = 0; j < va_desc.layers[i].num_planes; j++) { + drm_desc->layers[i].planes[j].object_index = + va_desc.layers[i].object_index[j]; + drm_desc->layers[i].planes[j].offset = + va_desc.layers[i].offset[j]; + drm_desc->layers[i].planes[j].pitch = + va_desc.layers[i].pitch[j]; + } + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &vaapi_unmap_to_drm_esh, drm_desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + dst->data[0] = (uint8_t*)drm_desc; + + return 0; + +fail: + for (i = 0; i < va_desc.num_objects; i++) + close(va_desc.objects[i].fd); + av_freep(&drm_desc); + return err; +} +#endif + +#if VA_CHECK_VERSION(0, 36, 0) +typedef struct VAAPIDRMImageBufferMapping { + VAImage image; + VABufferInfo buffer_info; + + AVDRMFrameDescriptor drm_desc; +} VAAPIDRMImageBufferMapping; + +static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from DRM.\n", + surface_id); + + // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(), + // so we shouldn't close them separately. + + vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer " + "handle of image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + } + + vas = vaDestroyImage(hwctx->display, mapping->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image " + "derived from surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + } + + av_free(mapping); +} + +static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = NULL; + VASurfaceID surface_id; + VAStatus vas; + int err, i, p; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map VAAPI surface %#x to DRM.\n", + surface_id); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + vas = vaDeriveImage(hwctx->display, surface_id, + &mapping->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (vaapi_drm_format_map[i].va_fourcc == + mapping->image.format.fourcc) + break; + } + if (i >= FF_ARRAY_ELEMS(vaapi_drm_format_map)) { + av_log(hwfc, AV_LOG_ERROR, "No matching DRM format for " + "VAAPI format %#x.\n", mapping->image.format.fourcc); + err = AVERROR(EINVAL); + goto fail_derived; + } + + mapping->buffer_info.mem_type = + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + + mapping->drm_desc.nb_layers = + vaapi_drm_format_map[i].nb_layer_formats; + if (mapping->drm_desc.nb_layers > 1) { + if (mapping->drm_desc.nb_layers != mapping->image.num_planes) { + av_log(hwfc, AV_LOG_ERROR, "Image properties do not match " + "expected format: got %d planes, but expected %d.\n", + mapping->image.num_planes, mapping->drm_desc.nb_layers); + err = AVERROR(EINVAL); + goto fail_derived; + } + + for(p = 0; p < mapping->drm_desc.nb_layers; p++) { + mapping->drm_desc.layers[p] = (AVDRMLayerDescriptor) { + .format = vaapi_drm_format_map[i].layer_formats[p], + .nb_planes = 1, + .planes[0] = { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }, + }; + } + } else { + mapping->drm_desc.layers[0].format = + vaapi_drm_format_map[i].layer_formats[0]; + mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes; + for (p = 0; p < mapping->image.num_planes; p++) { + mapping->drm_desc.layers[0].planes[p] = (AVDRMPlaneDescriptor) { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }; + } + } + + vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf, + &mapping->buffer_info); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer " + "handle from image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_derived; + } + + av_log(hwfc, AV_LOG_DEBUG, "DRM PRIME fd is %"PRIdPTR".\n", + mapping->buffer_info.handle); + + mapping->drm_desc.nb_objects = 1; + mapping->drm_desc.objects[0] = (AVDRMObjectDescriptor) { + .fd = mapping->buffer_info.handle, + .size = mapping->image.data_size, + // There is no way to get the format modifier with this API. + .format_modifier = DRM_FORMAT_MOD_INVALID, + }; + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_to_drm_abh, + mapping); + if (err < 0) + goto fail_mapped; + + dst->data[0] = (uint8_t*)&mapping->drm_desc; + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail_mapped: + vaReleaseBufferHandle(hwctx->display, mapping->image.buf); +fail_derived: + vaDestroyImage(hwctx->display, mapping->image.image_id); +fail: + av_freep(&mapping); + return err; +} +#endif + +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if VA_CHECK_VERSION(1, 1, 0) + int err; + err = vaapi_map_to_drm_esh(hwfc, dst, src, flags); + if (err != AVERROR(ENOSYS)) + return err; +#endif +#if VA_CHECK_VERSION(0, 36, 0) + return vaapi_map_to_drm_abh(hwfc, dst, src, flags); +#endif + return AVERROR(ENOSYS); +} + +#endif /* CONFIG_LIBDRM */ + +static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (src->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_from_drm(hwfc, dst, src, flags); +#endif + default: + return AVERROR(ENOSYS); + } +} + +static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (dst->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_to_drm(hwfc, dst, src, flags); +#endif + default: + return vaapi_map_to_memory(hwfc, dst, src, flags); + } +} + +static void vaapi_device_free(AVHWDeviceContext *ctx) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VAAPIDevicePriv *priv = ctx->user_opaque; + + if (hwctx->display) + vaTerminate(hwctx->display); + +#if HAVE_VAAPI_X11 + if (priv->x11_display) + XCloseDisplay(priv->x11_display); +#endif + + if (priv->drm_fd >= 0) + close(priv->drm_fd); + + av_freep(&priv); +} + +#if CONFIG_VAAPI_1 +static void vaapi_device_log_error(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_ERROR, "libva: %s", message); +} + +static void vaapi_device_log_info(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_VERBOSE, "libva: %s", message); +} +#endif + +static int vaapi_device_connect(AVHWDeviceContext *ctx, + VADisplay display) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + int major, minor; + VAStatus vas; + +#if CONFIG_VAAPI_1 + vaSetErrorCallback(display, &vaapi_device_log_error, ctx); + vaSetInfoCallback (display, &vaapi_device_log_info, ctx); +#endif + + hwctx->display = display; + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: " + "version %d.%d\n", major, minor); + + return 0; +} + +static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + VAAPIDevicePriv *priv; + VADisplay display = NULL; + const AVDictionaryEntry *ent; + int try_drm, try_x11, try_all; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + priv->drm_fd = -1; + + ctx->user_opaque = priv; + ctx->free = vaapi_device_free; + + ent = av_dict_get(opts, "connection_type", NULL, 0); + if (ent) { + try_all = try_drm = try_x11 = 0; + if (!strcmp(ent->value, "drm")) { + try_drm = 1; + } else if (!strcmp(ent->value, "x11")) { + try_x11 = 1; + } else { + av_log(ctx, AV_LOG_ERROR, "Invalid connection type %s.\n", + ent->value); + return AVERROR(EINVAL); + } + } else { + try_all = 1; + try_drm = HAVE_VAAPI_DRM; + try_x11 = HAVE_VAAPI_X11; + } + +#if HAVE_VAAPI_DRM + while (!display && try_drm) { + // If the device is specified, try to open it as a DRM device node. + // If not, look for a usable render node, possibly restricted to those + // using a specified kernel driver. + int loglevel = try_all ? AV_LOG_VERBOSE : AV_LOG_ERROR; + if (device) { + priv->drm_fd = open(device, O_RDWR); + if (priv->drm_fd < 0) { + av_log(ctx, loglevel, "Failed to open %s as " + "DRM device node.\n", device); + break; + } + } else { + char path[64]; + int n, max_devices = 8; +#if CONFIG_LIBDRM + drmVersion *info; + const AVDictionaryEntry *kernel_driver; + kernel_driver = av_dict_get(opts, "kernel_driver", NULL, 0); +#endif + for (n = 0; n < max_devices; n++) { + snprintf(path, sizeof(path), + "/dev/dri/renderD%d", 128 + n); + priv->drm_fd = open(path, O_RDWR); + if (priv->drm_fd < 0) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open " + "DRM render node for device %d.\n", n); + break; + } +#if CONFIG_LIBDRM + info = drmGetVersion(priv->drm_fd); + if (!info) { + av_log(ctx, AV_LOG_VERBOSE, + "Failed to get DRM version for device %d.\n", n); + close(priv->drm_fd); + priv->drm_fd = -1; + continue; + } + if (kernel_driver) { + if (strcmp(kernel_driver->value, info->name)) { + av_log(ctx, AV_LOG_VERBOSE, "Ignoring device %d " + "with non-matching kernel driver (%s).\n", + n, info->name); + drmFreeVersion(info); + close(priv->drm_fd); + priv->drm_fd = -1; + continue; + } + av_log(ctx, AV_LOG_VERBOSE, "Trying to use " + "DRM render node for device %d, " + "with matching kernel driver (%s).\n", + n, info->name); + drmFreeVersion(info); + break; + // drmGetVersion() ensures |info->name| is 0-terminated. + } else if (!strcmp(info->name, "vgem")) { + av_log(ctx, AV_LOG_VERBOSE, + "Skipping vgem node for device %d.\n", n); + drmFreeVersion(info); + close(priv->drm_fd); + priv->drm_fd = -1; + continue; + } + drmFreeVersion(info); +#endif + av_log(ctx, AV_LOG_VERBOSE, "Trying to use " + "DRM render node for device %d.\n", n); + break; + } + if (n >= max_devices) + break; + } + + display = vaGetDisplayDRM(priv->drm_fd); + if (!display) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open a VA display " + "from DRM device %s.\n", device); + return AVERROR_EXTERNAL; + } + break; + } +#endif + +#if HAVE_VAAPI_X11 + if (!display && try_x11) { + // Try to open the device as an X11 display. + priv->x11_display = XOpenDisplay(device); + if (!priv->x11_display) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display " + "%s.\n", XDisplayName(device)); + } else { + display = vaGetDisplay(priv->x11_display); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " + "from X11 display %s.\n", XDisplayName(device)); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " + "X11 display %s.\n", XDisplayName(device)); + } + } +#endif + + if (!display) { + if (device) + av_log(ctx, AV_LOG_ERROR, "No VA display found for " + "device %s.\n", device); + else + av_log(ctx, AV_LOG_ERROR, "No VA display found for " + "any default device.\n"); + return AVERROR(EINVAL); + } + + ent = av_dict_get(opts, "driver", NULL, 0); + if (ent) { +#if VA_CHECK_VERSION(0, 38, 0) + VAStatus vas; + vas = vaSetDriverName(display, ent->value); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to set driver name to " + "%s: %d (%s).\n", ent->value, vas, vaErrorStr(vas)); + vaTerminate(display); + return AVERROR_EXTERNAL; + } +#else + av_log(ctx, AV_LOG_WARNING, "Driver name setting is not " + "supported with this VAAPI version.\n"); +#endif + } + + return vaapi_device_connect(ctx, display); +} + +static int vaapi_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *src_ctx, + AVDictionary *opts, int flags) +{ +#if HAVE_VAAPI_DRM + if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { + AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; + VADisplay *display; + VAAPIDevicePriv *priv; + int fd; + + if (src_hwctx->fd < 0) { + av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " + "device to derive a VA display from.\n"); + return AVERROR(EINVAL); + } + +#if CONFIG_LIBDRM + { + int node_type = drmGetNodeTypeFromFd(src_hwctx->fd); + char *render_node; + if (node_type < 0) { + av_log(ctx, AV_LOG_ERROR, "DRM instance fd does not appear " + "to refer to a DRM device.\n"); + return AVERROR(EINVAL); + } + if (node_type == DRM_NODE_RENDER) { + fd = src_hwctx->fd; + } else { + render_node = drmGetRenderDeviceNameFromFd(src_hwctx->fd); + if (!render_node) { + av_log(ctx, AV_LOG_VERBOSE, "Using non-render node " + "because the device does not have an " + "associated render node.\n"); + fd = src_hwctx->fd; + } else { + fd = open(render_node, O_RDWR); + if (fd < 0) { + av_log(ctx, AV_LOG_VERBOSE, "Using non-render node " + "because the associated render node " + "could not be opened.\n"); + fd = src_hwctx->fd; + } else { + av_log(ctx, AV_LOG_VERBOSE, "Using render node %s " + "in place of non-render DRM device.\n", + render_node); + } + free(render_node); + } + } + } +#else + fd = src_hwctx->fd; +#endif + + priv = av_mallocz(sizeof(*priv)); + if (!priv) { + if (fd != src_hwctx->fd) { + // The fd was opened in this function. + close(fd); + } + return AVERROR(ENOMEM); + } + + if (fd == src_hwctx->fd) { + // The fd is inherited from the source context and we are holding + // a reference to that, we don't want to close it from here. + priv->drm_fd = -1; + } else { + priv->drm_fd = fd; + } + + ctx->user_opaque = priv; + ctx->free = &vaapi_device_free; + + display = vaGetDisplayDRM(fd); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from " + "DRM device.\n"); + return AVERROR(EIO); + } + + return vaapi_device_connect(ctx, display); + } +#endif + return AVERROR(ENOSYS); +} + +const HWContextType ff_hwcontext_type_vaapi = { + .type = AV_HWDEVICE_TYPE_VAAPI, + .name = "VAAPI", + + .device_hwctx_size = sizeof(AVVAAPIDeviceContext), + .device_priv_size = sizeof(VAAPIDeviceContext), + .device_hwconfig_size = sizeof(AVVAAPIHWConfig), + .frames_hwctx_size = sizeof(AVVAAPIFramesContext), + .frames_priv_size = sizeof(VAAPIFramesContext), + + .device_create = &vaapi_device_create, + .device_derive = &vaapi_device_derive, + .device_init = &vaapi_device_init, + .device_uninit = &vaapi_device_uninit, + .frames_get_constraints = &vaapi_frames_get_constraints, + .frames_init = &vaapi_frames_init, + .frames_uninit = &vaapi_frames_uninit, + .frames_get_buffer = &vaapi_get_buffer, + .transfer_get_formats = &vaapi_transfer_get_formats, + .transfer_data_to = &vaapi_transfer_data_to, + .transfer_data_from = &vaapi_transfer_data_from, + .map_to = &vaapi_map_to, + .map_from = &vaapi_map_from, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_VAAPI, + AV_PIX_FMT_NONE + }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.h new file mode 100644 index 00000000..0b2e071c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vaapi.h @@ -0,0 +1,117 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VAAPI_H +#define AVUTIL_HWCONTEXT_VAAPI_H + +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_VAAPI. + * + * Dynamic frame pools are supported, but note that any pool used as a render + * target is required to be of fixed size in order to be be usable as an + * argument to vaCreateContext(). + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a VASurfaceID. + */ + +enum { + /** + * The quirks field has been set by the user and should not be detected + * automatically by av_hwdevice_ctx_init(). + */ + AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0), + /** + * The driver does not destroy parameter buffers when they are used by + * vaRenderPicture(). Additional code will be required to destroy them + * separately afterwards. + */ + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1), + + /** + * The driver does not support the VASurfaceAttribMemoryType attribute, + * so the surface allocation code will not try to use it. + */ + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), + + /** + * The driver does not support surface attributes at all. + * The surface allocation code will never pass them to surface allocation, + * and the results of the vaQuerySurfaceAttributes() call will be faked. + */ + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3), +}; + +/** + * VAAPI connection details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVAAPIDeviceContext { + /** + * The VADisplay handle, to be filled by the user. + */ + VADisplay display; + /** + * Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), + * with reference to a table of known drivers, unless the + * AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present. The user + * may need to refer to this field when performing any later + * operations using VAAPI with the same VADisplay. + */ + unsigned int driver_quirks; +} AVVAAPIDeviceContext; + +/** + * VAAPI-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVVAAPIFramesContext { + /** + * Set by the user to apply surface attributes to all surfaces in + * the frame pool. If null, default settings are used. + */ + VASurfaceAttrib *attributes; + int nb_attributes; + /** + * The surfaces IDs of all surfaces in the pool after creation. + * Only valid if AVHWFramesContext.initial_pool_size was positive. + * These are intended to be used as the render_targets arguments to + * vaCreateContext(). + */ + VASurfaceID *surface_ids; + int nb_surfaces; +} AVVAAPIFramesContext; + +/** + * VAAPI hardware pipeline configuration details. + * + * Allocated with av_hwdevice_hwconfig_alloc(). + */ +typedef struct AVVAAPIHWConfig { + /** + * ID of a VAAPI pipeline configuration. + */ + VAConfigID config_id; +} AVVAAPIHWConfig; + +#endif /* AVUTIL_HWCONTEXT_VAAPI_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.c new file mode 100644 index 00000000..5b78e955 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.c @@ -0,0 +1,528 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_vdpau.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" + +typedef struct VDPAUPixFmtMap { + VdpYCbCrFormat vdpau_fmt; + enum AVPixelFormat pix_fmt; +} VDPAUPixFmtMap; + +static const VDPAUPixFmtMap pix_fmts_420[] = { + { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 }, + { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_YCBCR_FORMAT_P016, AV_PIX_FMT_P016 }, + { VDP_YCBCR_FORMAT_P010, AV_PIX_FMT_P010 }, +#endif + { 0, AV_PIX_FMT_NONE, }, +}; + +static const VDPAUPixFmtMap pix_fmts_422[] = { + { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV16 }, + { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV422P }, + { VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 }, + { VDP_YCBCR_FORMAT_YUYV, AV_PIX_FMT_YUYV422 }, + { 0, AV_PIX_FMT_NONE, }, +}; + +static const VDPAUPixFmtMap pix_fmts_444[] = { +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + { VDP_YCBCR_FORMAT_Y_U_V_444, AV_PIX_FMT_YUV444P }, +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + {VDP_YCBCR_FORMAT_Y_U_V_444_16, AV_PIX_FMT_YUV444P16}, +#endif + { 0, AV_PIX_FMT_NONE, }, +}; + +static const struct { + VdpChromaType chroma_type; + enum AVPixelFormat frames_sw_format; + const VDPAUPixFmtMap *map; +} vdpau_pix_fmts[] = { + { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUV420P, pix_fmts_420 }, + { VDP_CHROMA_TYPE_422, AV_PIX_FMT_YUV422P, pix_fmts_422 }, + { VDP_CHROMA_TYPE_444, AV_PIX_FMT_YUV444P, pix_fmts_444 }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P10, pix_fmts_420 }, + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P12, pix_fmts_420 }, + { VDP_CHROMA_TYPE_422_16, AV_PIX_FMT_YUV422P10, pix_fmts_422 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P10, pix_fmts_444 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P12, pix_fmts_444 }, +#endif +}; + +typedef struct VDPAUDeviceContext { + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *get_transfer_caps; + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpVideoSurfaceCreate *surf_create; + VdpVideoSurfaceDestroy *surf_destroy; + + enum AVPixelFormat *pix_fmts[FF_ARRAY_ELEMS(vdpau_pix_fmts)]; + int nb_pix_fmts[FF_ARRAY_ELEMS(vdpau_pix_fmts)]; +} VDPAUDeviceContext; + +typedef struct VDPAUFramesContext { + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpChromaType chroma_type; + int chroma_idx; + + const enum AVPixelFormat *pix_fmts; + int nb_pix_fmts; +} VDPAUFramesContext; + +static int count_pixfmts(const VDPAUPixFmtMap *map) +{ + int count = 0; + while (map->pix_fmt != AV_PIX_FMT_NONE) { + map++; + count++; + } + return count; +} + +static int vdpau_init_pixmfts(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDeviceContext *priv = ctx->internal->priv; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(priv->pix_fmts); i++) { + const VDPAUPixFmtMap *map = vdpau_pix_fmts[i].map; + int nb_pix_fmts; + + nb_pix_fmts = count_pixfmts(map); + priv->pix_fmts[i] = av_malloc_array(nb_pix_fmts + 1, sizeof(*priv->pix_fmts[i])); + if (!priv->pix_fmts[i]) + return AVERROR(ENOMEM); + + nb_pix_fmts = 0; + while (map->pix_fmt != AV_PIX_FMT_NONE) { + VdpBool supported; + VdpStatus err = priv->get_transfer_caps(hwctx->device, vdpau_pix_fmts[i].chroma_type, + map->vdpau_fmt, &supported); + if (err == VDP_STATUS_OK && supported) + priv->pix_fmts[i][nb_pix_fmts++] = map->pix_fmt; + map++; + } + priv->pix_fmts[i][nb_pix_fmts++] = AV_PIX_FMT_NONE; + priv->nb_pix_fmts[i] = nb_pix_fmts; + } + + return 0; +} + +#define GET_CALLBACK(id, result) \ +do { \ + void *tmp; \ + err = hwctx->get_proc_address(hwctx->device, id, &tmp); \ + if (err != VDP_STATUS_OK) { \ + av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ + return AVERROR_UNKNOWN; \ + } \ + result = tmp; \ +} while (0) + +static int vdpau_device_init(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDeviceContext *priv = ctx->internal->priv; + VdpStatus err; + int ret; + + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + priv->get_transfer_caps); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, priv->get_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, priv->put_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, priv->surf_create); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, priv->surf_destroy); + + ret = vdpau_init_pixmfts(ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error querying the supported pixel formats\n"); + return ret; + } + + return 0; +} + +static void vdpau_device_uninit(AVHWDeviceContext *ctx) +{ + VDPAUDeviceContext *priv = ctx->internal->priv; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(priv->pix_fmts); i++) + av_freep(&priv->pix_fmts[i]); +} + +static int vdpau_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + VDPAUDeviceContext *priv = ctx->internal->priv; + int nb_sw_formats = 0; + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(vdpau_pix_fmts) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(vdpau_pix_fmts); i++) { + if (priv->nb_pix_fmts[i] > 1) + constraints->valid_sw_formats[nb_sw_formats++] = vdpau_pix_fmts[i].frames_sw_format; + } + constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_VDPAU; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void vdpau_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = opaque; + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)data; + + device_priv->surf_destroy(surf); +} + +static AVBufferRef *vdpau_pool_alloc(void *opaque, size_t size) +{ + AVHWFramesContext *ctx = opaque; + VDPAUFramesContext *priv = ctx->internal->priv; + AVVDPAUDeviceContext *device_hwctx = ctx->device_ctx->hwctx; + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + + AVBufferRef *ret; + VdpVideoSurface surf; + VdpStatus err; + + err = device_priv->surf_create(device_hwctx->device, priv->chroma_type, + ctx->width, ctx->height, &surf); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error allocating a VDPAU video surface\n"); + return NULL; + } + + ret = av_buffer_create((uint8_t*)(uintptr_t)surf, sizeof(surf), + vdpau_buffer_free, ctx, AV_BUFFER_FLAG_READONLY); + if (!ret) { + device_priv->surf_destroy(surf); + return NULL; + } + + return ret; +} + +static int vdpau_frames_init(AVHWFramesContext *ctx) +{ + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + VDPAUFramesContext *priv = ctx->internal->priv; + + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(vdpau_pix_fmts); i++) { + if (vdpau_pix_fmts[i].frames_sw_format == ctx->sw_format) { + priv->chroma_type = vdpau_pix_fmts[i].chroma_type; + priv->chroma_idx = i; + priv->pix_fmts = device_priv->pix_fmts[i]; + priv->nb_pix_fmts = device_priv->nb_pix_fmts[i]; + break; + } + } + if (priv->nb_pix_fmts < 2) { + av_log(ctx, AV_LOG_ERROR, "Unsupported sw format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(ENOSYS); + } + + if (!ctx->pool) { + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(VdpVideoSurface), ctx, + vdpau_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + } + + priv->get_data = device_priv->get_data; + priv->put_data = device_priv->put_data; + + return 0; +} + +static int vdpau_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VDPAU; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int vdpau_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + + enum AVPixelFormat *fmts; + + if (priv->nb_pix_fmts == 1) { + av_log(ctx, AV_LOG_ERROR, + "No target formats are supported for this chroma type\n"); + return AVERROR(ENOSYS); + } + + fmts = av_malloc_array(priv->nb_pix_fmts, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + memcpy(fmts, priv->pix_fmts, sizeof(*fmts) * (priv->nb_pix_fmts)); + *formats = fmts; + + return 0; +} + +static int vdpau_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)src->data[3]; + + void *data[3]; + uint32_t linesize[3]; + + const VDPAUPixFmtMap *map; + VdpYCbCrFormat vdpau_format; + VdpStatus err; + int i; + + for (i = 0; i< FF_ARRAY_ELEMS(data) && dst->data[i]; i++) { + data[i] = dst->data[i]; + if (dst->linesize[i] < 0 || dst->linesize[i] > UINT32_MAX) { + av_log(ctx, AV_LOG_ERROR, + "The linesize %d cannot be represented as uint32\n", + dst->linesize[i]); + return AVERROR(ERANGE); + } + linesize[i] = dst->linesize[i]; + } + + map = vdpau_pix_fmts[priv->chroma_idx].map; + for (i = 0; map[i].pix_fmt != AV_PIX_FMT_NONE; i++) { + if (map[i].pix_fmt == dst->format) { + vdpau_format = map[i].vdpau_fmt; + break; + } + } + if (map[i].pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "Unsupported target pixel format: %s\n", + av_get_pix_fmt_name(dst->format)); + return AVERROR(EINVAL); + } + + if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444_16) +#endif + ) + FFSWAP(void*, data[1], data[2]); + + err = priv->get_data(surf, vdpau_format, data, linesize); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error retrieving the data from a VDPAU surface\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int vdpau_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)dst->data[3]; + + const void *data[3]; + uint32_t linesize[3]; + + const VDPAUPixFmtMap *map; + VdpYCbCrFormat vdpau_format; + VdpStatus err; + int i; + + for (i = 0; i< FF_ARRAY_ELEMS(data) && src->data[i]; i++) { + data[i] = src->data[i]; + if (src->linesize[i] < 0 || src->linesize[i] > UINT32_MAX) { + av_log(ctx, AV_LOG_ERROR, + "The linesize %d cannot be represented as uint32\n", + src->linesize[i]); + return AVERROR(ERANGE); + } + linesize[i] = src->linesize[i]; + } + + map = vdpau_pix_fmts[priv->chroma_idx].map; + for (i = 0; map[i].pix_fmt != AV_PIX_FMT_NONE; i++) { + if (map[i].pix_fmt == src->format) { + vdpau_format = map[i].vdpau_fmt; + break; + } + } + if (map[i].pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "Unsupported source pixel format: %s\n", + av_get_pix_fmt_name(src->format)); + return AVERROR(EINVAL); + } + + if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif + ) + FFSWAP(const void*, data[1], data[2]); + + err = priv->put_data(surf, vdpau_format, data, linesize); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error uploading the data to a VDPAU surface\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +#if HAVE_VDPAU_X11 +#include +#include + +typedef struct VDPAUDevicePriv { + VdpDeviceDestroy *device_destroy; + Display *dpy; +} VDPAUDevicePriv; + +static void vdpau_device_free(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDevicePriv *priv = ctx->user_opaque; + + if (priv->device_destroy) + priv->device_destroy(hwctx->device); + if (priv->dpy) + XCloseDisplay(priv->dpy); + av_freep(&priv); +} + +static int vdpau_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + + VDPAUDevicePriv *priv; + VdpStatus err; + VdpGetInformationString *get_information_string; + const char *display, *vendor; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = vdpau_device_free; + + priv->dpy = XOpenDisplay(device); + if (!priv->dpy) { + av_log(ctx, AV_LOG_ERROR, "Cannot open the X11 display %s.\n", + XDisplayName(device)); + return AVERROR_UNKNOWN; + } + display = XDisplayString(priv->dpy); + + err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy), + &hwctx->device, &hwctx->get_proc_address); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "VDPAU device creation on X11 display %s failed.\n", + display); + return AVERROR_UNKNOWN; + } + + GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); + GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy); + + get_information_string(&vendor); + av_log(ctx, AV_LOG_VERBOSE, "Successfully created a VDPAU device (%s) on " + "X11 display %s\n", vendor, display); + + return 0; +} +#endif + +const HWContextType ff_hwcontext_type_vdpau = { + .type = AV_HWDEVICE_TYPE_VDPAU, + .name = "VDPAU", + + .device_hwctx_size = sizeof(AVVDPAUDeviceContext), + .device_priv_size = sizeof(VDPAUDeviceContext), + .frames_priv_size = sizeof(VDPAUFramesContext), + +#if HAVE_VDPAU_X11 + .device_create = vdpau_device_create, +#endif + .device_init = vdpau_device_init, + .device_uninit = vdpau_device_uninit, + .frames_get_constraints = vdpau_frames_get_constraints, + .frames_init = vdpau_frames_init, + .frames_get_buffer = vdpau_get_buffer, + .transfer_get_formats = vdpau_transfer_get_formats, + .transfer_data_to = vdpau_transfer_data_to, + .transfer_data_from = vdpau_transfer_data_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.h new file mode 100644 index 00000000..1b7ea1e4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vdpau.h @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VDPAU_H +#define AVUTIL_HWCONTEXT_VDPAU_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VDPAU. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a VdpVideoSurface. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVDPAUDeviceContext { + VdpDevice device; + VdpGetProcAddress *get_proc_address; +} AVVDPAUDeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +#endif /* AVUTIL_HWCONTEXT_VDPAU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.c new file mode 100644 index 00000000..b8e6bb40 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.c @@ -0,0 +1,763 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include + +#include "buffer.h" +#include "buffer_internal.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_videotoolbox.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" + +typedef struct VTFramesContext { + CVPixelBufferPoolRef pool; +} VTFramesContext; + +static const struct { + uint32_t cv_fmt; + bool full_range; + enum AVPixelFormat pix_fmt; +} cv_pix_fmts[] = { + { kCVPixelFormatType_420YpCbCr8Planar, false, AV_PIX_FMT_YUV420P }, + { kCVPixelFormatType_422YpCbCr8, false, AV_PIX_FMT_UYVY422 }, + { kCVPixelFormatType_32BGRA, true, AV_PIX_FMT_BGRA }, +#ifdef kCFCoreFoundationVersionNumber10_7 + { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, false, AV_PIX_FMT_NV12 }, + { kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, true, AV_PIX_FMT_NV12 }, + { kCVPixelFormatType_4444AYpCbCr16, false, AV_PIX_FMT_AYUV64 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE + { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, false, AV_PIX_FMT_P010 }, + { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange, true, AV_PIX_FMT_P010 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE + { kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange, false, AV_PIX_FMT_NV16 }, + { kCVPixelFormatType_422YpCbCr8BiPlanarFullRange, true, AV_PIX_FMT_NV16 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE + { kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange, false, AV_PIX_FMT_P210 }, + { kCVPixelFormatType_422YpCbCr10BiPlanarFullRange, true, AV_PIX_FMT_P210 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE + { kCVPixelFormatType_422YpCbCr16BiPlanarVideoRange, false, AV_PIX_FMT_P216 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE + { kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange, false, AV_PIX_FMT_NV24 }, + { kCVPixelFormatType_444YpCbCr8BiPlanarFullRange, true, AV_PIX_FMT_NV24 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE + { kCVPixelFormatType_444YpCbCr10BiPlanarVideoRange, false, AV_PIX_FMT_P410 }, + { kCVPixelFormatType_444YpCbCr10BiPlanarFullRange, true, AV_PIX_FMT_P410 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE + { kCVPixelFormatType_444YpCbCr16BiPlanarVideoRange, false, AV_PIX_FMT_P416 }, +#endif +}; + +static const enum AVPixelFormat supported_formats[] = { +#ifdef kCFCoreFoundationVersionNumber10_7 + AV_PIX_FMT_NV12, + AV_PIX_FMT_AYUV64, +#endif + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_UYVY422, +#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE + AV_PIX_FMT_P010, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE + AV_PIX_FMT_NV16, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE + AV_PIX_FMT_P210, +#endif +#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE + AV_PIX_FMT_P216, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE + AV_PIX_FMT_NV24, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE + AV_PIX_FMT_P410, +#endif +#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE + AV_PIX_FMT_P416, +#endif + AV_PIX_FMT_BGRA, +}; + +static int vt_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) + constraints->valid_sw_formats[i] = supported_formats[i]; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_VIDEOTOOLBOX; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { + if (cv_pix_fmts[i].cv_fmt == cv_fmt) + return cv_pix_fmts[i].pix_fmt; + } + return AV_PIX_FMT_NONE; +} + +uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt) +{ + return av_map_videotoolbox_format_from_pixfmt2(pix_fmt, false); +} + +uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { + if (cv_pix_fmts[i].pix_fmt == pix_fmt && cv_pix_fmts[i].full_range == full_range) + return cv_pix_fmts[i].cv_fmt; + } + return 0; +} + +static int vt_pool_alloc(AVHWFramesContext *ctx) +{ + VTFramesContext *fctx = ctx->internal->priv; + CVReturn err; + CFNumberRef w, h, pixfmt; + uint32_t cv_pixfmt; + CFMutableDictionaryRef attributes, iosurface_properties; + + attributes = CFDictionaryCreateMutable( + NULL, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + cv_pixfmt = av_map_videotoolbox_format_from_pixfmt(ctx->sw_format); + pixfmt = CFNumberCreate(NULL, kCFNumberSInt32Type, &cv_pixfmt); + CFDictionarySetValue( + attributes, + kCVPixelBufferPixelFormatTypeKey, + pixfmt); + CFRelease(pixfmt); + + iosurface_properties = CFDictionaryCreateMutable( + NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(attributes, kCVPixelBufferIOSurfacePropertiesKey, iosurface_properties); + CFRelease(iosurface_properties); + + w = CFNumberCreate(NULL, kCFNumberSInt32Type, &ctx->width); + h = CFNumberCreate(NULL, kCFNumberSInt32Type, &ctx->height); + CFDictionarySetValue(attributes, kCVPixelBufferWidthKey, w); + CFDictionarySetValue(attributes, kCVPixelBufferHeightKey, h); + CFRelease(w); + CFRelease(h); + + err = CVPixelBufferPoolCreate( + NULL, + NULL, + attributes, + &fctx->pool); + CFRelease(attributes); + + if (err == kCVReturnSuccess) + return 0; + + av_log(ctx, AV_LOG_ERROR, "Error creating CVPixelBufferPool: %d\n", err); + return AVERROR_EXTERNAL; +} + +static void videotoolbox_buffer_release(void *opaque, uint8_t *data) +{ + CVPixelBufferRelease((CVPixelBufferRef)data); +} + +static AVBufferRef *vt_pool_alloc_buffer(void *opaque, size_t size) +{ + CVPixelBufferRef pixbuf; + AVBufferRef *buf; + CVReturn err; + AVHWFramesContext *ctx = opaque; + VTFramesContext *fctx = ctx->internal->priv; + + err = CVPixelBufferPoolCreatePixelBuffer( + NULL, + fctx->pool, + &pixbuf + ); + if (err != kCVReturnSuccess) { + av_log(ctx, AV_LOG_ERROR, "Failed to create pixel buffer from pool: %d\n", err); + return NULL; + } + + buf = av_buffer_create((uint8_t *)pixbuf, size, + videotoolbox_buffer_release, NULL, 0); + if (!buf) { + CVPixelBufferRelease(pixbuf); + return NULL; + } + return buf; +} + +static void vt_frames_uninit(AVHWFramesContext *ctx) +{ + VTFramesContext *fctx = ctx->internal->priv; + if (fctx->pool) { + CVPixelBufferPoolRelease(fctx->pool); + fctx->pool = NULL; + } +} + +static int vt_frames_init(AVHWFramesContext *ctx) +{ + int i, ret; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i]) + break; + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(ENOSYS); + } + + if (!ctx->pool) { + ctx->internal->pool_internal = av_buffer_pool_init2( + sizeof(CVPixelBufferRef), ctx, vt_pool_alloc_buffer, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + } + + ret = vt_pool_alloc(ctx); + if (ret < 0) + return ret; + + return 0; +} + +static int vt_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VIDEOTOOLBOX; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int vt_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + return 0; +} + +static void vt_unmap(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) +{ + CVPixelBufferRef pixbuf = (CVPixelBufferRef)hwmap->source->data[3]; + + CVPixelBufferUnlockBaseAddress(pixbuf, (uintptr_t)hwmap->priv); +} + +static int vt_pixbuf_set_par(void *log_ctx, + CVPixelBufferRef pixbuf, const AVFrame *src) +{ + CFMutableDictionaryRef par = NULL; + CFNumberRef num = NULL, den = NULL; + AVRational avpar = src->sample_aspect_ratio; + + if (avpar.num == 0) + return 0; + + av_reduce(&avpar.num, &avpar.den, + avpar.num, avpar.den, + 0xFFFFFFFF); + + num = CFNumberCreate(kCFAllocatorDefault, + kCFNumberIntType, + &avpar.num); + + den = CFNumberCreate(kCFAllocatorDefault, + kCFNumberIntType, + &avpar.den); + + par = CFDictionaryCreateMutable(kCFAllocatorDefault, + 2, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (!par || !num || !den) { + if (par) CFRelease(par); + if (num) CFRelease(num); + if (den) CFRelease(den); + return AVERROR(ENOMEM); + } + + CFDictionarySetValue( + par, + kCVImageBufferPixelAspectRatioHorizontalSpacingKey, + num); + CFDictionarySetValue( + par, + kCVImageBufferPixelAspectRatioVerticalSpacingKey, + den); + + CVBufferSetAttachment( + pixbuf, + kCVImageBufferPixelAspectRatioKey, + par, + kCVAttachmentMode_ShouldPropagate + ); + + CFRelease(par); + CFRelease(num); + CFRelease(den); + + return 0; +} + +CFStringRef av_map_videotoolbox_chroma_loc_from_av(enum AVChromaLocation loc) +{ + switch (loc) { + case AVCHROMA_LOC_LEFT: + return kCVImageBufferChromaLocation_Left; + case AVCHROMA_LOC_CENTER: + return kCVImageBufferChromaLocation_Center; + case AVCHROMA_LOC_TOP: + return kCVImageBufferChromaLocation_Top; + case AVCHROMA_LOC_BOTTOM: + return kCVImageBufferChromaLocation_Bottom; + case AVCHROMA_LOC_TOPLEFT: + return kCVImageBufferChromaLocation_TopLeft; + case AVCHROMA_LOC_BOTTOMLEFT: + return kCVImageBufferChromaLocation_BottomLeft; + default: + return NULL; + } +} + +static int vt_pixbuf_set_chromaloc(void *log_ctx, + CVPixelBufferRef pixbuf, const AVFrame *src) +{ + CFStringRef loc = av_map_videotoolbox_chroma_loc_from_av(src->chroma_location); + + if (loc) { + CVBufferSetAttachment( + pixbuf, + kCVImageBufferChromaLocationTopFieldKey, + loc, + kCVAttachmentMode_ShouldPropagate); + } + + return 0; +} + +CFStringRef av_map_videotoolbox_color_matrix_from_av(enum AVColorSpace space) +{ + switch (space) { + case AVCOL_SPC_BT2020_CL: + case AVCOL_SPC_BT2020_NCL: +#if HAVE_KCVIMAGEBUFFERYCBCRMATRIX_ITU_R_2020 + if (__builtin_available(macOS 10.11, iOS 9, *)) + return kCVImageBufferYCbCrMatrix_ITU_R_2020; +#endif + return CFSTR("ITU_R_2020"); + case AVCOL_SPC_BT470BG: + case AVCOL_SPC_SMPTE170M: + return kCVImageBufferYCbCrMatrix_ITU_R_601_4; + case AVCOL_SPC_BT709: + return kCVImageBufferYCbCrMatrix_ITU_R_709_2; + case AVCOL_SPC_SMPTE240M: + return kCVImageBufferYCbCrMatrix_SMPTE_240M_1995; + default: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG + if (__builtin_available(macOS 10.13, iOS 11, tvOS 11, watchOS 4, *)) + return CVYCbCrMatrixGetStringForIntegerCodePoint(space); +#endif + case AVCOL_SPC_UNSPECIFIED: + return NULL; + } +} + +CFStringRef av_map_videotoolbox_color_primaries_from_av(enum AVColorPrimaries pri) +{ + switch (pri) { + case AVCOL_PRI_BT2020: +#if HAVE_KCVIMAGEBUFFERCOLORPRIMARIES_ITU_R_2020 + if (__builtin_available(macOS 10.11, iOS 9, *)) + return kCVImageBufferColorPrimaries_ITU_R_2020; +#endif + return CFSTR("ITU_R_2020"); + case AVCOL_PRI_BT709: + return kCVImageBufferColorPrimaries_ITU_R_709_2; + case AVCOL_PRI_SMPTE170M: + return kCVImageBufferColorPrimaries_SMPTE_C; + case AVCOL_PRI_BT470BG: + return kCVImageBufferColorPrimaries_EBU_3213; + default: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG + if (__builtin_available(macOS 10.13, iOS 11, tvOS 11, watchOS 4, *)) + return CVColorPrimariesGetStringForIntegerCodePoint(pri); +#endif + case AVCOL_PRI_UNSPECIFIED: + return NULL; + } +} + +CFStringRef av_map_videotoolbox_color_trc_from_av(enum AVColorTransferCharacteristic trc) +{ + + switch (trc) { + case AVCOL_TRC_SMPTE2084: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ + if (__builtin_available(macOS 10.13, iOS 11, *)) + return kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ; +#endif + return CFSTR("SMPTE_ST_2084_PQ"); + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2020 + if (__builtin_available(macOS 10.11, iOS 9, *)) + return kCVImageBufferTransferFunction_ITU_R_2020; +#endif + return CFSTR("ITU_R_2020"); + case AVCOL_TRC_BT709: + return kCVImageBufferTransferFunction_ITU_R_709_2; + case AVCOL_TRC_SMPTE240M: + return kCVImageBufferTransferFunction_SMPTE_240M_1995; + case AVCOL_TRC_SMPTE428: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_428_1 + if (__builtin_available(macOS 10.12, iOS 10, *)) + return kCVImageBufferTransferFunction_SMPTE_ST_428_1; +#endif + return CFSTR("SMPTE_ST_428_1"); + case AVCOL_TRC_ARIB_STD_B67: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG + if (__builtin_available(macOS 10.13, iOS 11, *)) + return kCVImageBufferTransferFunction_ITU_R_2100_HLG; +#endif + return CFSTR("ITU_R_2100_HLG"); + case AVCOL_TRC_GAMMA22: + return kCVImageBufferTransferFunction_UseGamma; + case AVCOL_TRC_GAMMA28: + return kCVImageBufferTransferFunction_UseGamma; + default: +#if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG + if (__builtin_available(macOS 10.13, iOS 11, tvOS 11, watchOS 4, *)) + return CVTransferFunctionGetStringForIntegerCodePoint(trc); +#endif + case AVCOL_TRC_UNSPECIFIED: + return NULL; + } +} + +static int vt_pixbuf_set_colorspace(void *log_ctx, + CVPixelBufferRef pixbuf, const AVFrame *src) +{ + CFStringRef colormatrix = NULL, colorpri = NULL, colortrc = NULL; + Float32 gamma = 0; + + colormatrix = av_map_videotoolbox_color_matrix_from_av(src->colorspace); + if (!colormatrix && src->colorspace != AVCOL_SPC_UNSPECIFIED) + av_log(log_ctx, AV_LOG_WARNING, "Color space %s is not supported.\n", av_color_space_name(src->colorspace)); + + colorpri = av_map_videotoolbox_color_primaries_from_av(src->color_primaries); + if (!colorpri && src->color_primaries != AVCOL_PRI_UNSPECIFIED) + av_log(log_ctx, AV_LOG_WARNING, "Color primaries %s is not supported.\n", av_color_primaries_name(src->color_primaries)); + + colortrc = av_map_videotoolbox_color_trc_from_av(src->color_trc); + if (!colortrc && src->color_trc != AVCOL_TRC_UNSPECIFIED) + av_log(log_ctx, AV_LOG_WARNING, "Color transfer function %s is not supported.\n", av_color_transfer_name(src->color_trc)); + + if (src->color_trc == AVCOL_TRC_GAMMA22) + gamma = 2.2; + else if (src->color_trc == AVCOL_TRC_GAMMA28) + gamma = 2.8; + + if (colormatrix) { + CVBufferSetAttachment( + pixbuf, + kCVImageBufferYCbCrMatrixKey, + colormatrix, + kCVAttachmentMode_ShouldPropagate); + } + if (colorpri) { + CVBufferSetAttachment( + pixbuf, + kCVImageBufferColorPrimariesKey, + colorpri, + kCVAttachmentMode_ShouldPropagate); + } + if (colortrc) { + CVBufferSetAttachment( + pixbuf, + kCVImageBufferTransferFunctionKey, + colortrc, + kCVAttachmentMode_ShouldPropagate); + } + if (gamma != 0) { + CFNumberRef gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma); + CVBufferSetAttachment( + pixbuf, + kCVImageBufferGammaLevelKey, + gamma_level, + kCVAttachmentMode_ShouldPropagate); + CFRelease(gamma_level); + } + + return 0; +} + +static int vt_pixbuf_set_attachments(void *log_ctx, + CVPixelBufferRef pixbuf, const AVFrame *src) +{ + int ret; + ret = vt_pixbuf_set_par(log_ctx, pixbuf, src); + if (ret < 0) + return ret; + ret = vt_pixbuf_set_colorspace(log_ctx, pixbuf, src); + if (ret < 0) + return ret; + ret = vt_pixbuf_set_chromaloc(log_ctx, pixbuf, src); + if (ret < 0) + return ret; + return 0; +} + +int av_vt_pixbuf_set_attachments(void *log_ctx, + CVPixelBufferRef pixbuf, const AVFrame *src) +{ + return vt_pixbuf_set_attachments(log_ctx, pixbuf, src); +} + +static int vt_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, + int flags) +{ + CVPixelBufferRef pixbuf = (CVPixelBufferRef)src->data[3]; + OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf); + CVReturn err; + uint32_t map_flags = 0; + int ret; + int i; + enum AVPixelFormat format; + + format = av_map_videotoolbox_format_to_pixfmt(pixel_format); + if (dst->format != format) { + av_log(ctx, AV_LOG_ERROR, "Unsupported or mismatching pixel format: %s\n", + av_fourcc2str(pixel_format)); + return AVERROR_UNKNOWN; + } + + if (CVPixelBufferGetWidth(pixbuf) != ctx->width || + CVPixelBufferGetHeight(pixbuf) != ctx->height) { + av_log(ctx, AV_LOG_ERROR, "Inconsistent frame dimensions.\n"); + return AVERROR_UNKNOWN; + } + + if (flags == AV_HWFRAME_MAP_READ) + map_flags = kCVPixelBufferLock_ReadOnly; + + err = CVPixelBufferLockBaseAddress(pixbuf, map_flags); + if (err != kCVReturnSuccess) { + av_log(ctx, AV_LOG_ERROR, "Error locking the pixel buffer.\n"); + return AVERROR_UNKNOWN; + } + + if (CVPixelBufferIsPlanar(pixbuf)) { + int planes = CVPixelBufferGetPlaneCount(pixbuf); + for (i = 0; i < planes; i++) { + dst->data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i); + dst->linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i); + } + } else { + dst->data[0] = CVPixelBufferGetBaseAddress(pixbuf); + dst->linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf); + } + + ret = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, vt_unmap, + (void *)(uintptr_t)map_flags); + if (ret < 0) + goto unlock; + + return 0; + +unlock: + CVPixelBufferUnlockBaseAddress(pixbuf, map_flags); + return ret; +} + +static int vt_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = vt_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vt_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = vt_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = vt_pixbuf_set_attachments(hwfc, (CVPixelBufferRef)dst->data[3], src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vt_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (dst->format == AV_PIX_FMT_NONE) + dst->format = hwfc->sw_format; + else if (dst->format != hwfc->sw_format) + return AVERROR(ENOSYS); + + err = vt_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + dst->width = src->width; + dst->height = src->height; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +static int vt_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + if (device && device[0]) { + av_log(ctx, AV_LOG_ERROR, "Device selection unsupported.\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_videotoolbox = { + .type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX, + .name = "videotoolbox", + + .frames_priv_size = sizeof(VTFramesContext), + + .device_create = vt_device_create, + .frames_init = vt_frames_init, + .frames_get_buffer = vt_get_buffer, + .frames_get_constraints = vt_frames_get_constraints, + .frames_uninit = vt_frames_uninit, + .transfer_get_formats = vt_transfer_get_formats, + .transfer_data_to = vt_transfer_data_to, + .transfer_data_from = vt_transfer_data_from, + .map_from = vt_map_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VIDEOTOOLBOX, AV_PIX_FMT_NONE }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.h new file mode 100644 index 00000000..25dde85d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_videotoolbox.h @@ -0,0 +1,96 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H +#define AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H + +#include + +#include + +#include "frame.h" +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX. + * + * This API supports frame allocation using a native CVPixelBufferPool + * instead of an AVBufferPool. + * + * If the API user sets a custom pool, AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CVImageBufferRef or CVPixelBufferRef. + * Note that the underlying CVPixelBuffer could be retained by OS frameworks + * depending on application usage, so it is preferable to let CoreVideo manage + * the pool using the default implementation. + * + * Currently AVHWDeviceContext.hwctx and AVHWFramesContext.hwctx are always + * NULL. + */ + +/** + * Convert a VideoToolbox (actually CoreVideo) format to AVPixelFormat. + * Returns AV_PIX_FMT_NONE if no known equivalent was found. + */ +enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt); + +/** + * Convert an AVPixelFormat to a VideoToolbox (actually CoreVideo) format. + * Returns 0 if no known equivalent was found. + */ +uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); + +/** + * Same as av_map_videotoolbox_format_from_pixfmt function, but can map and + * return full range pixel formats via a flag. + */ +uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range); + +/** + * Convert an AVChromaLocation to a VideoToolbox/CoreVideo chroma location string. + * Returns 0 if no known equivalent was found. + */ +CFStringRef av_map_videotoolbox_chroma_loc_from_av(enum AVChromaLocation loc); + +/** + * Convert an AVColorSpace to a VideoToolbox/CoreVideo color matrix string. + * Returns 0 if no known equivalent was found. + */ +CFStringRef av_map_videotoolbox_color_matrix_from_av(enum AVColorSpace space); + +/** + * Convert an AVColorPrimaries to a VideoToolbox/CoreVideo color primaries string. + * Returns 0 if no known equivalent was found. + */ +CFStringRef av_map_videotoolbox_color_primaries_from_av(enum AVColorPrimaries pri); + +/** + * Convert an AVColorTransferCharacteristic to a VideoToolbox/CoreVideo color transfer + * function string. + * Returns 0 if no known equivalent was found. + */ +CFStringRef av_map_videotoolbox_color_trc_from_av(enum AVColorTransferCharacteristic trc); + +/** + * Update a CVPixelBufferRef's metadata to based on an AVFrame. + * Returns 0 if no known equivalent was found. + */ +int av_vt_pixbuf_set_attachments(void *log_ctx, + CVPixelBufferRef pixbuf, const struct AVFrame *src); + +#endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.c b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.c new file mode 100644 index 00000000..2a9b5f4a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.c @@ -0,0 +1,4168 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define VK_NO_PROTOTYPES +#define VK_ENABLE_BETA_EXTENSIONS + +#ifdef _WIN32 +#include /* Included to prevent conflicts with CreateSemaphore */ +#include +#include "compat/w32dlfcn.h" +#else +#include +#endif + +#include + +#include "config.h" +#include "pixdesc.h" +#include "avstring.h" +#include "imgutils.h" +#include "hwcontext.h" +#include "avassert.h" +#include "hwcontext_internal.h" +#include "hwcontext_vulkan.h" + +#include "vulkan.h" +#include "vulkan_loader.h" + +#if CONFIG_LIBDRM +#include +#include +#include "hwcontext_drm.h" +#if CONFIG_VAAPI +#include +#include "hwcontext_vaapi.h" +#endif +#endif + +#if CONFIG_CUDA +#include "hwcontext_cuda_internal.h" +#include "cuda_check.h" +#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x) +#endif + +typedef struct VulkanQueueCtx { + VkFence fence; + VkQueue queue; + int was_synchronous; + + /* Buffer dependencies */ + AVBufferRef **buf_deps; + int nb_buf_deps; + int buf_deps_alloc_size; +} VulkanQueueCtx; + +typedef struct VulkanExecCtx { + VkCommandPool pool; + VkCommandBuffer *bufs; + VulkanQueueCtx *queues; + int nb_queues; + int cur_queue_idx; +} VulkanExecCtx; + +typedef struct VulkanDevicePriv { + /* Vulkan library and loader functions */ + void *libvulkan; + FFVulkanFunctions vkfn; + + /* Properties */ + VkPhysicalDeviceProperties2 props; + VkPhysicalDeviceMemoryProperties mprops; + VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops; + + /* Features */ + VkPhysicalDeviceVulkan11Features device_features_1_1; + VkPhysicalDeviceVulkan12Features device_features_1_2; + + /* Queues */ + uint32_t qfs[5]; + int num_qfs; + + /* Debug callback */ + VkDebugUtilsMessengerEXT debug_ctx; + + /* Extensions */ + FFVulkanExtensions extensions; + + /* Settings */ + int use_linear_images; + + /* Option to allocate all image planes in a single allocation */ + int contiguous_planes; + + /* Nvidia */ + int dev_is_nvidia; + + /* Intel */ + int dev_is_intel; +} VulkanDevicePriv; + +typedef struct VulkanFramesPriv { + /* Image conversions */ + VulkanExecCtx conv_ctx; + + /* Image transfers */ + VulkanExecCtx upload_ctx; + VulkanExecCtx download_ctx; + + /* Modifier info list to free at uninit */ + VkImageDrmFormatModifierListCreateInfoEXT *modifier_info; +} VulkanFramesPriv; + +typedef struct AVVkFrameInternal { +#if CONFIG_CUDA + /* Importing external memory into cuda is really expensive so we keep the + * memory imported all the time */ + AVBufferRef *cuda_fc_ref; /* Need to keep it around for uninit */ + CUexternalMemory ext_mem[AV_NUM_DATA_POINTERS]; + CUmipmappedArray cu_mma[AV_NUM_DATA_POINTERS]; + CUarray cu_array[AV_NUM_DATA_POINTERS]; + CUexternalSemaphore cu_sem[AV_NUM_DATA_POINTERS]; +#ifdef _WIN32 + HANDLE ext_mem_handle[AV_NUM_DATA_POINTERS]; + HANDLE ext_sem_handle[AV_NUM_DATA_POINTERS]; +#endif +#endif +} AVVkFrameInternal; + +#define ADD_VAL_TO_LIST(list, count, val) \ + do { \ + list = av_realloc_array(list, sizeof(*list), ++count); \ + if (!list) { \ + err = AVERROR(ENOMEM); \ + goto fail; \ + } \ + list[count - 1] = av_strdup(val); \ + if (!list[count - 1]) { \ + err = AVERROR(ENOMEM); \ + goto fail; \ + } \ + } while(0) + +#define RELEASE_PROPS(props, count) \ + if (props) { \ + for (int i = 0; i < count; i++) \ + av_free((void *)((props)[i])); \ + av_free((void *)props); \ + } + +static const struct { + enum AVPixelFormat pixfmt; + const VkFormat vkfmts[4]; +} vk_pixfmt_map[] = { + { AV_PIX_FMT_GRAY8, { VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_GRAY16, { VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_GRAYF32, { VK_FORMAT_R32_SFLOAT } }, + + { AV_PIX_FMT_NV12, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_NV21, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_P010, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } }, + { AV_PIX_FMT_P012, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } }, + { AV_PIX_FMT_P016, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM } }, + + { AV_PIX_FMT_NV16, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + + { AV_PIX_FMT_NV24, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + { AV_PIX_FMT_NV42, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, + + { AV_PIX_FMT_YUV420P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV420P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV420P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV420P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUV422P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV422P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV422P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV422P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUV444P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUV444P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV444P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUV444P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUVA420P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA420P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + /* There is no AV_PIX_FMT_YUVA420P12 */ + { AV_PIX_FMT_YUVA420P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUVA422P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA422P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA422P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA422P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_YUVA444P, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_YUVA444P10, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA444P12, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_YUVA444P16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + + { AV_PIX_FMT_VUYX, { VK_FORMAT_R8G8B8A8_UNORM } }, + { AV_PIX_FMT_XV36, { VK_FORMAT_R16G16B16A16_UNORM } }, + + { AV_PIX_FMT_BGRA, { VK_FORMAT_B8G8R8A8_UNORM } }, + { AV_PIX_FMT_RGBA, { VK_FORMAT_R8G8B8A8_UNORM } }, + { AV_PIX_FMT_RGB24, { VK_FORMAT_R8G8B8_UNORM } }, + { AV_PIX_FMT_BGR24, { VK_FORMAT_B8G8R8_UNORM } }, + { AV_PIX_FMT_RGB48, { VK_FORMAT_R16G16B16_UNORM } }, + { AV_PIX_FMT_RGBA64, { VK_FORMAT_R16G16B16A16_UNORM } }, + { AV_PIX_FMT_RGBA64, { VK_FORMAT_R16G16B16A16_UNORM } }, + { AV_PIX_FMT_RGB565, { VK_FORMAT_R5G6B5_UNORM_PACK16 } }, + { AV_PIX_FMT_BGR565, { VK_FORMAT_B5G6R5_UNORM_PACK16 } }, + { AV_PIX_FMT_BGR0, { VK_FORMAT_B8G8R8A8_UNORM } }, + { AV_PIX_FMT_RGB0, { VK_FORMAT_R8G8B8A8_UNORM } }, + + /* Lower priority as there's an endianess-dependent overlap between these + * and rgba/bgr0, and PACK32 formats are more limited */ + { AV_PIX_FMT_BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + { AV_PIX_FMT_0BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + + { AV_PIX_FMT_X2RGB10, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } }, + + { AV_PIX_FMT_GBRAP, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { AV_PIX_FMT_GBRAP16, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { AV_PIX_FMT_GBRPF32, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, + { AV_PIX_FMT_GBRAPF32, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, +}; + +const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p) +{ + for (enum AVPixelFormat i = 0; i < FF_ARRAY_ELEMS(vk_pixfmt_map); i++) + if (vk_pixfmt_map[i].pixfmt == p) + return vk_pixfmt_map[i].vkfmts; + return NULL; +} + +static const void *vk_find_struct(const void *chain, VkStructureType stype) +{ + const VkBaseInStructure *in = chain; + while (in) { + if (in->sType == stype) + return in; + + in = in->pNext; + } + + return NULL; +} + +static void vk_link_struct(void *chain, void *in) +{ + VkBaseOutStructure *out = chain; + if (!in) + return; + + while (out->pNext) + out = out->pNext; + + out->pNext = in; +} + +static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, + int linear) +{ + AVVulkanDeviceContext *hwctx = dev_ctx->hwctx; + VulkanDevicePriv *priv = dev_ctx->internal->priv; + FFVulkanFunctions *vk = &priv->vkfn; + const VkFormat *fmt = av_vkfmt_from_pixfmt(p); + int planes = av_pix_fmt_count_planes(p); + + if (!fmt) + return 0; + + for (int i = 0; i < planes; i++) { + VkFormatFeatureFlags flags; + VkFormatProperties2 prop = { + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + }; + vk->GetPhysicalDeviceFormatProperties2(hwctx->phys_dev, fmt[i], &prop); + flags = linear ? prop.formatProperties.linearTilingFeatures : + prop.formatProperties.optimalTilingFeatures; + if (!(flags & FF_VK_DEFAULT_USAGE_FLAGS)) + return 0; + } + + return 1; +} + +static int load_libvulkan(AVHWDeviceContext *ctx) +{ + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + + static const char *lib_names[] = { +#if defined(_WIN32) + "vulkan-1.dll", +#elif defined(__APPLE__) + "libvulkan.dylib", + "libvulkan.1.dylib", + "libMoltenVK.dylib", +#else + "libvulkan.so.1", + "libvulkan.so", +#endif + }; + + for (int i = 0; i < FF_ARRAY_ELEMS(lib_names); i++) { + p->libvulkan = dlopen(lib_names[i], RTLD_NOW | RTLD_LOCAL); + if (p->libvulkan) + break; + } + + if (!p->libvulkan) { + av_log(ctx, AV_LOG_ERROR, "Unable to open the libvulkan library!\n"); + return AVERROR_UNKNOWN; + } + + hwctx->get_proc_addr = (PFN_vkGetInstanceProcAddr)dlsym(p->libvulkan, "vkGetInstanceProcAddr"); + + return 0; +} + +typedef struct VulkanOptExtension { + const char *name; + FFVulkanExtensions flag; +} VulkanOptExtension; + +static const VulkanOptExtension optional_instance_exts[] = { + /* For future use */ +}; + +static const VulkanOptExtension optional_device_exts[] = { + /* Misc or required by other extensions */ + { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_NO_FLAG }, + { VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, FF_VK_EXT_NO_FLAG }, + { VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, FF_VK_EXT_NO_FLAG }, + + /* Imports/exports */ + { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY }, + { VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY }, + { VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS }, + { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM }, + { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY }, +#ifdef _WIN32 + { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY }, + { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM }, +#endif +}; + +/* Converts return values to strings */ +static const char *vk_ret2str(VkResult res) +{ +#define CASE(VAL) case VAL: return #VAL + switch (res) { + CASE(VK_SUCCESS); + CASE(VK_NOT_READY); + CASE(VK_TIMEOUT); + CASE(VK_EVENT_SET); + CASE(VK_EVENT_RESET); + CASE(VK_INCOMPLETE); + CASE(VK_ERROR_OUT_OF_HOST_MEMORY); + CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY); + CASE(VK_ERROR_INITIALIZATION_FAILED); + CASE(VK_ERROR_DEVICE_LOST); + CASE(VK_ERROR_MEMORY_MAP_FAILED); + CASE(VK_ERROR_LAYER_NOT_PRESENT); + CASE(VK_ERROR_EXTENSION_NOT_PRESENT); + CASE(VK_ERROR_FEATURE_NOT_PRESENT); + CASE(VK_ERROR_INCOMPATIBLE_DRIVER); + CASE(VK_ERROR_TOO_MANY_OBJECTS); + CASE(VK_ERROR_FORMAT_NOT_SUPPORTED); + CASE(VK_ERROR_FRAGMENTED_POOL); + CASE(VK_ERROR_SURFACE_LOST_KHR); + CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); + CASE(VK_SUBOPTIMAL_KHR); + CASE(VK_ERROR_OUT_OF_DATE_KHR); + CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); + CASE(VK_ERROR_VALIDATION_FAILED_EXT); + CASE(VK_ERROR_INVALID_SHADER_NV); + CASE(VK_ERROR_OUT_OF_POOL_MEMORY); + CASE(VK_ERROR_INVALID_EXTERNAL_HANDLE); + CASE(VK_ERROR_NOT_PERMITTED_EXT); + CASE(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); + CASE(VK_ERROR_INVALID_DEVICE_ADDRESS_EXT); + CASE(VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT); + default: return "Unknown error"; + } +#undef CASE +} + +static VkBool32 vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT *data, + void *priv) +{ + int l; + AVHWDeviceContext *ctx = priv; + + switch (severity) { + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: l = AV_LOG_VERBOSE; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: l = AV_LOG_INFO; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: l = AV_LOG_WARNING; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: l = AV_LOG_ERROR; break; + default: l = AV_LOG_DEBUG; break; + } + + av_log(ctx, l, "%s\n", data->pMessage); + for (int i = 0; i < data->cmdBufLabelCount; i++) + av_log(ctx, l, "\t%i: %s\n", i, data->pCmdBufLabels[i].pLabelName); + + return 0; +} + +static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts, + const char * const **dst, uint32_t *num, int debug) +{ + const char *tstr; + const char **extension_names = NULL; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + int err = 0, found, extensions_found = 0; + + const char *mod; + int optional_exts_num; + uint32_t sup_ext_count; + char *user_exts_str = NULL; + AVDictionaryEntry *user_exts; + VkExtensionProperties *sup_ext; + const VulkanOptExtension *optional_exts; + + if (!dev) { + mod = "instance"; + optional_exts = optional_instance_exts; + optional_exts_num = FF_ARRAY_ELEMS(optional_instance_exts); + user_exts = av_dict_get(opts, "instance_extensions", NULL, 0); + if (user_exts) { + user_exts_str = av_strdup(user_exts->value); + if (!user_exts_str) { + err = AVERROR(ENOMEM); + goto fail; + } + } + vk->EnumerateInstanceExtensionProperties(NULL, &sup_ext_count, NULL); + sup_ext = av_malloc_array(sup_ext_count, sizeof(VkExtensionProperties)); + if (!sup_ext) + return AVERROR(ENOMEM); + vk->EnumerateInstanceExtensionProperties(NULL, &sup_ext_count, sup_ext); + } else { + mod = "device"; + optional_exts = optional_device_exts; + optional_exts_num = FF_ARRAY_ELEMS(optional_device_exts); + user_exts = av_dict_get(opts, "device_extensions", NULL, 0); + if (user_exts) { + user_exts_str = av_strdup(user_exts->value); + if (!user_exts_str) { + err = AVERROR(ENOMEM); + goto fail; + } + } + vk->EnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL, + &sup_ext_count, NULL); + sup_ext = av_malloc_array(sup_ext_count, sizeof(VkExtensionProperties)); + if (!sup_ext) + return AVERROR(ENOMEM); + vk->EnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL, + &sup_ext_count, sup_ext); + } + + for (int i = 0; i < optional_exts_num; i++) { + tstr = optional_exts[i].name; + found = 0; + for (int j = 0; j < sup_ext_count; j++) { + if (!strcmp(tstr, sup_ext[j].extensionName)) { + found = 1; + break; + } + } + if (!found) + continue; + + av_log(ctx, AV_LOG_VERBOSE, "Using %s extension %s\n", mod, tstr); + p->extensions |= optional_exts[i].flag; + ADD_VAL_TO_LIST(extension_names, extensions_found, tstr); + } + + if (debug && !dev) { + tstr = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; + found = 0; + for (int j = 0; j < sup_ext_count; j++) { + if (!strcmp(tstr, sup_ext[j].extensionName)) { + found = 1; + break; + } + } + if (found) { + av_log(ctx, AV_LOG_VERBOSE, "Using %s extension %s\n", mod, tstr); + ADD_VAL_TO_LIST(extension_names, extensions_found, tstr); + p->extensions |= FF_VK_EXT_DEBUG_UTILS; + } else { + av_log(ctx, AV_LOG_ERROR, "Debug extension \"%s\" not found!\n", + tstr); + err = AVERROR(EINVAL); + goto fail; + } + } + + if (user_exts_str) { + char *save, *token = av_strtok(user_exts_str, "+", &save); + while (token) { + found = 0; + for (int j = 0; j < sup_ext_count; j++) { + if (!strcmp(token, sup_ext[j].extensionName)) { + found = 1; + break; + } + } + if (found) { + av_log(ctx, AV_LOG_VERBOSE, "Using %s extension \"%s\"\n", mod, token); + ADD_VAL_TO_LIST(extension_names, extensions_found, token); + } else { + av_log(ctx, AV_LOG_WARNING, "%s extension \"%s\" not found, excluding.\n", + mod, token); + } + token = av_strtok(NULL, "+", &save); + } + } + + *dst = extension_names; + *num = extensions_found; + + av_free(user_exts_str); + av_free(sup_ext); + return 0; + +fail: + RELEASE_PROPS(extension_names, extensions_found); + av_free(user_exts_str); + av_free(sup_ext); + return err; +} + +static int check_validation_layers(AVHWDeviceContext *ctx, AVDictionary *opts, + const char * const **dst, uint32_t *num, + int *debug_mode) +{ + static const char default_layer[] = { "VK_LAYER_KHRONOS_validation" }; + + int found = 0, err = 0; + VulkanDevicePriv *priv = ctx->internal->priv; + FFVulkanFunctions *vk = &priv->vkfn; + + uint32_t sup_layer_count; + VkLayerProperties *sup_layers; + + AVDictionaryEntry *user_layers; + char *user_layers_str = NULL; + char *save, *token; + + const char **enabled_layers = NULL; + uint32_t enabled_layers_count = 0; + + AVDictionaryEntry *debug_opt = av_dict_get(opts, "debug", NULL, 0); + int debug = debug_opt && strtol(debug_opt->value, NULL, 10); + + /* If `debug=0`, enable no layers at all. */ + if (debug_opt && !debug) + return 0; + + vk->EnumerateInstanceLayerProperties(&sup_layer_count, NULL); + sup_layers = av_malloc_array(sup_layer_count, sizeof(VkLayerProperties)); + if (!sup_layers) + return AVERROR(ENOMEM); + vk->EnumerateInstanceLayerProperties(&sup_layer_count, sup_layers); + + av_log(ctx, AV_LOG_VERBOSE, "Supported validation layers:\n"); + for (int i = 0; i < sup_layer_count; i++) + av_log(ctx, AV_LOG_VERBOSE, "\t%s\n", sup_layers[i].layerName); + + /* If `debug=1` is specified, enable the standard validation layer extension */ + if (debug) { + *debug_mode = debug; + for (int i = 0; i < sup_layer_count; i++) { + if (!strcmp(default_layer, sup_layers[i].layerName)) { + found = 1; + av_log(ctx, AV_LOG_VERBOSE, "Default validation layer %s is enabled\n", + default_layer); + ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, default_layer); + break; + } + } + } + + user_layers = av_dict_get(opts, "validation_layers", NULL, 0); + if (!user_layers) + goto end; + + user_layers_str = av_strdup(user_layers->value); + if (!user_layers_str) { + err = AVERROR(ENOMEM); + goto fail; + } + + token = av_strtok(user_layers_str, "+", &save); + while (token) { + found = 0; + if (!strcmp(default_layer, token)) { + if (debug) { + /* if the `debug=1`, default_layer is enabled, skip here */ + token = av_strtok(NULL, "+", &save); + continue; + } else { + /* if the `debug=0`, enable debug mode to load its callback properly */ + *debug_mode = debug; + } + } + for (int j = 0; j < sup_layer_count; j++) { + if (!strcmp(token, sup_layers[j].layerName)) { + found = 1; + break; + } + } + if (found) { + av_log(ctx, AV_LOG_VERBOSE, "Requested Validation Layer: %s\n", token); + ADD_VAL_TO_LIST(enabled_layers, enabled_layers_count, token); + } else { + av_log(ctx, AV_LOG_ERROR, + "Validation Layer \"%s\" not support.\n", token); + err = AVERROR(EINVAL); + goto fail; + } + token = av_strtok(NULL, "+", &save); + } + + av_free(user_layers_str); + +end: + av_free(sup_layers); + + *dst = enabled_layers; + *num = enabled_layers_count; + + return 0; + +fail: + RELEASE_PROPS(enabled_layers, enabled_layers_count); + av_free(sup_layers); + av_free(user_layers_str); + return err; +} + +/* Creates a VkInstance */ +static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts) +{ + int err = 0, debug_mode = 0; + VkResult ret; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VkApplicationInfo application_info = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pEngineName = "libavutil", + .apiVersion = VK_API_VERSION_1_2, + .engineVersion = VK_MAKE_VERSION(LIBAVUTIL_VERSION_MAJOR, + LIBAVUTIL_VERSION_MINOR, + LIBAVUTIL_VERSION_MICRO), + }; + VkInstanceCreateInfo inst_props = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pApplicationInfo = &application_info, + }; + + if (!hwctx->get_proc_addr) { + err = load_libvulkan(ctx); + if (err < 0) + return err; + } + + err = ff_vk_load_functions(ctx, vk, p->extensions, 0, 0); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Unable to load instance enumeration functions!\n"); + return err; + } + + err = check_validation_layers(ctx, opts, &inst_props.ppEnabledLayerNames, + &inst_props.enabledLayerCount, &debug_mode); + if (err) + goto fail; + + /* Check for present/missing extensions */ + err = check_extensions(ctx, 0, opts, &inst_props.ppEnabledExtensionNames, + &inst_props.enabledExtensionCount, debug_mode); + hwctx->enabled_inst_extensions = inst_props.ppEnabledExtensionNames; + hwctx->nb_enabled_inst_extensions = inst_props.enabledExtensionCount; + if (err < 0) + goto fail; + + /* Try to create the instance */ + ret = vk->CreateInstance(&inst_props, hwctx->alloc, &hwctx->inst); + + /* Check for errors */ + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Instance creation failure: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + err = ff_vk_load_functions(ctx, vk, p->extensions, 1, 0); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Unable to load instance functions!\n"); + goto fail; + } + + if (debug_mode) { + VkDebugUtilsMessengerCreateInfoEXT dbg = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, + .pfnUserCallback = vk_dbg_callback, + .pUserData = ctx, + }; + + vk->CreateDebugUtilsMessengerEXT(hwctx->inst, &dbg, + hwctx->alloc, &p->debug_ctx); + } + + err = 0; + +fail: + RELEASE_PROPS(inst_props.ppEnabledLayerNames, inst_props.enabledLayerCount); + return err; +} + +typedef struct VulkanDeviceSelection { + uint8_t uuid[VK_UUID_SIZE]; /* Will use this first unless !has_uuid */ + int has_uuid; + const char *name; /* Will use this second unless NULL */ + uint32_t pci_device; /* Will use this third unless 0x0 */ + uint32_t vendor_id; /* Last resort to find something deterministic */ + int index; /* Finally fall back to index */ +} VulkanDeviceSelection; + +static const char *vk_dev_type(enum VkPhysicalDeviceType type) +{ + switch (type) { + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return "integrated"; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return "discrete"; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return "virtual"; + case VK_PHYSICAL_DEVICE_TYPE_CPU: return "software"; + default: return "unknown"; + } +} + +/* Finds a device */ +static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select) +{ + int err = 0, choice = -1; + uint32_t num; + VkResult ret; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + VkPhysicalDevice *devices = NULL; + VkPhysicalDeviceIDProperties *idp = NULL; + VkPhysicalDeviceProperties2 *prop = NULL; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + + ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, NULL); + if (ret != VK_SUCCESS || !num) { + av_log(ctx, AV_LOG_ERROR, "No devices found: %s!\n", vk_ret2str(ret)); + return AVERROR(ENODEV); + } + + devices = av_malloc_array(num, sizeof(VkPhysicalDevice)); + if (!devices) + return AVERROR(ENOMEM); + + ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, devices); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed enumerating devices: %s\n", + vk_ret2str(ret)); + err = AVERROR(ENODEV); + goto end; + } + + prop = av_calloc(num, sizeof(*prop)); + if (!prop) { + err = AVERROR(ENOMEM); + goto end; + } + + idp = av_calloc(num, sizeof(*idp)); + if (!idp) { + err = AVERROR(ENOMEM); + goto end; + } + + av_log(ctx, AV_LOG_VERBOSE, "GPU listing:\n"); + for (int i = 0; i < num; i++) { + idp[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; + prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + prop[i].pNext = &idp[i]; + + vk->GetPhysicalDeviceProperties2(devices[i], &prop[i]); + av_log(ctx, AV_LOG_VERBOSE, " %d: %s (%s) (0x%x)\n", i, + prop[i].properties.deviceName, + vk_dev_type(prop[i].properties.deviceType), + prop[i].properties.deviceID); + } + + if (select->has_uuid) { + for (int i = 0; i < num; i++) { + if (!strncmp(idp[i].deviceUUID, select->uuid, VK_UUID_SIZE)) { + choice = i; + goto end; + } + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device by given UUID!\n"); + err = AVERROR(ENODEV); + goto end; + } else if (select->name) { + av_log(ctx, AV_LOG_VERBOSE, "Requested device: %s\n", select->name); + for (int i = 0; i < num; i++) { + if (strstr(prop[i].properties.deviceName, select->name)) { + choice = i; + goto end; + } + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device \"%s\"!\n", + select->name); + err = AVERROR(ENODEV); + goto end; + } else if (select->pci_device) { + av_log(ctx, AV_LOG_VERBOSE, "Requested device: 0x%x\n", select->pci_device); + for (int i = 0; i < num; i++) { + if (select->pci_device == prop[i].properties.deviceID) { + choice = i; + goto end; + } + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device with PCI ID 0x%x!\n", + select->pci_device); + err = AVERROR(EINVAL); + goto end; + } else if (select->vendor_id) { + av_log(ctx, AV_LOG_VERBOSE, "Requested vendor: 0x%x\n", select->vendor_id); + for (int i = 0; i < num; i++) { + if (select->vendor_id == prop[i].properties.vendorID) { + choice = i; + goto end; + } + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device with Vendor ID 0x%x!\n", + select->vendor_id); + err = AVERROR(ENODEV); + goto end; + } else { + if (select->index < num) { + choice = select->index; + goto end; + } + av_log(ctx, AV_LOG_ERROR, "Unable to find device with index %i!\n", + select->index); + err = AVERROR(ENODEV); + goto end; + } + +end: + if (choice > -1) { + av_log(ctx, AV_LOG_VERBOSE, "Device %d selected: %s (%s) (0x%x)\n", + choice, prop[choice].properties.deviceName, + vk_dev_type(prop[choice].properties.deviceType), + prop[choice].properties.deviceID); + hwctx->phys_dev = devices[choice]; + } + + av_free(devices); + av_free(prop); + av_free(idp); + + return err; +} + +/* Picks the least used qf with the fewest unneeded flags, or -1 if none found */ +static inline int pick_queue_family(VkQueueFamilyProperties *qf, uint32_t num_qf, + VkQueueFlagBits flags) +{ + int index = -1; + uint32_t min_score = UINT32_MAX; + + for (int i = 0; i < num_qf; i++) { + const VkQueueFlagBits qflags = qf[i].queueFlags; + if (qflags & flags) { + uint32_t score = av_popcount(qflags) + qf[i].timestampValidBits; + if (score < min_score) { + index = i; + min_score = score; + } + } + } + + if (index > -1) + qf[index].timestampValidBits++; + + return index; +} + +static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) +{ + uint32_t num; + float *weights; + VkQueueFamilyProperties *qf = NULL; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + int graph_index, comp_index, tx_index, enc_index, dec_index; + + /* First get the number of queue families */ + vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, NULL); + if (!num) { + av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n"); + return AVERROR_EXTERNAL; + } + + /* Then allocate memory */ + qf = av_malloc_array(num, sizeof(VkQueueFamilyProperties)); + if (!qf) + return AVERROR(ENOMEM); + + /* Finally retrieve the queue families */ + vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, qf); + + av_log(ctx, AV_LOG_VERBOSE, "Queue families:\n"); + for (int i = 0; i < num; i++) { + av_log(ctx, AV_LOG_VERBOSE, " %i:%s%s%s%s%s%s%s (queues: %i)\n", i, + ((qf[i].queueFlags) & VK_QUEUE_GRAPHICS_BIT) ? " graphics" : "", + ((qf[i].queueFlags) & VK_QUEUE_COMPUTE_BIT) ? " compute" : "", + ((qf[i].queueFlags) & VK_QUEUE_TRANSFER_BIT) ? " transfer" : "", + ((qf[i].queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ? " encode" : "", + ((qf[i].queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ? " decode" : "", + ((qf[i].queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ? " sparse" : "", + ((qf[i].queueFlags) & VK_QUEUE_PROTECTED_BIT) ? " protected" : "", + qf[i].queueCount); + + /* We use this field to keep a score of how many times we've used that + * queue family in order to make better choices. */ + qf[i].timestampValidBits = 0; + } + + /* Pick each queue family to use */ + graph_index = pick_queue_family(qf, num, VK_QUEUE_GRAPHICS_BIT); + comp_index = pick_queue_family(qf, num, VK_QUEUE_COMPUTE_BIT); + tx_index = pick_queue_family(qf, num, VK_QUEUE_TRANSFER_BIT); + enc_index = pick_queue_family(qf, num, VK_QUEUE_VIDEO_ENCODE_BIT_KHR); + dec_index = pick_queue_family(qf, num, VK_QUEUE_VIDEO_DECODE_BIT_KHR); + + /* Signalling the transfer capabilities on a queue family is optional */ + if (tx_index < 0) { + tx_index = pick_queue_family(qf, num, VK_QUEUE_COMPUTE_BIT); + if (tx_index < 0) + tx_index = pick_queue_family(qf, num, VK_QUEUE_GRAPHICS_BIT); + } + + hwctx->queue_family_index = -1; + hwctx->queue_family_comp_index = -1; + hwctx->queue_family_tx_index = -1; + hwctx->queue_family_encode_index = -1; + hwctx->queue_family_decode_index = -1; + +#define SETUP_QUEUE(qf_idx) \ + if (qf_idx > -1) { \ + int fidx = qf_idx; \ + int qc = qf[fidx].queueCount; \ + VkDeviceQueueCreateInfo *pc; \ + \ + if (fidx == graph_index) { \ + hwctx->queue_family_index = fidx; \ + hwctx->nb_graphics_queues = qc; \ + graph_index = -1; \ + } \ + if (fidx == comp_index) { \ + hwctx->queue_family_comp_index = fidx; \ + hwctx->nb_comp_queues = qc; \ + comp_index = -1; \ + } \ + if (fidx == tx_index) { \ + hwctx->queue_family_tx_index = fidx; \ + hwctx->nb_tx_queues = qc; \ + tx_index = -1; \ + } \ + if (fidx == enc_index) { \ + hwctx->queue_family_encode_index = fidx; \ + hwctx->nb_encode_queues = qc; \ + enc_index = -1; \ + } \ + if (fidx == dec_index) { \ + hwctx->queue_family_decode_index = fidx; \ + hwctx->nb_decode_queues = qc; \ + dec_index = -1; \ + } \ + \ + pc = av_realloc((void *)cd->pQueueCreateInfos, \ + sizeof(*pc) * (cd->queueCreateInfoCount + 1)); \ + if (!pc) { \ + av_free(qf); \ + return AVERROR(ENOMEM); \ + } \ + cd->pQueueCreateInfos = pc; \ + pc = &pc[cd->queueCreateInfoCount]; \ + \ + weights = av_malloc(qc * sizeof(float)); \ + if (!weights) { \ + av_free(qf); \ + return AVERROR(ENOMEM); \ + } \ + \ + memset(pc, 0, sizeof(*pc)); \ + pc->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; \ + pc->queueFamilyIndex = fidx; \ + pc->queueCount = qc; \ + pc->pQueuePriorities = weights; \ + \ + for (int i = 0; i < qc; i++) \ + weights[i] = 1.0f / qc; \ + \ + cd->queueCreateInfoCount++; \ + } + + SETUP_QUEUE(graph_index) + SETUP_QUEUE(comp_index) + SETUP_QUEUE(tx_index) + SETUP_QUEUE(enc_index) + SETUP_QUEUE(dec_index) + +#undef SETUP_QUEUE + + av_free(qf); + + return 0; +} + +static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, + int queue_family_index, int num_queues) +{ + VkResult ret; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + VkCommandPoolCreateInfo cqueue_create = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = queue_family_index, + }; + VkCommandBufferAllocateInfo cbuf_create = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = num_queues, + }; + + cmd->nb_queues = num_queues; + + /* Create command pool */ + ret = vk->CreateCommandPool(hwctx->act_dev, &cqueue_create, + hwctx->alloc, &cmd->pool); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Command pool creation failure: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + cmd->bufs = av_mallocz(num_queues * sizeof(*cmd->bufs)); + if (!cmd->bufs) + return AVERROR(ENOMEM); + + cbuf_create.commandPool = cmd->pool; + + /* Allocate command buffer */ + ret = vk->AllocateCommandBuffers(hwctx->act_dev, &cbuf_create, cmd->bufs); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Command buffer alloc failure: %s\n", + vk_ret2str(ret)); + av_freep(&cmd->bufs); + return AVERROR_EXTERNAL; + } + + cmd->queues = av_mallocz(num_queues * sizeof(*cmd->queues)); + if (!cmd->queues) + return AVERROR(ENOMEM); + + for (int i = 0; i < num_queues; i++) { + VulkanQueueCtx *q = &cmd->queues[i]; + vk->GetDeviceQueue(hwctx->act_dev, queue_family_index, i, &q->queue); + q->was_synchronous = 1; + } + + return 0; +} + +static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) +{ + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + if (cmd->queues) { + for (int i = 0; i < cmd->nb_queues; i++) { + VulkanQueueCtx *q = &cmd->queues[i]; + + /* Make sure all queues have finished executing */ + if (q->fence && !q->was_synchronous) { + vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vk->ResetFences(hwctx->act_dev, 1, &q->fence); + } + + /* Free the fence */ + if (q->fence) + vk->DestroyFence(hwctx->act_dev, q->fence, hwctx->alloc); + + /* Free buffer dependencies */ + for (int j = 0; j < q->nb_buf_deps; j++) + av_buffer_unref(&q->buf_deps[j]); + av_free(q->buf_deps); + } + } + + if (cmd->bufs) + vk->FreeCommandBuffers(hwctx->act_dev, cmd->pool, cmd->nb_queues, cmd->bufs); + if (cmd->pool) + vk->DestroyCommandPool(hwctx->act_dev, cmd->pool, hwctx->alloc); + + av_freep(&cmd->queues); + av_freep(&cmd->bufs); + cmd->pool = NULL; +} + +static VkCommandBuffer get_buf_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) +{ + return cmd->bufs[cmd->cur_queue_idx]; +} + +static void unref_exec_ctx_deps(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) +{ + VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx]; + + for (int j = 0; j < q->nb_buf_deps; j++) + av_buffer_unref(&q->buf_deps[j]); + q->nb_buf_deps = 0; +} + +static int wait_start_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd) +{ + VkResult ret; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx]; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + VkCommandBufferBeginInfo cmd_start = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + + /* Create the fence and don't wait for it initially */ + if (!q->fence) { + VkFenceCreateInfo fence_spawn = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + }; + ret = vk->CreateFence(hwctx->act_dev, &fence_spawn, hwctx->alloc, + &q->fence); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to queue frame fence: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } else if (!q->was_synchronous) { + vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vk->ResetFences(hwctx->act_dev, 1, &q->fence); + } + + /* Discard queue dependencies */ + unref_exec_ctx_deps(hwfc, cmd); + + ret = vk->BeginCommandBuffer(cmd->bufs[cmd->cur_queue_idx], &cmd_start); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Unable to init command buffer: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static int add_buf_dep_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, + AVBufferRef * const *deps, int nb_deps) +{ + AVBufferRef **dst; + VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx]; + + if (!deps || !nb_deps) + return 0; + + dst = av_fast_realloc(q->buf_deps, &q->buf_deps_alloc_size, + (q->nb_buf_deps + nb_deps) * sizeof(*dst)); + if (!dst) + goto err; + + q->buf_deps = dst; + + for (int i = 0; i < nb_deps; i++) { + q->buf_deps[q->nb_buf_deps] = av_buffer_ref(deps[i]); + if (!q->buf_deps[q->nb_buf_deps]) + goto err; + q->nb_buf_deps++; + } + + return 0; + +err: + unref_exec_ctx_deps(hwfc, cmd); + return AVERROR(ENOMEM); +} + +static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, + VkSubmitInfo *s_info, AVVkFrame *f, int synchronous) +{ + VkResult ret; + VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx]; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + ret = vk->EndCommandBuffer(cmd->bufs[cmd->cur_queue_idx]); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Unable to finish command buffer: %s\n", + vk_ret2str(ret)); + unref_exec_ctx_deps(hwfc, cmd); + return AVERROR_EXTERNAL; + } + + s_info->pCommandBuffers = &cmd->bufs[cmd->cur_queue_idx]; + s_info->commandBufferCount = 1; + + ret = vk->QueueSubmit(q->queue, 1, s_info, q->fence); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Queue submission failure: %s\n", + vk_ret2str(ret)); + unref_exec_ctx_deps(hwfc, cmd); + return AVERROR_EXTERNAL; + } + + if (f) + for (int i = 0; i < s_info->signalSemaphoreCount; i++) + f->sem_value[i]++; + + q->was_synchronous = synchronous; + + if (synchronous) { + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vk->ResetFences(hwctx->act_dev, 1, &q->fence); + unref_exec_ctx_deps(hwfc, cmd); + } else { /* Rotate queues */ + cmd->cur_queue_idx = (cmd->cur_queue_idx + 1) % cmd->nb_queues; + } + + return 0; +} + +static void vulkan_device_free(AVHWDeviceContext *ctx) +{ + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + + if (hwctx->act_dev) + vk->DestroyDevice(hwctx->act_dev, hwctx->alloc); + + if (p->debug_ctx) + vk->DestroyDebugUtilsMessengerEXT(hwctx->inst, p->debug_ctx, + hwctx->alloc); + + if (hwctx->inst) + vk->DestroyInstance(hwctx->inst, hwctx->alloc); + + if (p->libvulkan) + dlclose(p->libvulkan); + + RELEASE_PROPS(hwctx->enabled_inst_extensions, hwctx->nb_enabled_inst_extensions); + RELEASE_PROPS(hwctx->enabled_dev_extensions, hwctx->nb_enabled_dev_extensions); +} + +static int vulkan_device_create_internal(AVHWDeviceContext *ctx, + VulkanDeviceSelection *dev_select, + AVDictionary *opts, int flags) +{ + int err = 0; + VkResult ret; + AVDictionaryEntry *opt_d; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + + /* + * VkPhysicalDeviceVulkan12Features has a timelineSemaphore field, but + * MoltenVK doesn't implement VkPhysicalDeviceVulkan12Features yet, so we + * use VkPhysicalDeviceTimelineSemaphoreFeatures directly. + */ + VkPhysicalDeviceTimelineSemaphoreFeatures timeline_features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + }; + VkPhysicalDeviceVulkan12Features dev_features_1_2 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .pNext = &timeline_features, + }; + VkPhysicalDeviceVulkan11Features dev_features_1_1 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + .pNext = &dev_features_1_2, + }; + VkPhysicalDeviceFeatures2 dev_features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &dev_features_1_1, + }; + + VkDeviceCreateInfo dev_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = &hwctx->device_features, + }; + + hwctx->device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + hwctx->device_features.pNext = &p->device_features_1_1; + p->device_features_1_1.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + p->device_features_1_1.pNext = &p->device_features_1_2; + p->device_features_1_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + ctx->free = vulkan_device_free; + + /* Create an instance if not given one */ + if ((err = create_instance(ctx, opts))) + goto end; + + /* Find a device (if not given one) */ + if ((err = find_device(ctx, dev_select))) + goto end; + + vk->GetPhysicalDeviceFeatures2(hwctx->phys_dev, &dev_features); + + /* Try to keep in sync with libplacebo */ +#define COPY_FEATURE(DST, NAME) (DST).features.NAME = dev_features.features.NAME; + COPY_FEATURE(hwctx->device_features, shaderImageGatherExtended) + COPY_FEATURE(hwctx->device_features, shaderStorageImageReadWithoutFormat) + COPY_FEATURE(hwctx->device_features, shaderStorageImageWriteWithoutFormat) + COPY_FEATURE(hwctx->device_features, fragmentStoresAndAtomics) + COPY_FEATURE(hwctx->device_features, vertexPipelineStoresAndAtomics) + COPY_FEATURE(hwctx->device_features, shaderInt64) +#undef COPY_FEATURE + + /* We require timeline semaphores */ + if (!timeline_features.timelineSemaphore) { + av_log(ctx, AV_LOG_ERROR, "Device does not support timeline semaphores!\n"); + err = AVERROR(ENOSYS); + goto end; + } + p->device_features_1_2.timelineSemaphore = 1; + + /* Setup queue family */ + if ((err = setup_queue_families(ctx, &dev_info))) + goto end; + + if ((err = check_extensions(ctx, 1, opts, &dev_info.ppEnabledExtensionNames, + &dev_info.enabledExtensionCount, 0))) { + for (int i = 0; i < dev_info.queueCreateInfoCount; i++) + av_free((void *)dev_info.pQueueCreateInfos[i].pQueuePriorities); + av_free((void *)dev_info.pQueueCreateInfos); + goto end; + } + + ret = vk->CreateDevice(hwctx->phys_dev, &dev_info, hwctx->alloc, + &hwctx->act_dev); + + for (int i = 0; i < dev_info.queueCreateInfoCount; i++) + av_free((void *)dev_info.pQueueCreateInfos[i].pQueuePriorities); + av_free((void *)dev_info.pQueueCreateInfos); + + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Device creation failure: %s\n", + vk_ret2str(ret)); + for (int i = 0; i < dev_info.enabledExtensionCount; i++) + av_free((void *)dev_info.ppEnabledExtensionNames[i]); + av_free((void *)dev_info.ppEnabledExtensionNames); + err = AVERROR_EXTERNAL; + goto end; + } + + /* Tiled images setting, use them by default */ + opt_d = av_dict_get(opts, "linear_images", NULL, 0); + if (opt_d) + p->use_linear_images = strtol(opt_d->value, NULL, 10); + + opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0); + if (opt_d) + p->contiguous_planes = strtol(opt_d->value, NULL, 10); + else + p->contiguous_planes = -1; + + hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames; + hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount; + +end: + return err; +} + +static int vulkan_device_init(AVHWDeviceContext *ctx) +{ + int err; + uint32_t queue_num; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + int graph_index, comp_index, tx_index, enc_index, dec_index; + + /* Set device extension flags */ + for (int i = 0; i < hwctx->nb_enabled_dev_extensions; i++) { + for (int j = 0; j < FF_ARRAY_ELEMS(optional_device_exts); j++) { + if (!strcmp(hwctx->enabled_dev_extensions[i], + optional_device_exts[j].name)) { + p->extensions |= optional_device_exts[j].flag; + break; + } + } + } + + err = ff_vk_load_functions(ctx, vk, p->extensions, 1, 1); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Unable to load functions!\n"); + return err; + } + + p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + p->props.pNext = &p->hprops; + p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT; + + vk->GetPhysicalDeviceProperties2(hwctx->phys_dev, &p->props); + av_log(ctx, AV_LOG_VERBOSE, "Using device: %s\n", + p->props.properties.deviceName); + av_log(ctx, AV_LOG_VERBOSE, "Alignments:\n"); + av_log(ctx, AV_LOG_VERBOSE, " optimalBufferCopyRowPitchAlignment: %"PRIu64"\n", + p->props.properties.limits.optimalBufferCopyRowPitchAlignment); + av_log(ctx, AV_LOG_VERBOSE, " minMemoryMapAlignment: %"SIZE_SPECIFIER"\n", + p->props.properties.limits.minMemoryMapAlignment); + if (p->extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY) + av_log(ctx, AV_LOG_VERBOSE, " minImportedHostPointerAlignment: %"PRIu64"\n", + p->hprops.minImportedHostPointerAlignment); + + p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de); + p->dev_is_intel = (p->props.properties.vendorID == 0x8086); + + vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, NULL); + if (!queue_num) { + av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n"); + return AVERROR_EXTERNAL; + } + + graph_index = hwctx->queue_family_index; + comp_index = hwctx->queue_family_comp_index; + tx_index = hwctx->queue_family_tx_index; + enc_index = hwctx->queue_family_encode_index; + dec_index = hwctx->queue_family_decode_index; + +#define CHECK_QUEUE(type, required, fidx, ctx_qf, qc) \ + do { \ + if (ctx_qf < 0 && required) { \ + av_log(ctx, AV_LOG_ERROR, "%s queue family is required, but marked as missing" \ + " in the context!\n", type); \ + return AVERROR(EINVAL); \ + } else if (fidx < 0 || ctx_qf < 0) { \ + break; \ + } else if (ctx_qf >= queue_num) { \ + av_log(ctx, AV_LOG_ERROR, "Invalid %s family index %i (device has %i families)!\n", \ + type, ctx_qf, queue_num); \ + return AVERROR(EINVAL); \ + } \ + \ + av_log(ctx, AV_LOG_VERBOSE, "Using queue family %i (queues: %i)" \ + " for%s%s%s%s%s\n", \ + ctx_qf, qc, \ + ctx_qf == graph_index ? " graphics" : "", \ + ctx_qf == comp_index ? " compute" : "", \ + ctx_qf == tx_index ? " transfers" : "", \ + ctx_qf == enc_index ? " encode" : "", \ + ctx_qf == dec_index ? " decode" : ""); \ + graph_index = (ctx_qf == graph_index) ? -1 : graph_index; \ + comp_index = (ctx_qf == comp_index) ? -1 : comp_index; \ + tx_index = (ctx_qf == tx_index) ? -1 : tx_index; \ + enc_index = (ctx_qf == enc_index) ? -1 : enc_index; \ + dec_index = (ctx_qf == dec_index) ? -1 : dec_index; \ + p->qfs[p->num_qfs++] = ctx_qf; \ + } while (0) + + CHECK_QUEUE("graphics", 0, graph_index, hwctx->queue_family_index, hwctx->nb_graphics_queues); + CHECK_QUEUE("upload", 1, tx_index, hwctx->queue_family_tx_index, hwctx->nb_tx_queues); + CHECK_QUEUE("compute", 1, comp_index, hwctx->queue_family_comp_index, hwctx->nb_comp_queues); + CHECK_QUEUE("encode", 0, enc_index, hwctx->queue_family_encode_index, hwctx->nb_encode_queues); + CHECK_QUEUE("decode", 0, dec_index, hwctx->queue_family_decode_index, hwctx->nb_decode_queues); + +#undef CHECK_QUEUE + + /* Get device capabilities */ + vk->GetPhysicalDeviceMemoryProperties(hwctx->phys_dev, &p->mprops); + + return 0; +} + +static int vulkan_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + VulkanDeviceSelection dev_select = { 0 }; + if (device && device[0]) { + char *end = NULL; + dev_select.index = strtol(device, &end, 10); + if (end == device) { + dev_select.index = 0; + dev_select.name = device; + } + } + + return vulkan_device_create_internal(ctx, &dev_select, opts, flags); +} + +static int vulkan_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *src_ctx, + AVDictionary *opts, int flags) +{ + av_unused VulkanDeviceSelection dev_select = { 0 }; + + /* If there's only one device on the system, then even if its not covered + * by the following checks (e.g. non-PCIe ARM GPU), having an empty + * dev_select will mean it'll get picked. */ + switch(src_ctx->type) { +#if CONFIG_LIBDRM +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: { + AVVAAPIDeviceContext *src_hwctx = src_ctx->hwctx; + + const char *vendor = vaQueryVendorString(src_hwctx->display); + if (!vendor) { + av_log(ctx, AV_LOG_ERROR, "Unable to get device info from VAAPI!\n"); + return AVERROR_EXTERNAL; + } + + if (strstr(vendor, "Intel")) + dev_select.vendor_id = 0x8086; + if (strstr(vendor, "AMD")) + dev_select.vendor_id = 0x1002; + + return vulkan_device_create_internal(ctx, &dev_select, opts, flags); + } +#endif + case AV_HWDEVICE_TYPE_DRM: { + AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; + + drmDevice *drm_dev_info; + int err = drmGetDevice(src_hwctx->fd, &drm_dev_info); + if (err) { + av_log(ctx, AV_LOG_ERROR, "Unable to get device info from DRM fd!\n"); + return AVERROR_EXTERNAL; + } + + if (drm_dev_info->bustype == DRM_BUS_PCI) + dev_select.pci_device = drm_dev_info->deviceinfo.pci->device_id; + + drmFreeDevice(&drm_dev_info); + + return vulkan_device_create_internal(ctx, &dev_select, opts, flags); + } +#endif +#if CONFIG_CUDA + case AV_HWDEVICE_TYPE_CUDA: { + AVHWDeviceContext *cuda_cu = src_ctx; + AVCUDADeviceContext *src_hwctx = src_ctx->hwctx; + AVCUDADeviceContextInternal *cu_internal = src_hwctx->internal; + CudaFunctions *cu = cu_internal->cuda_dl; + + int ret = CHECK_CU(cu->cuDeviceGetUuid((CUuuid *)&dev_select.uuid, + cu_internal->cuda_device)); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Unable to get UUID from CUDA!\n"); + return AVERROR_EXTERNAL; + } + + dev_select.has_uuid = 1; + + return vulkan_device_create_internal(ctx, &dev_select, opts, flags); + } +#endif + default: + return AVERROR(ENOSYS); + } +} + +static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int count = 0; + VulkanDevicePriv *p = ctx->internal->priv; + + for (enum AVPixelFormat i = 0; i < AV_PIX_FMT_NB; i++) + count += pixfmt_is_supported(ctx, i, p->use_linear_images); + +#if CONFIG_CUDA + if (p->dev_is_nvidia) + count++; +#endif + + constraints->valid_sw_formats = av_malloc_array(count + 1, + sizeof(enum AVPixelFormat)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + count = 0; + for (enum AVPixelFormat i = 0; i < AV_PIX_FMT_NB; i++) + if (pixfmt_is_supported(ctx, i, p->use_linear_images)) + constraints->valid_sw_formats[count++] = i; + +#if CONFIG_CUDA + if (p->dev_is_nvidia) + constraints->valid_sw_formats[count++] = AV_PIX_FMT_CUDA; +#endif + constraints->valid_sw_formats[count++] = AV_PIX_FMT_NONE; + + constraints->min_width = 0; + constraints->min_height = 0; + constraints->max_width = p->props.properties.limits.maxImageDimension2D; + constraints->max_height = p->props.properties.limits.maxImageDimension2D; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(enum AVPixelFormat)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_VULKAN; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req, + VkMemoryPropertyFlagBits req_flags, const void *alloc_extension, + VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem) +{ + VkResult ret; + int index = -1; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *dev_hwctx = ctx->hwctx; + VkMemoryAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = alloc_extension, + .allocationSize = req->size, + }; + + /* The vulkan spec requires memory types to be sorted in the "optimal" + * order, so the first matching type we find will be the best/fastest one */ + for (int i = 0; i < p->mprops.memoryTypeCount; i++) { + const VkMemoryType *type = &p->mprops.memoryTypes[i]; + + /* The memory type must be supported by the requirements (bitfield) */ + if (!(req->memoryTypeBits & (1 << i))) + continue; + + /* The memory type flags must include our properties */ + if ((type->propertyFlags & req_flags) != req_flags) + continue; + + /* The memory type must be large enough */ + if (req->size > p->mprops.memoryHeaps[type->heapIndex].size) + continue; + + /* Found a suitable memory type */ + index = i; + break; + } + + if (index < 0) { + av_log(ctx, AV_LOG_ERROR, "No memory type found for flags 0x%x\n", + req_flags); + return AVERROR(EINVAL); + } + + alloc_info.memoryTypeIndex = index; + + ret = vk->AllocateMemory(dev_hwctx->act_dev, &alloc_info, + dev_hwctx->alloc, mem); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory: %s\n", + vk_ret2str(ret)); + return AVERROR(ENOMEM); + } + + *mem_flags |= p->mprops.memoryTypes[index].propertyFlags; + + return 0; +} + +static void vulkan_free_internal(AVVkFrame *f) +{ + AVVkFrameInternal *internal = f->internal; + + if (!internal) + return; + +#if CONFIG_CUDA + if (internal->cuda_fc_ref) { + AVHWFramesContext *cuda_fc = (AVHWFramesContext *)internal->cuda_fc_ref->data; + int planes = av_pix_fmt_count_planes(cuda_fc->sw_format); + AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx; + AVCUDADeviceContext *cuda_dev = cuda_cu->hwctx; + AVCUDADeviceContextInternal *cu_internal = cuda_dev->internal; + CudaFunctions *cu = cu_internal->cuda_dl; + + for (int i = 0; i < planes; i++) { + if (internal->cu_sem[i]) + CHECK_CU(cu->cuDestroyExternalSemaphore(internal->cu_sem[i])); + if (internal->cu_mma[i]) + CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[i])); + if (internal->ext_mem[i]) + CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[i])); +#ifdef _WIN32 + if (internal->ext_sem_handle[i]) + CloseHandle(internal->ext_sem_handle[i]); + if (internal->ext_mem_handle[i]) + CloseHandle(internal->ext_mem_handle[i]); +#endif + } + + av_buffer_unref(&internal->cuda_fc_ref); + } +#endif + + av_freep(&f->internal); +} + +static void vulkan_frame_free(void *opaque, uint8_t *data) +{ + AVVkFrame *f = (AVVkFrame *)data; + AVHWFramesContext *hwfc = opaque; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + int planes = av_pix_fmt_count_planes(hwfc->sw_format); + + /* We could use vkWaitSemaphores, but the validation layer seems to have + * issues tracking command buffer execution state on uninit. */ + vk->DeviceWaitIdle(hwctx->act_dev); + + vulkan_free_internal(f); + + for (int i = 0; i < planes; i++) { + vk->DestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc); + vk->FreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc); + vk->DestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc); + } + + av_free(f); +} + +static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f, + void *alloc_pnext, size_t alloc_pnext_stride) +{ + int err; + VkResult ret; + AVHWDeviceContext *ctx = hwfc->device_ctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanFramesContext *hwfctx = hwfc->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } }; + + VkMemoryRequirements cont_memory_requirements = { 0 }; + int cont_mem_size_list[AV_NUM_DATA_POINTERS] = { 0 }; + int cont_mem_size = 0; + + AVVulkanDeviceContext *hwctx = ctx->hwctx; + + for (int i = 0; i < planes; i++) { + int use_ded_mem; + VkImageMemoryRequirementsInfo2 req_desc = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, + .image = f->img[i], + }; + VkMemoryDedicatedAllocateInfo ded_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = (void *)(((uint8_t *)alloc_pnext) + i*alloc_pnext_stride), + }; + VkMemoryDedicatedRequirements ded_req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + }; + VkMemoryRequirements2 req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &ded_req, + }; + + vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req); + + if (f->tiling == VK_IMAGE_TILING_LINEAR) + req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size, + p->props.properties.limits.minMemoryMapAlignment); + + if (hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) { + if (ded_req.requiresDedicatedAllocation) { + av_log(hwfc, AV_LOG_ERROR, "Cannot allocate all planes in a single allocation, " + "device requires dedicated image allocation!\n"); + return AVERROR(EINVAL); + } else if (!i) { + cont_memory_requirements = req.memoryRequirements; + } else if (cont_memory_requirements.memoryTypeBits != + req.memoryRequirements.memoryTypeBits) { + av_log(hwfc, AV_LOG_ERROR, "The memory requirements differ between plane 0 " + "and %i, cannot allocate in a single region!\n", + i); + return AVERROR(EINVAL); + } + + cont_mem_size_list[i] = FFALIGN(req.memoryRequirements.size, + req.memoryRequirements.alignment); + cont_mem_size += cont_mem_size_list[i]; + continue; + } + + /* In case the implementation prefers/requires dedicated allocation */ + use_ded_mem = ded_req.prefersDedicatedAllocation | + ded_req.requiresDedicatedAllocation; + if (use_ded_mem) + ded_alloc.image = f->img[i]; + + /* Allocate memory */ + if ((err = alloc_mem(ctx, &req.memoryRequirements, + f->tiling == VK_IMAGE_TILING_LINEAR ? + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + use_ded_mem ? &ded_alloc : (void *)ded_alloc.pNext, + &f->flags, &f->mem[i]))) + return err; + + f->size[i] = req.memoryRequirements.size; + bind_info[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO; + bind_info[i].image = f->img[i]; + bind_info[i].memory = f->mem[i]; + } + + if (hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) { + cont_memory_requirements.size = cont_mem_size; + + /* Allocate memory */ + if ((err = alloc_mem(ctx, &cont_memory_requirements, + f->tiling == VK_IMAGE_TILING_LINEAR ? + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + (void *)(((uint8_t *)alloc_pnext)), + &f->flags, &f->mem[0]))) + return err; + + f->size[0] = cont_memory_requirements.size; + + for (int i = 0, offset = 0; i < planes; i++) { + bind_info[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO; + bind_info[i].image = f->img[i]; + bind_info[i].memory = f->mem[0]; + bind_info[i].memoryOffset = offset; + + f->offset[i] = bind_info[i].memoryOffset; + offset += cont_mem_size_list[i]; + } + } + + /* Bind the allocated memory to the images */ + ret = vk->BindImageMemory2(hwctx->act_dev, planes, bind_info); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind memory: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +enum PrepMode { + PREP_MODE_WRITE, + PREP_MODE_EXTERNAL_EXPORT, + PREP_MODE_EXTERNAL_IMPORT +}; + +static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx, + AVVkFrame *frame, enum PrepMode pmode) +{ + int err; + uint32_t src_qf, dst_qf; + VkImageLayout new_layout; + VkAccessFlags new_access; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + uint64_t sem_sig_val[AV_NUM_DATA_POINTERS]; + + VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 }; + + VkTimelineSemaphoreSubmitInfo s_timeline_sem_info = { + .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + .pSignalSemaphoreValues = sem_sig_val, + .signalSemaphoreValueCount = planes, + }; + + VkSubmitInfo s_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = &s_timeline_sem_info, + .pSignalSemaphores = frame->sem, + .signalSemaphoreCount = planes, + }; + + VkPipelineStageFlagBits wait_st[AV_NUM_DATA_POINTERS]; + for (int i = 0; i < planes; i++) { + wait_st[i] = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + sem_sig_val[i] = frame->sem_value[i] + 1; + } + + switch (pmode) { + case PREP_MODE_WRITE: + new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + new_access = VK_ACCESS_TRANSFER_WRITE_BIT; + src_qf = VK_QUEUE_FAMILY_IGNORED; + dst_qf = VK_QUEUE_FAMILY_IGNORED; + break; + case PREP_MODE_EXTERNAL_IMPORT: + new_layout = VK_IMAGE_LAYOUT_GENERAL; + new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + src_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR; + dst_qf = VK_QUEUE_FAMILY_IGNORED; + s_timeline_sem_info.pWaitSemaphoreValues = frame->sem_value; + s_timeline_sem_info.waitSemaphoreValueCount = planes; + s_info.pWaitSemaphores = frame->sem; + s_info.pWaitDstStageMask = wait_st; + s_info.waitSemaphoreCount = planes; + break; + case PREP_MODE_EXTERNAL_EXPORT: + new_layout = VK_IMAGE_LAYOUT_GENERAL; + new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + src_qf = VK_QUEUE_FAMILY_IGNORED; + dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR; + s_timeline_sem_info.pWaitSemaphoreValues = frame->sem_value; + s_timeline_sem_info.waitSemaphoreValueCount = planes; + s_info.pWaitSemaphores = frame->sem; + s_info.pWaitDstStageMask = wait_st; + s_info.waitSemaphoreCount = planes; + break; + } + + if ((err = wait_start_exec_ctx(hwfc, ectx))) + return err; + + /* Change the image layout to something more optimal for writes. + * This also signals the newly created semaphore, making it usable + * for synchronization */ + for (int i = 0; i < planes; i++) { + img_bar[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + img_bar[i].srcAccessMask = 0x0; + img_bar[i].dstAccessMask = new_access; + img_bar[i].oldLayout = frame->layout[i]; + img_bar[i].newLayout = new_layout; + img_bar[i].srcQueueFamilyIndex = src_qf; + img_bar[i].dstQueueFamilyIndex = dst_qf; + img_bar[i].image = frame->img[i]; + img_bar[i].subresourceRange.levelCount = 1; + img_bar[i].subresourceRange.layerCount = 1; + img_bar[i].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + frame->layout[i] = img_bar[i].newLayout; + frame->access[i] = img_bar[i].dstAccessMask; + } + + vk->CmdPipelineBarrier(get_buf_exec_ctx(hwfc, ectx), + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, NULL, 0, NULL, planes, img_bar); + + return submit_exec_ctx(hwfc, ectx, &s_info, frame, 0); +} + +static inline void get_plane_wh(int *w, int *h, enum AVPixelFormat format, + int frame_w, int frame_h, int plane) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); + + /* Currently always true unless gray + alpha support is added */ + if (!plane || (plane == 3) || desc->flags & AV_PIX_FMT_FLAG_RGB || + !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) { + *w = frame_w; + *h = frame_h; + return; + } + + *w = AV_CEIL_RSHIFT(frame_w, desc->log2_chroma_w); + *h = AV_CEIL_RSHIFT(frame_h, desc->log2_chroma_h); +} + +static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame, + VkImageTiling tiling, VkImageUsageFlagBits usage, + void *create_pnext) +{ + int err; + VkResult ret; + AVHWDeviceContext *ctx = hwfc->device_ctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + enum AVPixelFormat format = hwfc->sw_format; + const VkFormat *img_fmts = av_vkfmt_from_pixfmt(format); + const int planes = av_pix_fmt_count_planes(format); + + VkExportSemaphoreCreateInfo ext_sem_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, +#ifdef _WIN32 + .handleTypes = IsWindows8OrGreater() + ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT + : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, +#else + .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, +#endif + }; + + VkSemaphoreTypeCreateInfo sem_type_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, +#ifdef _WIN32 + .pNext = p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM ? &ext_sem_info : NULL, +#else + .pNext = p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL, +#endif + .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, + .initialValue = 0, + }; + + VkSemaphoreCreateInfo sem_spawn = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = &sem_type_info, + }; + + AVVkFrame *f = av_vk_frame_alloc(); + if (!f) { + av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n"); + return AVERROR(ENOMEM); + } + + /* Create the images */ + for (int i = 0; i < planes; i++) { + VkImageCreateInfo create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = create_pnext, + .imageType = VK_IMAGE_TYPE_2D, + .format = img_fmts[i], + .extent.depth = 1, + .mipLevels = 1, + .arrayLayers = 1, + .flags = VK_IMAGE_CREATE_ALIAS_BIT, + .tiling = tiling, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .usage = usage, + .samples = VK_SAMPLE_COUNT_1_BIT, + .pQueueFamilyIndices = p->qfs, + .queueFamilyIndexCount = p->num_qfs, + .sharingMode = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT : + VK_SHARING_MODE_EXCLUSIVE, + }; + + get_plane_wh(&create_info.extent.width, &create_info.extent.height, + format, hwfc->width, hwfc->height, i); + + ret = vk->CreateImage(hwctx->act_dev, &create_info, + hwctx->alloc, &f->img[i]); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n", + vk_ret2str(ret)); + err = AVERROR(EINVAL); + goto fail; + } + + /* Create semaphore */ + ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn, + hwctx->alloc, &f->sem[i]); + if (ret != VK_SUCCESS) { + av_log(hwctx, AV_LOG_ERROR, "Failed to create semaphore: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + f->layout[i] = create_info.initialLayout; + f->access[i] = 0x0; + f->sem_value[i] = 0; + } + + f->flags = 0x0; + f->tiling = tiling; + + *frame = f; + return 0; + +fail: + vulkan_frame_free(hwfc, (uint8_t *)f); + return err; +} + +/* Checks if an export flag is enabled, and if it is ORs it with *iexp */ +static void try_export_flags(AVHWFramesContext *hwfc, + VkExternalMemoryHandleTypeFlags *comp_handle_types, + VkExternalMemoryHandleTypeFlagBits *iexp, + VkExternalMemoryHandleTypeFlagBits exp) +{ + VkResult ret; + AVVulkanFramesContext *hwctx = hwfc->hwctx; + AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + const VkImageDrmFormatModifierListCreateInfoEXT *drm_mod_info = + vk_find_struct(hwctx->create_pnext, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT); + int has_mods = hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && drm_mod_info; + int nb_mods; + + VkExternalImageFormatProperties eprops = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR, + }; + VkImageFormatProperties2 props = { + .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + .pNext = &eprops, + }; + VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .pNext = NULL, + .pQueueFamilyIndices = p->qfs, + .queueFamilyIndexCount = p->num_qfs, + .sharingMode = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT : + VK_SHARING_MODE_EXCLUSIVE, + }; + VkPhysicalDeviceExternalImageFormatInfo enext = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + .handleType = exp, + .pNext = has_mods ? &phy_dev_mod_info : NULL, + }; + VkPhysicalDeviceImageFormatInfo2 pinfo = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + .pNext = !exp ? NULL : &enext, + .format = av_vkfmt_from_pixfmt(hwfc->sw_format)[0], + .type = VK_IMAGE_TYPE_2D, + .tiling = hwctx->tiling, + .usage = hwctx->usage, + .flags = VK_IMAGE_CREATE_ALIAS_BIT, + }; + + nb_mods = has_mods ? drm_mod_info->drmFormatModifierCount : 1; + for (int i = 0; i < nb_mods; i++) { + if (has_mods) + phy_dev_mod_info.drmFormatModifier = drm_mod_info->pDrmFormatModifiers[i]; + + ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev, + &pinfo, &props); + + if (ret == VK_SUCCESS) { + *iexp |= exp; + *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes; + } + } +} + +static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size) +{ + int err; + AVVkFrame *f; + AVBufferRef *avbuf = NULL; + AVHWFramesContext *hwfc = opaque; + AVVulkanFramesContext *hwctx = hwfc->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + VulkanFramesPriv *fp = hwfc->internal->priv; + VkExportMemoryAllocateInfo eminfo[AV_NUM_DATA_POINTERS]; + VkExternalMemoryHandleTypeFlags e = 0x0; + + VkExternalMemoryImageCreateInfo eiinfo = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + .pNext = hwctx->create_pnext, + }; + +#ifdef _WIN32 + if (p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) + try_export_flags(hwfc, &eiinfo.handleTypes, &e, IsWindows8OrGreater() + ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT + : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT); +#else + if (p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) + try_export_flags(hwfc, &eiinfo.handleTypes, &e, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT); + + if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS)) + try_export_flags(hwfc, &eiinfo.handleTypes, &e, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); +#endif + + for (int i = 0; i < av_pix_fmt_count_planes(hwfc->sw_format); i++) { + eminfo[i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO; + eminfo[i].pNext = hwctx->alloc_pnext[i]; + eminfo[i].handleTypes = e; + } + + err = create_frame(hwfc, &f, hwctx->tiling, hwctx->usage, + eiinfo.handleTypes ? &eiinfo : NULL); + if (err) + return NULL; + + err = alloc_bind_mem(hwfc, f, eminfo, sizeof(*eminfo)); + if (err) + goto fail; + + err = prepare_frame(hwfc, &fp->conv_ctx, f, PREP_MODE_WRITE); + if (err) + goto fail; + + avbuf = av_buffer_create((uint8_t *)f, sizeof(AVVkFrame), + vulkan_frame_free, hwfc, 0); + if (!avbuf) + goto fail; + + return avbuf; + +fail: + vulkan_frame_free(hwfc, (uint8_t *)f); + return NULL; +} + +static void vulkan_frames_uninit(AVHWFramesContext *hwfc) +{ + VulkanFramesPriv *fp = hwfc->internal->priv; + + if (fp->modifier_info) { + if (fp->modifier_info->pDrmFormatModifiers) + av_freep(&fp->modifier_info->pDrmFormatModifiers); + av_freep(&fp->modifier_info); + } + + free_exec_ctx(hwfc, &fp->conv_ctx); + free_exec_ctx(hwfc, &fp->upload_ctx); + free_exec_ctx(hwfc, &fp->download_ctx); +} + +static int vulkan_frames_init(AVHWFramesContext *hwfc) +{ + int err; + AVVkFrame *f; + AVVulkanFramesContext *hwctx = hwfc->hwctx; + VulkanFramesPriv *fp = hwfc->internal->priv; + AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + const VkImageDrmFormatModifierListCreateInfoEXT *modifier_info; + const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS); + + /* Default tiling flags */ + hwctx->tiling = hwctx->tiling ? hwctx->tiling : + has_modifiers ? VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : + p->use_linear_images ? VK_IMAGE_TILING_LINEAR : + VK_IMAGE_TILING_OPTIMAL; + + if (!hwctx->usage) + hwctx->usage = FF_VK_DEFAULT_USAGE_FLAGS; + + if (!(hwctx->flags & AV_VK_FRAME_FLAG_NONE)) { + if (p->contiguous_planes == 1 || + ((p->contiguous_planes == -1) && p->dev_is_intel)) + hwctx->flags |= AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY; + } + + modifier_info = vk_find_struct(hwctx->create_pnext, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT); + + /* Get the supported modifiers if the user has not given any. */ + if (has_modifiers && !modifier_info) { + const VkFormat *fmt = av_vkfmt_from_pixfmt(hwfc->sw_format); + VkImageDrmFormatModifierListCreateInfoEXT *modifier_info; + FFVulkanFunctions *vk = &p->vkfn; + VkDrmFormatModifierPropertiesEXT *mod_props; + uint64_t *modifiers; + int modifier_count = 0; + + VkDrmFormatModifierPropertiesListEXT mod_props_list = { + .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, + .pNext = NULL, + .drmFormatModifierCount = 0, + .pDrmFormatModifierProperties = NULL, + }; + VkFormatProperties2 prop = { + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + .pNext = &mod_props_list, + }; + + /* Get all supported modifiers */ + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); + + if (!mod_props_list.drmFormatModifierCount) { + av_log(hwfc, AV_LOG_ERROR, "There are no supported modifiers for the given sw_format\n"); + return AVERROR(EINVAL); + } + + /* Createa structure to hold the modifier list info */ + modifier_info = av_mallocz(sizeof(*modifier_info)); + if (!modifier_info) + return AVERROR(ENOMEM); + + modifier_info->pNext = NULL; + modifier_info->sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT; + + /* Add structure to the image creation pNext chain */ + if (!hwctx->create_pnext) + hwctx->create_pnext = modifier_info; + else + vk_link_struct(hwctx->create_pnext, (void *)modifier_info); + + /* Backup the allocated struct to be freed later */ + fp->modifier_info = modifier_info; + + /* Allocate list of modifiers */ + modifiers = av_mallocz(mod_props_list.drmFormatModifierCount * + sizeof(*modifiers)); + if (!modifiers) + return AVERROR(ENOMEM); + + modifier_info->pDrmFormatModifiers = modifiers; + + /* Allocate a temporary list to hold all modifiers supported */ + mod_props = av_mallocz(mod_props_list.drmFormatModifierCount * + sizeof(*mod_props)); + if (!mod_props) + return AVERROR(ENOMEM); + + mod_props_list.pDrmFormatModifierProperties = mod_props; + + /* Finally get all modifiers from the device */ + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); + + /* Reject any modifiers that don't match our requirements */ + for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { + if (!(mod_props[i].drmFormatModifierTilingFeatures & hwctx->usage)) + continue; + + modifiers[modifier_count++] = mod_props[i].drmFormatModifier; + } + + if (!modifier_count) { + av_log(hwfc, AV_LOG_ERROR, "None of the given modifiers supports" + " the usage flags!\n"); + av_freep(&mod_props); + return AVERROR(EINVAL); + } + + modifier_info->drmFormatModifierCount = modifier_count; + av_freep(&mod_props); + } + + err = create_exec_ctx(hwfc, &fp->conv_ctx, + dev_hwctx->queue_family_comp_index, + dev_hwctx->nb_comp_queues); + if (err) + return err; + + err = create_exec_ctx(hwfc, &fp->upload_ctx, + dev_hwctx->queue_family_tx_index, + dev_hwctx->nb_tx_queues); + if (err) + return err; + + err = create_exec_ctx(hwfc, &fp->download_ctx, + dev_hwctx->queue_family_tx_index, 1); + if (err) + return err; + + /* Test to see if allocation will fail */ + err = create_frame(hwfc, &f, hwctx->tiling, hwctx->usage, + hwctx->create_pnext); + if (err) + return err; + + vulkan_frame_free(hwfc, (uint8_t *)f); + + /* If user did not specify a pool, hwfc->pool will be set to the internal one + * in hwcontext.c just after this gets called */ + if (!hwfc->pool) { + hwfc->internal->pool_internal = av_buffer_pool_init2(sizeof(AVVkFrame), + hwfc, vulkan_pool_alloc, + NULL); + if (!hwfc->internal->pool_internal) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int vulkan_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VULKAN; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +static int vulkan_transfer_get_formats(AVHWFramesContext *hwfc, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = hwfc->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + return 0; +} + +typedef struct VulkanMapping { + AVVkFrame *frame; + int flags; +} VulkanMapping; + +static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap) +{ + VulkanMapping *map = hwmap->priv; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + /* Check if buffer needs flushing */ + if ((map->flags & AV_HWFRAME_MAP_WRITE) && + !(map->frame->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { + VkResult ret; + VkMappedMemoryRange flush_ranges[AV_NUM_DATA_POINTERS] = { { 0 } }; + + for (int i = 0; i < planes; i++) { + flush_ranges[i].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + flush_ranges[i].memory = map->frame->mem[i]; + flush_ranges[i].size = VK_WHOLE_SIZE; + } + + ret = vk->FlushMappedMemoryRanges(hwctx->act_dev, planes, + flush_ranges); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to flush memory: %s\n", + vk_ret2str(ret)); + } + } + + for (int i = 0; i < planes; i++) + vk->UnmapMemory(hwctx->act_dev, map->frame->mem[i]); + + av_free(map); +} + +static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + VkResult ret; + int err, mapped_mem_count = 0, mem_planes = 0; + AVVkFrame *f = (AVVkFrame *)src->data[0]; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVVulkanFramesContext *hwfctx = hwfc->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + VulkanMapping *map = av_mallocz(sizeof(VulkanMapping)); + if (!map) + return AVERROR(EINVAL); + + if (src->format != AV_PIX_FMT_VULKAN) { + av_log(hwfc, AV_LOG_ERROR, "Cannot map from pixel format %s!\n", + av_get_pix_fmt_name(src->format)); + err = AVERROR(EINVAL); + goto fail; + } + + if (!(f->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || + !(f->tiling == VK_IMAGE_TILING_LINEAR)) { + av_log(hwfc, AV_LOG_ERROR, "Unable to map frame, not host visible " + "and linear!\n"); + err = AVERROR(EINVAL); + goto fail; + } + + dst->width = src->width; + dst->height = src->height; + + mem_planes = hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY ? 1 : planes; + for (int i = 0; i < mem_planes; i++) { + ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0, + VK_WHOLE_SIZE, 0, (void **)&dst->data[i]); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to map image memory: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + mapped_mem_count++; + } + + if (hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) { + for (int i = 0; i < planes; i++) + dst->data[i] = dst->data[0] + f->offset[i]; + } + + /* Check if the memory contents matter */ + if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) && + !(f->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { + VkMappedMemoryRange map_mem_ranges[AV_NUM_DATA_POINTERS] = { { 0 } }; + for (int i = 0; i < planes; i++) { + map_mem_ranges[i].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + map_mem_ranges[i].size = VK_WHOLE_SIZE; + map_mem_ranges[i].memory = f->mem[i]; + } + + ret = vk->InvalidateMappedMemoryRanges(hwctx->act_dev, planes, + map_mem_ranges); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to invalidate memory: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + } + + for (int i = 0; i < planes; i++) { + VkImageSubresource sub = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + }; + VkSubresourceLayout layout; + vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout); + dst->linesize[i] = layout.rowPitch; + } + + map->frame = f; + map->flags = flags; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &vulkan_unmap_frame, map); + if (err < 0) + goto fail; + + return 0; + +fail: + for (int i = 0; i < mapped_mem_count; i++) + vk->UnmapMemory(hwctx->act_dev, f->mem[i]); + + av_free(map); + return err; +} + +#if CONFIG_LIBDRM +static void vulkan_unmap_from_drm(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap) +{ + AVVkFrame *f = hwmap->priv; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + VkSemaphoreWaitInfo wait_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + .flags = 0x0, + .pSemaphores = f->sem, + .pValues = f->sem_value, + .semaphoreCount = planes, + }; + + vk->WaitSemaphores(hwctx->act_dev, &wait_info, UINT64_MAX); + + vulkan_free_internal(f); + + for (int i = 0; i < planes; i++) { + vk->DestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc); + vk->FreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc); + vk->DestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc); + } + + av_free(f); +} + +static const struct { + uint32_t drm_fourcc; + VkFormat vk_format; +} vulkan_drm_format_map[] = { + { DRM_FORMAT_R8, VK_FORMAT_R8_UNORM }, + { DRM_FORMAT_R16, VK_FORMAT_R16_UNORM }, + { DRM_FORMAT_GR88, VK_FORMAT_R8G8_UNORM }, + { DRM_FORMAT_RG88, VK_FORMAT_R8G8_UNORM }, + { DRM_FORMAT_GR1616, VK_FORMAT_R16G16_UNORM }, + { DRM_FORMAT_RG1616, VK_FORMAT_R16G16_UNORM }, + { DRM_FORMAT_ARGB8888, VK_FORMAT_B8G8R8A8_UNORM }, + { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM }, + { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM }, + { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM }, + + // All these DRM_FORMATs were added in the same libdrm commit. +#ifdef DRM_FORMAT_XYUV8888 + { DRM_FORMAT_XYUV8888, VK_FORMAT_R8G8B8A8_UNORM }, + { DRM_FORMAT_XVYU12_16161616, VK_FORMAT_R16G16B16A16_UNORM} , + // As we had to map XV36 to a 16bit Vulkan format, reverse mapping will + // end up yielding Y416 as the DRM format, so we need to recognise it. + { DRM_FORMAT_Y416, VK_FORMAT_R16G16B16A16_UNORM }, +#endif +}; + +static inline VkFormat drm_to_vulkan_fmt(uint32_t drm_fourcc) +{ + for (int i = 0; i < FF_ARRAY_ELEMS(vulkan_drm_format_map); i++) + if (vulkan_drm_format_map[i].drm_fourcc == drm_fourcc) + return vulkan_drm_format_map[i].vk_format; + return VK_FORMAT_UNDEFINED; +} + +static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **frame, + const AVFrame *src) +{ + int err = 0; + VkResult ret; + AVVkFrame *f; + int bind_counts = 0; + AVHWDeviceContext *ctx = hwfc->device_ctx; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + VulkanFramesPriv *fp = hwfc->internal->priv; + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0]; + VkBindImageMemoryInfo bind_info[AV_DRM_MAX_PLANES]; + VkBindImagePlaneMemoryInfo plane_info[AV_DRM_MAX_PLANES]; + + for (int i = 0; i < desc->nb_layers; i++) { + if (drm_to_vulkan_fmt(desc->layers[i].format) == VK_FORMAT_UNDEFINED) { + av_log(ctx, AV_LOG_ERROR, "Unsupported DMABUF layer format %#08x!\n", + desc->layers[i].format); + return AVERROR(EINVAL); + } + } + + if (!(f = av_vk_frame_alloc())) { + av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n"); + err = AVERROR(ENOMEM); + goto fail; + } + + f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; + + for (int i = 0; i < desc->nb_layers; i++) { + const int planes = desc->layers[i].nb_planes; + + /* Semaphore */ + VkSemaphoreTypeCreateInfo sem_type_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, + .initialValue = 0, + }; + VkSemaphoreCreateInfo sem_spawn = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = &sem_type_info, + }; + + /* Image creation */ + VkSubresourceLayout ext_img_layouts[AV_DRM_MAX_PLANES]; + VkImageDrmFormatModifierExplicitCreateInfoEXT ext_img_mod_spec = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT, + .drmFormatModifier = desc->objects[0].format_modifier, + .drmFormatModifierPlaneCount = planes, + .pPlaneLayouts = (const VkSubresourceLayout *)&ext_img_layouts, + }; + VkExternalMemoryImageCreateInfo ext_img_spec = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + .pNext = &ext_img_mod_spec, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + VkImageCreateInfo create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = &ext_img_spec, + .imageType = VK_IMAGE_TYPE_2D, + .format = drm_to_vulkan_fmt(desc->layers[i].format), + .extent.depth = 1, + .mipLevels = 1, + .arrayLayers = 1, + .flags = 0x0, /* ALIAS flag is implicit for imported images */ + .tiling = f->tiling, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, /* specs say so */ + .usage = VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + .samples = VK_SAMPLE_COUNT_1_BIT, + .pQueueFamilyIndices = p->qfs, + .queueFamilyIndexCount = p->num_qfs, + .sharingMode = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT : + VK_SHARING_MODE_EXCLUSIVE, + }; + + /* Image format verification */ + VkExternalImageFormatProperties ext_props = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR, + }; + VkImageFormatProperties2 props_ret = { + .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + .pNext = &ext_props, + }; + VkPhysicalDeviceImageDrmFormatModifierInfoEXT props_drm_mod = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .drmFormatModifier = ext_img_mod_spec.drmFormatModifier, + .pQueueFamilyIndices = create_info.pQueueFamilyIndices, + .queueFamilyIndexCount = create_info.queueFamilyIndexCount, + .sharingMode = create_info.sharingMode, + }; + VkPhysicalDeviceExternalImageFormatInfo props_ext = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + .pNext = &props_drm_mod, + .handleType = ext_img_spec.handleTypes, + }; + VkPhysicalDeviceImageFormatInfo2 fmt_props = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + .pNext = &props_ext, + .format = create_info.format, + .type = create_info.imageType, + .tiling = create_info.tiling, + .usage = create_info.usage, + .flags = create_info.flags, + }; + + /* Check if importing is possible for this combination of parameters */ + ret = vk->GetPhysicalDeviceImageFormatProperties2(hwctx->phys_dev, + &fmt_props, &props_ret); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Cannot map DRM frame to Vulkan: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + /* Set the image width/height */ + get_plane_wh(&create_info.extent.width, &create_info.extent.height, + hwfc->sw_format, src->width, src->height, i); + + /* Set the subresource layout based on the layer properties */ + for (int j = 0; j < planes; j++) { + ext_img_layouts[j].offset = desc->layers[i].planes[j].offset; + ext_img_layouts[j].rowPitch = desc->layers[i].planes[j].pitch; + ext_img_layouts[j].size = 0; /* The specs say so for all 3 */ + ext_img_layouts[j].arrayPitch = 0; + ext_img_layouts[j].depthPitch = 0; + } + + /* Create image */ + ret = vk->CreateImage(hwctx->act_dev, &create_info, + hwctx->alloc, &f->img[i]); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n", + vk_ret2str(ret)); + err = AVERROR(EINVAL); + goto fail; + } + + ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn, + hwctx->alloc, &f->sem[i]); + if (ret != VK_SUCCESS) { + av_log(hwctx, AV_LOG_ERROR, "Failed to create semaphore: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + /* We'd import a semaphore onto the one we created using + * vkImportSemaphoreFdKHR but unfortunately neither DRM nor VAAPI + * offer us anything we could import and sync with, so instead + * just signal the semaphore we created. */ + + f->layout[i] = create_info.initialLayout; + f->access[i] = 0x0; + f->sem_value[i] = 0; + } + + for (int i = 0; i < desc->nb_objects; i++) { + /* Memory requirements */ + VkImageMemoryRequirementsInfo2 req_desc = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, + .image = f->img[i], + }; + VkMemoryDedicatedRequirements ded_req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + }; + VkMemoryRequirements2 req2 = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &ded_req, + }; + + /* Allocation/importing */ + VkMemoryFdPropertiesKHR fdmp = { + .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR, + }; + VkImportMemoryFdInfoKHR idesc = { + .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, + .fd = dup(desc->objects[i].fd), + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + VkMemoryDedicatedAllocateInfo ded_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = &idesc, + .image = req_desc.image, + }; + + /* Get object properties */ + ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + idesc.fd, &fdmp); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to get FD properties: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + close(idesc.fd); + goto fail; + } + + vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2); + + /* Only a single bit must be set, not a range, and it must match */ + req2.memoryRequirements.memoryTypeBits = fdmp.memoryTypeBits; + + err = alloc_mem(ctx, &req2.memoryRequirements, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + (ded_req.prefersDedicatedAllocation || + ded_req.requiresDedicatedAllocation) ? + &ded_alloc : ded_alloc.pNext, + &f->flags, &f->mem[i]); + if (err) { + close(idesc.fd); + return err; + } + + f->size[i] = req2.memoryRequirements.size; + } + + for (int i = 0; i < desc->nb_layers; i++) { + const int planes = desc->layers[i].nb_planes; + for (int j = 0; j < planes; j++) { + VkImageAspectFlagBits aspect = j == 0 ? VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT : + j == 1 ? VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT : + VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT; + + plane_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO; + plane_info[bind_counts].pNext = NULL; + plane_info[bind_counts].planeAspect = aspect; + + bind_info[bind_counts].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO; + bind_info[bind_counts].pNext = planes > 1 ? &plane_info[bind_counts] : NULL; + bind_info[bind_counts].image = f->img[i]; + bind_info[bind_counts].memory = f->mem[desc->layers[i].planes[j].object_index]; + + /* Offset is already signalled via pPlaneLayouts above */ + bind_info[bind_counts].memoryOffset = 0; + + bind_counts++; + } + } + + /* Bind the allocated memory to the images */ + ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind memory: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + err = prepare_frame(hwfc, &fp->conv_ctx, f, PREP_MODE_EXTERNAL_IMPORT); + if (err) + goto fail; + + *frame = f; + + return 0; + +fail: + for (int i = 0; i < desc->nb_layers; i++) { + vk->DestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc); + vk->DestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc); + } + for (int i = 0; i < desc->nb_objects; i++) + vk->FreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc); + + av_free(f); + + return err; +} + +static int vulkan_map_from_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err = 0; + AVVkFrame *f; + + if ((err = vulkan_map_from_drm_frame_desc(hwfc, &f, src))) + return err; + + /* The unmapping function will free this */ + dst->data[0] = (uint8_t *)f; + dst->width = src->width; + dst->height = src->height; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &vulkan_unmap_from_drm, f); + if (err < 0) + goto fail; + + av_log(hwfc, AV_LOG_DEBUG, "Mapped DRM object to Vulkan!\n"); + + return 0; + +fail: + vulkan_frame_free(hwfc->device_ctx->hwctx, (uint8_t *)f); + dst->data[0] = NULL; + return err; +} + +#if CONFIG_VAAPI +static int vulkan_map_from_vaapi(AVHWFramesContext *dst_fc, + AVFrame *dst, const AVFrame *src, + int flags) +{ + int err; + AVFrame *tmp = av_frame_alloc(); + AVHWFramesContext *vaapi_fc = (AVHWFramesContext*)src->hw_frames_ctx->data; + AVVAAPIDeviceContext *vaapi_ctx = vaapi_fc->device_ctx->hwctx; + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + + if (!tmp) + return AVERROR(ENOMEM); + + /* We have to sync since like the previous comment said, no semaphores */ + vaSyncSurface(vaapi_ctx->display, surface_id); + + tmp->format = AV_PIX_FMT_DRM_PRIME; + + err = av_hwframe_map(tmp, src, flags); + if (err < 0) + goto fail; + + err = vulkan_map_from_drm(dst_fc, dst, tmp, flags); + if (err < 0) + goto fail; + + err = ff_hwframe_map_replace(dst, src); + +fail: + av_frame_free(&tmp); + return err; +} +#endif +#endif + +#if CONFIG_CUDA +static int vulkan_export_to_cuda(AVHWFramesContext *hwfc, + AVBufferRef *cuda_hwfc, + const AVFrame *frame) +{ + int err; + VkResult ret; + AVVkFrame *dst_f; + AVVkFrameInternal *dst_int; + AVHWDeviceContext *ctx = hwfc->device_ctx; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format); + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + AVHWFramesContext *cuda_fc = (AVHWFramesContext*)cuda_hwfc->data; + AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx; + AVCUDADeviceContext *cuda_dev = cuda_cu->hwctx; + AVCUDADeviceContextInternal *cu_internal = cuda_dev->internal; + CudaFunctions *cu = cu_internal->cuda_dl; + CUarray_format cufmt = desc->comp[0].depth > 8 ? CU_AD_FORMAT_UNSIGNED_INT16 : + CU_AD_FORMAT_UNSIGNED_INT8; + + dst_f = (AVVkFrame *)frame->data[0]; + + dst_int = dst_f->internal; + if (!dst_int || !dst_int->cuda_fc_ref) { + if (!dst_f->internal) + dst_f->internal = dst_int = av_mallocz(sizeof(*dst_f->internal)); + + if (!dst_int) + return AVERROR(ENOMEM); + + dst_int->cuda_fc_ref = av_buffer_ref(cuda_hwfc); + if (!dst_int->cuda_fc_ref) { + av_freep(&dst_f->internal); + return AVERROR(ENOMEM); + } + + for (int i = 0; i < planes; i++) { + CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = { + .offset = 0, + .arrayDesc = { + .Depth = 0, + .Format = cufmt, + .NumChannels = 1 + ((planes == 2) && i), + .Flags = 0, + }, + .numLevels = 1, + }; + int p_w, p_h; + +#ifdef _WIN32 + CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = { + .type = IsWindows8OrGreater() + ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 + : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT, + .size = dst_f->size[i], + }; + VkMemoryGetWin32HandleInfoKHR export_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, + .memory = dst_f->mem[i], + .handleType = IsWindows8OrGreater() + ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT + : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + }; + VkSemaphoreGetWin32HandleInfoKHR sem_export = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, + .semaphore = dst_f->sem[i], + .handleType = IsWindows8OrGreater() + ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT + : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + }; + CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = { + .type = 10 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 */, + }; + + ret = vk->GetMemoryWin32HandleKHR(hwctx->act_dev, &export_info, + &ext_desc.handle.win32.handle); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a Win32 Handle: %s!\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + dst_int->ext_mem_handle[i] = ext_desc.handle.win32.handle; +#else + CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = { + .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD, + .size = dst_f->size[i], + }; + VkMemoryGetFdInfoKHR export_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, + .memory = dst_f->mem[i], + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, + }; + VkSemaphoreGetFdInfoKHR sem_export = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, + .semaphore = dst_f->sem[i], + .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, + }; + CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = { + .type = 9 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD */, + }; + + ret = vk->GetMemoryFdKHR(hwctx->act_dev, &export_info, + &ext_desc.handle.fd); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a FD: %s!\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } +#endif + + ret = CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[i], &ext_desc)); + if (ret < 0) { +#ifndef _WIN32 + close(ext_desc.handle.fd); +#endif + err = AVERROR_EXTERNAL; + goto fail; + } + + get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i); + tex_desc.arrayDesc.Width = p_w; + tex_desc.arrayDesc.Height = p_h; + + ret = CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[i], + dst_int->ext_mem[i], + &tex_desc)); + if (ret < 0) { + err = AVERROR_EXTERNAL; + goto fail; + } + + ret = CHECK_CU(cu->cuMipmappedArrayGetLevel(&dst_int->cu_array[i], + dst_int->cu_mma[i], 0)); + if (ret < 0) { + err = AVERROR_EXTERNAL; + goto fail; + } + +#ifdef _WIN32 + ret = vk->GetSemaphoreWin32HandleKHR(hwctx->act_dev, &sem_export, + &ext_sem_desc.handle.win32.handle); +#else + ret = vk->GetSemaphoreFdKHR(hwctx->act_dev, &sem_export, + &ext_sem_desc.handle.fd); +#endif + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to export semaphore: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } +#ifdef _WIN32 + dst_int->ext_sem_handle[i] = ext_sem_desc.handle.win32.handle; +#endif + + ret = CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[i], + &ext_sem_desc)); + if (ret < 0) { +#ifndef _WIN32 + close(ext_sem_desc.handle.fd); +#endif + err = AVERROR_EXTERNAL; + goto fail; + } + } + } + + return 0; + +fail: + vulkan_free_internal(dst_f); + return err; +} + +static int vulkan_transfer_data_from_cuda(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + int err; + CUcontext dummy; + AVVkFrame *dst_f; + AVVkFrameInternal *dst_int; + VulkanFramesPriv *fp = hwfc->internal->priv; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format); + + AVHWFramesContext *cuda_fc = (AVHWFramesContext*)src->hw_frames_ctx->data; + AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx; + AVCUDADeviceContext *cuda_dev = cuda_cu->hwctx; + AVCUDADeviceContextInternal *cu_internal = cuda_dev->internal; + CudaFunctions *cu = cu_internal->cuda_dl; + CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS s_w_par[AV_NUM_DATA_POINTERS] = { 0 }; + CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS s_s_par[AV_NUM_DATA_POINTERS] = { 0 }; + + dst_f = (AVVkFrame *)dst->data[0]; + + err = prepare_frame(hwfc, &fp->upload_ctx, dst_f, PREP_MODE_EXTERNAL_EXPORT); + if (err < 0) + return err; + + err = CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx)); + if (err < 0) + return err; + + err = vulkan_export_to_cuda(hwfc, src->hw_frames_ctx, dst); + if (err < 0) { + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return err; + } + + dst_int = dst_f->internal; + + for (int i = 0; i < planes; i++) { + s_w_par[i].params.fence.value = dst_f->sem_value[i] + 0; + s_s_par[i].params.fence.value = dst_f->sem_value[i] + 1; + } + + err = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par, + planes, cuda_dev->stream)); + if (err < 0) + goto fail; + + for (int i = 0; i < planes; i++) { + CUDA_MEMCPY2D cpy = { + .srcMemoryType = CU_MEMORYTYPE_DEVICE, + .srcDevice = (CUdeviceptr)src->data[i], + .srcPitch = src->linesize[i], + .srcY = 0, + + .dstMemoryType = CU_MEMORYTYPE_ARRAY, + .dstArray = dst_int->cu_array[i], + }; + + int p_w, p_h; + get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i); + + cpy.WidthInBytes = p_w * desc->comp[i].step; + cpy.Height = p_h; + + err = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream)); + if (err < 0) + goto fail; + } + + err = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par, + planes, cuda_dev->stream)); + if (err < 0) + goto fail; + + for (int i = 0; i < planes; i++) + dst_f->sem_value[i]++; + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + av_log(hwfc, AV_LOG_VERBOSE, "Transfered CUDA image to Vulkan!\n"); + + return err = prepare_frame(hwfc, &fp->upload_ctx, dst_f, PREP_MODE_EXTERNAL_IMPORT); + +fail: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + vulkan_free_internal(dst_f); + dst_f->internal = NULL; + av_buffer_unref(&dst->buf[0]); + return err; +} +#endif + +static int vulkan_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_unused VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + + switch (src->format) { +#if CONFIG_LIBDRM +#if CONFIG_VAAPI + case AV_PIX_FMT_VAAPI: + if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS)) + return vulkan_map_from_vaapi(hwfc, dst, src, flags); + else + return AVERROR(ENOSYS); +#endif + case AV_PIX_FMT_DRM_PRIME: + if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS)) + return vulkan_map_from_drm(hwfc, dst, src, flags); + else + return AVERROR(ENOSYS); +#endif + default: + return AVERROR(ENOSYS); + } +} + +#if CONFIG_LIBDRM +typedef struct VulkanDRMMapping { + AVDRMFrameDescriptor drm_desc; + AVVkFrame *source; +} VulkanDRMMapping; + +static void vulkan_unmap_to_drm(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap) +{ + AVDRMFrameDescriptor *drm_desc = hwmap->priv; + + for (int i = 0; i < drm_desc->nb_objects; i++) + close(drm_desc->objects[i].fd); + + av_free(drm_desc); +} + +static inline uint32_t vulkan_fmt_to_drm(VkFormat vkfmt) +{ + for (int i = 0; i < FF_ARRAY_ELEMS(vulkan_drm_format_map); i++) + if (vulkan_drm_format_map[i].vk_format == vkfmt) + return vulkan_drm_format_map[i].drm_fourcc; + return DRM_FORMAT_INVALID; +} + +static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err = 0; + VkResult ret; + AVVkFrame *f = (AVVkFrame *)src->data[0]; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + VulkanFramesPriv *fp = hwfc->internal->priv; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVVulkanFramesContext *hwfctx = hwfc->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VkImageDrmFormatModifierPropertiesEXT drm_mod = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT, + }; + VkSemaphoreWaitInfo wait_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + .flags = 0x0, + .semaphoreCount = planes, + }; + + AVDRMFrameDescriptor *drm_desc = av_mallocz(sizeof(*drm_desc)); + if (!drm_desc) + return AVERROR(ENOMEM); + + err = prepare_frame(hwfc, &fp->conv_ctx, f, PREP_MODE_EXTERNAL_EXPORT); + if (err < 0) + goto end; + + /* Wait for the operation to finish so we can cleanly export it. */ + wait_info.pSemaphores = f->sem; + wait_info.pValues = f->sem_value; + + vk->WaitSemaphores(hwctx->act_dev, &wait_info, UINT64_MAX); + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, &vulkan_unmap_to_drm, drm_desc); + if (err < 0) + goto end; + + ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->act_dev, f->img[0], + &drm_mod); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to retrieve DRM format modifier!\n"); + err = AVERROR_EXTERNAL; + goto end; + } + + for (int i = 0; (i < planes) && (f->mem[i]); i++) { + VkMemoryGetFdInfoKHR export_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, + .memory = f->mem[i], + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + + ret = vk->GetMemoryFdKHR(hwctx->act_dev, &export_info, + &drm_desc->objects[i].fd); + if (ret != VK_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a FD!\n"); + err = AVERROR_EXTERNAL; + goto end; + } + + drm_desc->nb_objects++; + drm_desc->objects[i].size = f->size[i]; + drm_desc->objects[i].format_modifier = drm_mod.drmFormatModifier; + } + + drm_desc->nb_layers = planes; + for (int i = 0; i < drm_desc->nb_layers; i++) { + VkSubresourceLayout layout; + VkImageSubresource sub = { + .aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT, + }; + VkFormat plane_vkfmt = av_vkfmt_from_pixfmt(hwfc->sw_format)[i]; + + drm_desc->layers[i].format = vulkan_fmt_to_drm(plane_vkfmt); + drm_desc->layers[i].nb_planes = 1; + + if (drm_desc->layers[i].format == DRM_FORMAT_INVALID) { + av_log(hwfc, AV_LOG_ERROR, "Cannot map to DRM layer, unsupported!\n"); + err = AVERROR_PATCHWELCOME; + goto end; + } + + drm_desc->layers[i].planes[0].object_index = FFMIN(i, drm_desc->nb_objects - 1); + + if (f->tiling == VK_IMAGE_TILING_OPTIMAL) + continue; + + vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout); + drm_desc->layers[i].planes[0].offset = layout.offset; + drm_desc->layers[i].planes[0].pitch = layout.rowPitch; + + if (hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) + drm_desc->layers[i].planes[0].offset += f->offset[i]; + } + + dst->width = src->width; + dst->height = src->height; + dst->data[0] = (uint8_t *)drm_desc; + + av_log(hwfc, AV_LOG_VERBOSE, "Mapped AVVkFrame to a DRM object!\n"); + + return 0; + +end: + av_free(drm_desc); + return err; +} + +#if CONFIG_VAAPI +static int vulkan_map_to_vaapi(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + AVFrame *tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + tmp->format = AV_PIX_FMT_DRM_PRIME; + + err = vulkan_map_to_drm(hwfc, tmp, src, flags); + if (err < 0) + goto fail; + + err = av_hwframe_map(dst, tmp, flags); + if (err < 0) + goto fail; + + err = ff_hwframe_map_replace(dst, src); + +fail: + av_frame_free(&tmp); + return err; +} +#endif +#endif + +static int vulkan_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_unused VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + + switch (dst->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS)) + return vulkan_map_to_drm(hwfc, dst, src, flags); + else + return AVERROR(ENOSYS); +#if CONFIG_VAAPI + case AV_PIX_FMT_VAAPI: + if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS)) + return vulkan_map_to_vaapi(hwfc, dst, src, flags); + else + return AVERROR(ENOSYS); +#endif +#endif + default: + return vulkan_map_frame_to_mem(hwfc, dst, src, flags); + } +} + +typedef struct ImageBuffer { + VkBuffer buf; + VkDeviceMemory mem; + VkMemoryPropertyFlagBits flags; + int mapped_mem; +} ImageBuffer; + +static void free_buf(void *opaque, uint8_t *data) +{ + AVHWDeviceContext *ctx = opaque; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + ImageBuffer *vkbuf = (ImageBuffer *)data; + + if (vkbuf->buf) + vk->DestroyBuffer(hwctx->act_dev, vkbuf->buf, hwctx->alloc); + if (vkbuf->mem) + vk->FreeMemory(hwctx->act_dev, vkbuf->mem, hwctx->alloc); + + av_free(data); +} + +static size_t get_req_buffer_size(VulkanDevicePriv *p, int *stride, int height) +{ + size_t size; + *stride = FFALIGN(*stride, p->props.properties.limits.optimalBufferCopyRowPitchAlignment); + size = height*(*stride); + size = FFALIGN(size, p->props.properties.limits.minMemoryMapAlignment); + return size; +} + +static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf, + VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags, + size_t size, uint32_t req_memory_bits, int host_mapped, + void *create_pnext, void *alloc_pnext) +{ + int err; + VkResult ret; + int use_ded_mem; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + VkBufferCreateInfo buf_spawn = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = create_pnext, + .usage = usage, + .size = size, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + + VkBufferMemoryRequirementsInfo2 req_desc = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + }; + VkMemoryDedicatedAllocateInfo ded_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = alloc_pnext, + }; + VkMemoryDedicatedRequirements ded_req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + }; + VkMemoryRequirements2 req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &ded_req, + }; + + ImageBuffer *vkbuf = av_mallocz(sizeof(*vkbuf)); + if (!vkbuf) + return AVERROR(ENOMEM); + + vkbuf->mapped_mem = host_mapped; + + ret = vk->CreateBuffer(hwctx->act_dev, &buf_spawn, NULL, &vkbuf->buf); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to create buffer: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + req_desc.buffer = vkbuf->buf; + + vk->GetBufferMemoryRequirements2(hwctx->act_dev, &req_desc, &req); + + /* In case the implementation prefers/requires dedicated allocation */ + use_ded_mem = ded_req.prefersDedicatedAllocation | + ded_req.requiresDedicatedAllocation; + if (use_ded_mem) + ded_alloc.buffer = vkbuf->buf; + + /* Additional requirements imposed on us */ + if (req_memory_bits) + req.memoryRequirements.memoryTypeBits &= req_memory_bits; + + err = alloc_mem(ctx, &req.memoryRequirements, flags, + use_ded_mem ? &ded_alloc : (void *)ded_alloc.pNext, + &vkbuf->flags, &vkbuf->mem); + if (err) + goto fail; + + ret = vk->BindBufferMemory(hwctx->act_dev, vkbuf->buf, vkbuf->mem, 0); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind memory to buffer: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + *buf = av_buffer_create((uint8_t *)vkbuf, sizeof(*vkbuf), free_buf, ctx, 0); + if (!(*buf)) { + err = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + free_buf(ctx, (uint8_t *)vkbuf); + return err; +} + +/* Skips mapping of host mapped buffers but still invalidates them */ +static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[], + int nb_buffers, int invalidate) +{ + VkResult ret; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + VkMappedMemoryRange invalidate_ctx[AV_NUM_DATA_POINTERS]; + int invalidate_count = 0; + + for (int i = 0; i < nb_buffers; i++) { + ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; + if (vkbuf->mapped_mem) + continue; + + ret = vk->MapMemory(hwctx->act_dev, vkbuf->mem, 0, + VK_WHOLE_SIZE, 0, (void **)&mem[i]); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to map buffer memory: %s\n", + vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + if (!invalidate) + return 0; + + for (int i = 0; i < nb_buffers; i++) { + ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; + const VkMappedMemoryRange ival_buf = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .memory = vkbuf->mem, + .size = VK_WHOLE_SIZE, + }; + + /* For host imported memory Vulkan says to use platform-defined + * sync methods, but doesn't really say not to call flush or invalidate + * on original host pointers. It does explicitly allow to do that on + * host-mapped pointers which are then mapped again using vkMapMemory, + * but known implementations return the original pointers when mapped + * again. */ + if (vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + continue; + + invalidate_ctx[invalidate_count++] = ival_buf; + } + + if (invalidate_count) { + ret = vk->InvalidateMappedMemoryRanges(hwctx->act_dev, invalidate_count, + invalidate_ctx); + if (ret != VK_SUCCESS) + av_log(ctx, AV_LOG_WARNING, "Failed to invalidate memory: %s\n", + vk_ret2str(ret)); + } + + return 0; +} + +static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, + int nb_buffers, int flush) +{ + int err = 0; + VkResult ret; + AVVulkanDeviceContext *hwctx = ctx->hwctx; + VulkanDevicePriv *p = ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + VkMappedMemoryRange flush_ctx[AV_NUM_DATA_POINTERS]; + int flush_count = 0; + + if (flush) { + for (int i = 0; i < nb_buffers; i++) { + ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; + const VkMappedMemoryRange flush_buf = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .memory = vkbuf->mem, + .size = VK_WHOLE_SIZE, + }; + + if (vkbuf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + continue; + + flush_ctx[flush_count++] = flush_buf; + } + } + + if (flush_count) { + ret = vk->FlushMappedMemoryRanges(hwctx->act_dev, flush_count, flush_ctx); + if (ret != VK_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to flush memory: %s\n", + vk_ret2str(ret)); + err = AVERROR_EXTERNAL; /* We still want to try to unmap them */ + } + } + + for (int i = 0; i < nb_buffers; i++) { + ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; + if (vkbuf->mapped_mem) + continue; + + vk->UnmapMemory(hwctx->act_dev, vkbuf->mem); + } + + return err; +} + +static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f, + AVBufferRef **bufs, size_t *buf_offsets, + const int *buf_stride, int w, + int h, enum AVPixelFormat pix_fmt, int to_buf) +{ + int err; + AVVkFrame *frame = (AVVkFrame *)f->data[0]; + VulkanFramesPriv *fp = hwfc->internal->priv; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + int bar_num = 0; + VkPipelineStageFlagBits sem_wait_dst[AV_NUM_DATA_POINTERS]; + + const int planes = av_pix_fmt_count_planes(pix_fmt); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + + VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 }; + VulkanExecCtx *ectx = to_buf ? &fp->download_ctx : &fp->upload_ctx; + VkCommandBuffer cmd_buf = get_buf_exec_ctx(hwfc, ectx); + + uint64_t sem_signal_values[AV_NUM_DATA_POINTERS]; + + VkTimelineSemaphoreSubmitInfo s_timeline_sem_info = { + .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + .pWaitSemaphoreValues = frame->sem_value, + .pSignalSemaphoreValues = sem_signal_values, + .waitSemaphoreValueCount = planes, + .signalSemaphoreValueCount = planes, + }; + + VkSubmitInfo s_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = &s_timeline_sem_info, + .pSignalSemaphores = frame->sem, + .pWaitSemaphores = frame->sem, + .pWaitDstStageMask = sem_wait_dst, + .signalSemaphoreCount = planes, + .waitSemaphoreCount = planes, + }; + + for (int i = 0; i < planes; i++) + sem_signal_values[i] = frame->sem_value[i] + 1; + + if ((err = wait_start_exec_ctx(hwfc, ectx))) + return err; + + /* Change the image layout to something more optimal for transfers */ + for (int i = 0; i < planes; i++) { + VkImageLayout new_layout = to_buf ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + VkAccessFlags new_access = to_buf ? VK_ACCESS_TRANSFER_READ_BIT : + VK_ACCESS_TRANSFER_WRITE_BIT; + + sem_wait_dst[i] = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + /* If the layout matches and we have read access skip the barrier */ + if ((frame->layout[i] == new_layout) && (frame->access[i] & new_access)) + continue; + + img_bar[bar_num].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + img_bar[bar_num].srcAccessMask = 0x0; + img_bar[bar_num].dstAccessMask = new_access; + img_bar[bar_num].oldLayout = frame->layout[i]; + img_bar[bar_num].newLayout = new_layout; + img_bar[bar_num].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + img_bar[bar_num].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + img_bar[bar_num].image = frame->img[i]; + img_bar[bar_num].subresourceRange.levelCount = 1; + img_bar[bar_num].subresourceRange.layerCount = 1; + img_bar[bar_num].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + frame->layout[i] = img_bar[bar_num].newLayout; + frame->access[i] = img_bar[bar_num].dstAccessMask; + + bar_num++; + } + + if (bar_num) + vk->CmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, + 0, NULL, 0, NULL, bar_num, img_bar); + + /* Schedule a copy for each plane */ + for (int i = 0; i < planes; i++) { + ImageBuffer *vkbuf = (ImageBuffer *)bufs[i]->data; + VkBufferImageCopy buf_reg = { + .bufferOffset = buf_offsets[i], + .bufferRowLength = buf_stride[i] / desc->comp[i].step, + .imageSubresource.layerCount = 1, + .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .imageOffset = { 0, 0, 0, }, + }; + + int p_w, p_h; + get_plane_wh(&p_w, &p_h, pix_fmt, w, h, i); + + buf_reg.bufferImageHeight = p_h; + buf_reg.imageExtent = (VkExtent3D){ p_w, p_h, 1, }; + + if (to_buf) + vk->CmdCopyImageToBuffer(cmd_buf, frame->img[i], frame->layout[i], + vkbuf->buf, 1, &buf_reg); + else + vk->CmdCopyBufferToImage(cmd_buf, vkbuf->buf, frame->img[i], + frame->layout[i], 1, &buf_reg); + } + + /* When uploading, do this asynchronously if the source is refcounted by + * keeping the buffers as a submission dependency. + * The hwcontext is guaranteed to not be freed until all frames are freed + * in the frames_unint function. + * When downloading to buffer, do this synchronously and wait for the + * queue submission to finish executing */ + if (!to_buf) { + int ref; + for (ref = 0; ref < AV_NUM_DATA_POINTERS; ref++) { + if (!f->buf[ref]) + break; + if ((err = add_buf_dep_exec_ctx(hwfc, ectx, &f->buf[ref], 1))) + return err; + } + if (ref && (err = add_buf_dep_exec_ctx(hwfc, ectx, bufs, planes))) + return err; + return submit_exec_ctx(hwfc, ectx, &s_info, frame, !ref); + } else { + return submit_exec_ctx(hwfc, ectx, &s_info, frame, 1); + } +} + +static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf, + const AVFrame *swf, int from) +{ + int err = 0; + VkResult ret; + AVVkFrame *f = (AVVkFrame *)vkf->data[0]; + AVHWDeviceContext *dev_ctx = hwfc->device_ctx; + AVVulkanDeviceContext *hwctx = dev_ctx->hwctx; + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; + + AVFrame tmp; + AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 }; + size_t buf_offsets[AV_NUM_DATA_POINTERS] = { 0 }; + + int p_w, p_h; + const int planes = av_pix_fmt_count_planes(swf->format); + + int host_mapped[AV_NUM_DATA_POINTERS] = { 0 }; + const int map_host = !!(p->extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY); + + if ((swf->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(swf->format))) { + av_log(hwfc, AV_LOG_ERROR, "Unsupported software frame pixel format!\n"); + return AVERROR(EINVAL); + } + + if (swf->width > hwfc->width || swf->height > hwfc->height) + return AVERROR(EINVAL); + + /* For linear, host visiable images */ + if (f->tiling == VK_IMAGE_TILING_LINEAR && + f->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + AVFrame *map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = swf->format; + + err = vulkan_map_frame_to_mem(hwfc, map, vkf, AV_HWFRAME_MAP_WRITE); + if (err) + return err; + + err = av_frame_copy((AVFrame *)(from ? swf : map), from ? map : swf); + av_frame_free(&map); + return err; + } + + /* Create buffers */ + for (int i = 0; i < planes; i++) { + size_t req_size; + + VkExternalMemoryBufferCreateInfo create_desc = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, + }; + + VkImportMemoryHostPointerInfoEXT import_desc = { + .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, + }; + + VkMemoryHostPointerPropertiesEXT p_props = { + .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT, + }; + + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); + + tmp.linesize[i] = FFABS(swf->linesize[i]); + + /* Do not map images with a negative stride */ + if (map_host && swf->linesize[i] > 0) { + size_t offs; + offs = (uintptr_t)swf->data[i] % p->hprops.minImportedHostPointerAlignment; + import_desc.pHostPointer = swf->data[i] - offs; + + /* We have to compensate for the few extra bytes of padding we + * completely ignore at the start */ + req_size = FFALIGN(offs + tmp.linesize[i] * p_h, + p->hprops.minImportedHostPointerAlignment); + + ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->act_dev, + import_desc.handleType, + import_desc.pHostPointer, + &p_props); + + if (ret == VK_SUCCESS) { + host_mapped[i] = 1; + buf_offsets[i] = offs; + } + } + + if (!host_mapped[i]) + req_size = get_req_buffer_size(p, &tmp.linesize[i], p_h); + + err = create_buf(dev_ctx, &bufs[i], + from ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + req_size, p_props.memoryTypeBits, host_mapped[i], + host_mapped[i] ? &create_desc : NULL, + host_mapped[i] ? &import_desc : NULL); + if (err) + goto end; + } + + if (!from) { + /* Map, copy image TO buffer (which then goes to the VkImage), unmap */ + if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 0))) + goto end; + + for (int i = 0; i < planes; i++) { + if (host_mapped[i]) + continue; + + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); + + av_image_copy_plane(tmp.data[i], tmp.linesize[i], + (const uint8_t *)swf->data[i], swf->linesize[i], + FFMIN(tmp.linesize[i], FFABS(swf->linesize[i])), + p_h); + } + + if ((err = unmap_buffers(dev_ctx, bufs, planes, 1))) + goto end; + } + + /* Copy buffers into/from image */ + err = transfer_image_buf(hwfc, vkf, bufs, buf_offsets, tmp.linesize, + swf->width, swf->height, swf->format, from); + + if (from) { + /* Map, copy buffer (which came FROM the VkImage) to the frame, unmap */ + if ((err = map_buffers(dev_ctx, bufs, tmp.data, planes, 0))) + goto end; + + for (int i = 0; i < planes; i++) { + if (host_mapped[i]) + continue; + + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); + + av_image_copy_plane_uc_from(swf->data[i], swf->linesize[i], + (const uint8_t *)tmp.data[i], tmp.linesize[i], + FFMIN(tmp.linesize[i], FFABS(swf->linesize[i])), + p_h); + } + + if ((err = unmap_buffers(dev_ctx, bufs, planes, 1))) + goto end; + } + +end: + for (int i = 0; i < planes; i++) + av_buffer_unref(&bufs[i]); + + return err; +} + +static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src) +{ + av_unused VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + + switch (src->format) { +#if CONFIG_CUDA + case AV_PIX_FMT_CUDA: +#ifdef _WIN32 + if ((p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) && + (p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM)) +#else + if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) && + (p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM)) +#endif + return vulkan_transfer_data_from_cuda(hwfc, dst, src); +#endif + default: + if (src->hw_frames_ctx) + return AVERROR(ENOSYS); + else + return vulkan_transfer_data(hwfc, dst, src, 0); + } +} + +#if CONFIG_CUDA +static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src) +{ + int err; + CUcontext dummy; + AVVkFrame *dst_f; + AVVkFrameInternal *dst_int; + VulkanFramesPriv *fp = hwfc->internal->priv; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format); + + AVHWFramesContext *cuda_fc = (AVHWFramesContext*)dst->hw_frames_ctx->data; + AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx; + AVCUDADeviceContext *cuda_dev = cuda_cu->hwctx; + AVCUDADeviceContextInternal *cu_internal = cuda_dev->internal; + CudaFunctions *cu = cu_internal->cuda_dl; + CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS s_w_par[AV_NUM_DATA_POINTERS] = { 0 }; + CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS s_s_par[AV_NUM_DATA_POINTERS] = { 0 }; + + dst_f = (AVVkFrame *)src->data[0]; + + err = prepare_frame(hwfc, &fp->upload_ctx, dst_f, PREP_MODE_EXTERNAL_EXPORT); + if (err < 0) + return err; + + err = CHECK_CU(cu->cuCtxPushCurrent(cuda_dev->cuda_ctx)); + if (err < 0) + return err; + + err = vulkan_export_to_cuda(hwfc, dst->hw_frames_ctx, src); + if (err < 0) { + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return err; + } + + dst_int = dst_f->internal; + + for (int i = 0; i < planes; i++) { + s_w_par[i].params.fence.value = dst_f->sem_value[i] + 0; + s_s_par[i].params.fence.value = dst_f->sem_value[i] + 1; + } + + err = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par, + planes, cuda_dev->stream)); + if (err < 0) + goto fail; + + for (int i = 0; i < planes; i++) { + CUDA_MEMCPY2D cpy = { + .dstMemoryType = CU_MEMORYTYPE_DEVICE, + .dstDevice = (CUdeviceptr)dst->data[i], + .dstPitch = dst->linesize[i], + .dstY = 0, + + .srcMemoryType = CU_MEMORYTYPE_ARRAY, + .srcArray = dst_int->cu_array[i], + }; + + int w, h; + get_plane_wh(&w, &h, hwfc->sw_format, hwfc->width, hwfc->height, i); + + cpy.WidthInBytes = w * desc->comp[i].step; + cpy.Height = h; + + err = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, cuda_dev->stream)); + if (err < 0) + goto fail; + } + + err = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(dst_int->cu_sem, s_s_par, + planes, cuda_dev->stream)); + if (err < 0) + goto fail; + + for (int i = 0; i < planes; i++) + dst_f->sem_value[i]++; + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + av_log(hwfc, AV_LOG_VERBOSE, "Transfered Vulkan image to CUDA!\n"); + + return prepare_frame(hwfc, &fp->upload_ctx, dst_f, PREP_MODE_EXTERNAL_IMPORT); + +fail: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + vulkan_free_internal(dst_f); + dst_f->internal = NULL; + av_buffer_unref(&dst->buf[0]); + return err; +} +#endif + +static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src) +{ + av_unused VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + + switch (dst->format) { +#if CONFIG_CUDA + case AV_PIX_FMT_CUDA: +#ifdef _WIN32 + if ((p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) && + (p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM)) +#else + if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) && + (p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM)) +#endif + return vulkan_transfer_data_to_cuda(hwfc, dst, src); +#endif + default: + if (dst->hw_frames_ctx) + return AVERROR(ENOSYS); + else + return vulkan_transfer_data(hwfc, src, dst, 1); + } +} + +static int vulkan_frames_derive_to(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + return vulkan_frames_init(dst_fc); +} + +AVVkFrame *av_vk_frame_alloc(void) +{ + return av_mallocz(sizeof(AVVkFrame)); +} + +const HWContextType ff_hwcontext_type_vulkan = { + .type = AV_HWDEVICE_TYPE_VULKAN, + .name = "Vulkan", + + .device_hwctx_size = sizeof(AVVulkanDeviceContext), + .device_priv_size = sizeof(VulkanDevicePriv), + .frames_hwctx_size = sizeof(AVVulkanFramesContext), + .frames_priv_size = sizeof(VulkanFramesPriv), + + .device_init = &vulkan_device_init, + .device_create = &vulkan_device_create, + .device_derive = &vulkan_device_derive, + + .frames_get_constraints = &vulkan_frames_get_constraints, + .frames_init = vulkan_frames_init, + .frames_get_buffer = vulkan_get_buffer, + .frames_uninit = vulkan_frames_uninit, + + .transfer_get_formats = vulkan_transfer_get_formats, + .transfer_data_to = vulkan_transfer_data_to, + .transfer_data_from = vulkan_transfer_data_from, + + .map_to = vulkan_map_to, + .map_from = vulkan_map_from, + .frames_derive_to = &vulkan_frames_derive_to, + + .pix_fmts = (const enum AVPixelFormat []) { + AV_PIX_FMT_VULKAN, + AV_PIX_FMT_NONE + }, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.h b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.h new file mode 100644 index 00000000..df86c85b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/hwcontext_vulkan.h @@ -0,0 +1,281 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VULKAN_H +#define AVUTIL_HWCONTEXT_VULKAN_H + +#if defined(_WIN32) && !defined(VK_USE_PLATFORM_WIN32_KHR) +#define VK_USE_PLATFORM_WIN32_KHR +#endif +#include + +#include "pixfmt.h" +#include "frame.h" + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_VULKAN. + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to an AVVkFrame. + */ + +/** + * Main Vulkan context, allocated as AVHWDeviceContext.hwctx. + * All of these can be set before init to change what the context uses + */ +typedef struct AVVulkanDeviceContext { + /** + * Custom memory allocator, else NULL + */ + const VkAllocationCallbacks *alloc; + + /** + * Pointer to the instance-provided vkGetInstanceProcAddr loading function. + * If NULL, will pick either libvulkan or libvolk, depending on libavutil's + * compilation settings, and set this field. + */ + PFN_vkGetInstanceProcAddr get_proc_addr; + + /** + * Vulkan instance. Must be at least version 1.2. + */ + VkInstance inst; + + /** + * Physical device + */ + VkPhysicalDevice phys_dev; + + /** + * Active device + */ + VkDevice act_dev; + + /** + * This structure should be set to the set of features that present and enabled + * during device creation. When a device is created by FFmpeg, it will default to + * enabling all that are present of the shaderImageGatherExtended, + * fragmentStoresAndAtomics, shaderInt64 and vertexPipelineStoresAndAtomics features. + */ + VkPhysicalDeviceFeatures2 device_features; + + /** + * Enabled instance extensions. + * If supplying your own device context, set this to an array of strings, with + * each entry containing the specified Vulkan extension string to enable. + * Duplicates are possible and accepted. + * If no extensions are enabled, set these fields to NULL, and 0 respectively. + */ + const char * const *enabled_inst_extensions; + int nb_enabled_inst_extensions; + + /** + * Enabled device extensions. By default, VK_KHR_external_memory_fd, + * VK_EXT_external_memory_dma_buf, VK_EXT_image_drm_format_modifier, + * VK_KHR_external_semaphore_fd and VK_EXT_external_memory_host are enabled if found. + * If supplying your own device context, these fields takes the same format as + * the above fields, with the same conditions that duplicates are possible + * and accepted, and that NULL and 0 respectively means no extensions are enabled. + */ + const char * const *enabled_dev_extensions; + int nb_enabled_dev_extensions; + + /** + * Queue family index for graphics operations, and the number of queues + * enabled for it. If unavaiable, will be set to -1. Not required. + * av_hwdevice_create() will attempt to find a dedicated queue for each + * queue family, or pick the one with the least unrelated flags set. + * Queue indices here may overlap if a queue has to share capabilities. + */ + int queue_family_index; + int nb_graphics_queues; + + /** + * Queue family index for transfer operations and the number of queues + * enabled. Required. + */ + int queue_family_tx_index; + int nb_tx_queues; + + /** + * Queue family index for compute operations and the number of queues + * enabled. Required. + */ + int queue_family_comp_index; + int nb_comp_queues; + + /** + * Queue family index for video encode ops, and the amount of queues enabled. + * If the device doesn't support such, queue_family_encode_index will be -1. + * Not required. + */ + int queue_family_encode_index; + int nb_encode_queues; + + /** + * Queue family index for video decode ops, and the amount of queues enabled. + * If the device doesn't support such, queue_family_decode_index will be -1. + * Not required. + */ + int queue_family_decode_index; + int nb_decode_queues; +} AVVulkanDeviceContext; + +/** + * Defines the behaviour of frame allocation. + */ +typedef enum AVVkFrameFlags { + /* Unless this flag is set, autodetected flags will be OR'd based on the + * device and tiling during av_hwframe_ctx_init(). */ + AV_VK_FRAME_FLAG_NONE = (1ULL << 0), + + /* Image planes will be allocated in a single VkDeviceMemory, rather + * than as per-plane VkDeviceMemory allocations. Required for exporting + * to VAAPI on Intel devices. */ + AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY = (1ULL << 1), +} AVVkFrameFlags; + +/** + * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options + */ +typedef struct AVVulkanFramesContext { + /** + * Controls the tiling of allocated frames. If left as optimal tiling, + * then during av_hwframe_ctx_init() will decide based on whether the device + * supports DRM modifiers, or if the linear_images flag is set, otherwise + * will allocate optimally-tiled images. + */ + VkImageTiling tiling; + + /** + * Defines extra usage of output frames. If left as 0, the following bits + * are set: TRANSFER_SRC, TRANSFER_DST. SAMPLED and STORAGE. + */ + VkImageUsageFlagBits usage; + + /** + * Extension data for image creation. + * If VkImageDrmFormatModifierListCreateInfoEXT is present in the chain, + * and the device supports DRM modifiers, then images will be allocated + * with the specific requested DRM modifiers. + * Additional structures may be added at av_hwframe_ctx_init() time, + * which will be freed automatically on uninit(), so users need only free + * any structures they've allocated themselves. + */ + void *create_pnext; + + /** + * Extension data for memory allocation. Must have as many entries as + * the number of planes of the sw_format. + * This will be chained to VkExportMemoryAllocateInfo, which is used + * to make all pool images exportable to other APIs if the necessary + * extensions are present in enabled_dev_extensions. + */ + void *alloc_pnext[AV_NUM_DATA_POINTERS]; + + /** + * A combination of AVVkFrameFlags. Unless AV_VK_FRAME_FLAG_NONE is set, + * autodetected flags will be OR'd based on the device and tiling during + * av_hwframe_ctx_init(). + */ + AVVkFrameFlags flags; +} AVVulkanFramesContext; + +/* + * Frame structure, the VkFormat of the image will always match + * the pool's sw_format. + * All frames, imported or allocated, will be created with the + * VK_IMAGE_CREATE_ALIAS_BIT flag set, so the memory may be aliased if needed. + * + * If all queue family indices in the device context are the same, + * images will be created with the EXCLUSIVE sharing mode. Otherwise, all images + * will be created using the CONCURRENT sharing mode. + * + * @note the size of this structure is not part of the ABI, to allocate + * you must use @av_vk_frame_alloc(). + */ +typedef struct AVVkFrame { + /** + * Vulkan images to which the memory is bound to. + */ + VkImage img[AV_NUM_DATA_POINTERS]; + + /** + * The same tiling must be used for all images in the frame. + */ + VkImageTiling tiling; + + /** + * Memory backing the images. Could be less than the amount of planes, + * in which case the offset value will indicate the binding offset of + * each plane in the memory. + */ + VkDeviceMemory mem[AV_NUM_DATA_POINTERS]; + size_t size[AV_NUM_DATA_POINTERS]; + + /** + * OR'd flags for all memory allocated + */ + VkMemoryPropertyFlagBits flags; + + /** + * Updated after every barrier + */ + VkAccessFlagBits access[AV_NUM_DATA_POINTERS]; + VkImageLayout layout[AV_NUM_DATA_POINTERS]; + + /** + * Synchronization timeline semaphores, one for each sw_format plane. + * Must not be freed manually. Must be waited on at every submission using + * the value in sem_value, and must be signalled at every submission, + * using an incremented value. + */ + VkSemaphore sem[AV_NUM_DATA_POINTERS]; + + /** + * Up to date semaphore value at which each image becomes accessible. + * Clients must wait on this value when submitting a command queue, + * and increment it when signalling. + */ + uint64_t sem_value[AV_NUM_DATA_POINTERS]; + + /** + * Internal data. + */ + struct AVVkFrameInternal *internal; + + /** + * Describes the binding offset of each plane to the VkDeviceMemory. + */ + ptrdiff_t offset[AV_NUM_DATA_POINTERS]; +} AVVkFrame; + +/** + * Allocates a single AVVkFrame and initializes everything as 0. + * @note Must be freed via av_free() + */ +AVVkFrame *av_vk_frame_alloc(void); + +/** + * Returns the format of each image up to the number of planes for a given sw_format. + * Returns NULL on unsupported formats. + */ +const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p); + +#endif /* AVUTIL_HWCONTEXT_VULKAN_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/imgutils.c b/arm/raspi/third_party/ffmpeg/libavutil/imgutils.c new file mode 100644 index 00000000..9ab5757c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/imgutils.c @@ -0,0 +1,692 @@ +/* + * 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 + * misc image utilities + */ + +#include "avassert.h" +#include "common.h" +#include "imgutils.h" +#include "imgutils_internal.h" +#include "internal.h" +#include "intreadwrite.h" +#include "log.h" +#include "mathematics.h" +#include "pixdesc.h" +#include "rational.h" + +void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc) +{ + int i; + memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0])); + if (max_pixstep_comps) + memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0])); + + for (i = 0; i < 4; i++) { + const AVComponentDescriptor *comp = &(pixdesc->comp[i]); + if (comp->step > max_pixsteps[comp->plane]) { + max_pixsteps[comp->plane] = comp->step; + if (max_pixstep_comps) + max_pixstep_comps[comp->plane] = i; + } + } +} + +static inline +int image_get_linesize(int width, int plane, + int max_step, int max_step_comp, + const AVPixFmtDescriptor *desc) +{ + int s, shifted_w, linesize; + + if (!desc) + return AVERROR(EINVAL); + + if (width < 0) + return AVERROR(EINVAL); + s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0; + shifted_w = ((width + (1 << s) - 1)) >> s; + if (shifted_w && max_step > INT_MAX / shifted_w) + return AVERROR(EINVAL); + linesize = max_step * shifted_w; + + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) + linesize = (linesize + 7) >> 3; + return linesize; +} + +int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int max_step [4]; /* max pixel step for each plane */ + int max_step_comp[4]; /* the component for each plane which has the max pixel step */ + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + av_image_fill_max_pixsteps(max_step, max_step_comp, desc); + return image_get_linesize(width, plane, max_step[plane], max_step_comp[plane], desc); +} + +int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width) +{ + int i, ret; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int max_step [4]; /* max pixel step for each plane */ + int max_step_comp[4]; /* the component for each plane which has the max pixel step */ + + memset(linesizes, 0, 4*sizeof(linesizes[0])); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + av_image_fill_max_pixsteps(max_step, max_step_comp, desc); + for (i = 0; i < 4; i++) { + if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < 0) + return ret; + linesizes[i] = ret; + } + + return 0; +} + +int av_image_fill_plane_sizes(size_t sizes[4], enum AVPixelFormat pix_fmt, + int height, const ptrdiff_t linesizes[4]) +{ + int i, has_plane[4] = { 0 }; + + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + memset(sizes , 0, sizeof(sizes[0])*4); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + if (linesizes[0] > SIZE_MAX / height) + return AVERROR(EINVAL); + sizes[0] = linesizes[0] * (size_t)height; + + if (desc->flags & AV_PIX_FMT_FLAG_PAL) { + sizes[1] = 256 * 4; /* palette is stored here as 256 32 bits words */ + return 0; + } + + for (i = 0; i < 4; i++) + has_plane[desc->comp[i].plane] = 1; + + for (i = 1; i < 4 && has_plane[i]; i++) { + int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + h = (height + (1 << s) - 1) >> s; + if (linesizes[i] > SIZE_MAX / h) + return AVERROR(EINVAL); + sizes[i] = (size_t)h * linesizes[i]; + } + + return 0; +} + +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]) +{ + int i, ret; + ptrdiff_t linesizes1[4]; + size_t sizes[4]; + + memset(data , 0, sizeof(data[0])*4); + + for (i = 0; i < 4; i++) + linesizes1[i] = linesizes[i]; + + ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, linesizes1); + if (ret < 0) + return ret; + + ret = 0; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - ret) + return AVERROR(EINVAL); + ret += sizes[i]; + } + + if (!ptr) + return ret; + + data[0] = ptr; + for (i = 1; i < 4 && sizes[i]; i++) + data[i] = data[i - 1] + sizes[i - 1]; + + return ret; +} + +int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt) +{ + int i; + + for (i = 0; i < 256; i++) { + int r, g, b; + + switch (pix_fmt) { + case AV_PIX_FMT_RGB8: + r = (i>>5 )*36; + g = ((i>>2)&7)*36; + b = (i&3 )*85; + break; + case AV_PIX_FMT_BGR8: + b = (i>>6 )*85; + g = ((i>>3)&7)*36; + r = (i&7 )*36; + break; + case AV_PIX_FMT_RGB4_BYTE: + r = (i>>3 )*255; + g = ((i>>1)&3)*85; + b = (i&1 )*255; + break; + case AV_PIX_FMT_BGR4_BYTE: + b = (i>>3 )*255; + g = ((i>>1)&3)*85; + r = (i&1 )*255; + break; + case AV_PIX_FMT_GRAY8: + r = b = g = i; + break; + default: + return AVERROR(EINVAL); + } + pal[i] = b + (g << 8) + (r << 16) + (0xFFU << 24); + } + + return 0; +} + +int av_image_alloc(uint8_t *pointers[4], int linesizes[4], + int w, int h, enum AVPixelFormat pix_fmt, int align) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i, ret; + ptrdiff_t linesizes1[4]; + size_t total_size, sizes[4]; + uint8_t *buf; + + if (!desc) + return AVERROR(EINVAL); + + if ((ret = av_image_check_size(w, h, 0, NULL)) < 0) + return ret; + if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0) + return ret; + + for (i = 0; i < 4; i++) { + linesizes[i] = FFALIGN(linesizes[i], align); + linesizes1[i] = linesizes[i]; + } + + if ((ret = av_image_fill_plane_sizes(sizes, pix_fmt, h, linesizes1)) < 0) + return ret; + total_size = align; + for (i = 0; i < 4; i++) { + if (total_size > SIZE_MAX - sizes[i]) + return AVERROR(EINVAL); + total_size += sizes[i]; + } + buf = av_malloc(total_size); + if (!buf) + return AVERROR(ENOMEM); + if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) { + av_free(buf); + return ret; + } + if (desc->flags & AV_PIX_FMT_FLAG_PAL) { + avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); + if (align < 4) { + av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); + av_free(buf); + return AVERROR(EINVAL); + } + } + + if (desc->flags & AV_PIX_FMT_FLAG_PAL && pointers[1] && + pointers[1] - pointers[0] > linesizes[0] * h) { + /* zero-initialize the padding before the palette */ + memset(pointers[0] + linesizes[0] * h, 0, + pointers[1] - pointers[0] - linesizes[0] * h); + } + + return ret; +} + +typedef struct ImgUtils { + const AVClass *class; + int log_offset; + void *log_ctx; +} ImgUtils; + +static const AVClass imgutils_class = { + .class_name = "IMGUTILS", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(ImgUtils, log_offset), + .parent_log_context_offset = offsetof(ImgUtils, log_ctx), +}; + +int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx) +{ + ImgUtils imgutils = { + .class = &imgutils_class, + .log_offset = log_offset, + .log_ctx = log_ctx, + }; + int64_t stride = av_image_get_linesize(pix_fmt, w, 0); + if (stride <= 0) + stride = 8LL*w; + stride += 128*8; + + if ((int)w<=0 || (int)h<=0 || stride >= INT_MAX || stride*(uint64_t)(h+128) >= INT_MAX) { + av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h); + return AVERROR(EINVAL); + } + + if (max_pixels < INT64_MAX) { + if (w*(int64_t)h > max_pixels) { + av_log(&imgutils, AV_LOG_ERROR, + "Picture size %ux%u exceeds specified max pixel count %"PRId64", see the documentation if you wish to increase it\n", + w, h, max_pixels); + return AVERROR(EINVAL); + } + } + + return 0; +} + +int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx) +{ + return av_image_check_size2(w, h, INT64_MAX, AV_PIX_FMT_NONE, log_offset, log_ctx); +} + +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) +{ + int64_t scaled_dim; + + if (sar.den <= 0 || sar.num < 0) + return AVERROR(EINVAL); + + if (!sar.num || sar.num == sar.den) + return 0; + + if (sar.num < sar.den) + scaled_dim = av_rescale_rnd(w, sar.num, sar.den, AV_ROUND_ZERO); + else + scaled_dim = av_rescale_rnd(h, sar.den, sar.num, AV_ROUND_ZERO); + + if (scaled_dim > 0) + return 0; + + return AVERROR(EINVAL); +} + +static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + if (!dst || !src) + return; + av_assert0(FFABS(src_linesize) >= bytewidth); + av_assert0(FFABS(dst_linesize) >= bytewidth); + for (;height > 0; height--) { + memcpy(dst, src, bytewidth); + dst += dst_linesize; + src += src_linesize; + } +} + +void av_image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int ret = -1; + +#if ARCH_X86 + ret = ff_image_copy_plane_uc_from_x86(dst, dst_linesize, src, src_linesize, + bytewidth, height); +#endif + + if (ret < 0) + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height) +{ + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height, + void (*copy_plane)(uint8_t *, ptrdiff_t, const uint8_t *, + ptrdiff_t, ptrdiff_t, int)) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return; + + if (desc->flags & AV_PIX_FMT_FLAG_PAL) { + copy_plane(dst_data[0], dst_linesizes[0], + src_data[0], src_linesizes[0], + width, height); + /* copy the palette */ + if ((desc->flags & AV_PIX_FMT_FLAG_PAL) || (dst_data[1] && src_data[1])) + memcpy(dst_data[1], src_data[1], 4*256); + } else { + int i, planes_nb = 0; + + for (i = 0; i < desc->nb_components; i++) + planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1); + + for (i = 0; i < planes_nb; i++) { + int h = height; + ptrdiff_t bwidth = av_image_get_linesize(pix_fmt, width, i); + if (bwidth < 0) { + av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n"); + return; + } + if (i == 1 || i == 2) { + h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h); + } + copy_plane(dst_data[i], dst_linesizes[i], + src_data[i], src_linesizes[i], + bwidth, h); + } + } +} + +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + ptrdiff_t dst_linesizes1[4], src_linesizes1[4]; + int i; + + for (i = 0; i < 4; i++) { + dst_linesizes1[i] = dst_linesizes[i]; + src_linesizes1[i] = src_linesizes[i]; + } + + image_copy(dst_data, dst_linesizes1, src_data, src_linesizes1, pix_fmt, + width, height, image_copy_plane); +} + +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + image_copy(dst_data, dst_linesizes, src_data, src_linesizes, pix_fmt, + width, height, av_image_copy_plane_uc_from); +} + +int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], + const uint8_t *src, enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + int ret, i; + + ret = av_image_check_size(width, height, 0, NULL); + if (ret < 0) + return ret; + + ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width); + if (ret < 0) + return ret; + + for (i = 0; i < 4; i++) + dst_linesize[i] = FFALIGN(dst_linesize[i], align); + + return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize); +} + +int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + int ret, i; + int linesize[4]; + ptrdiff_t aligned_linesize[4]; + size_t sizes[4]; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + if (!desc) + return AVERROR(EINVAL); + + ret = av_image_check_size(width, height, 0, NULL); + if (ret < 0) + return ret; + + ret = av_image_fill_linesizes(linesize, pix_fmt, width); + if (ret < 0) + return ret; + + for (i = 0; i < 4; i++) + aligned_linesize[i] = FFALIGN(linesize[i], align); + + ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, aligned_linesize); + if (ret < 0) + return ret; + + ret = 0; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - ret) + return AVERROR(EINVAL); + ret += sizes[i]; + } + return ret; +} + +int av_image_copy_to_buffer(uint8_t *dst, int dst_size, + const uint8_t * const src_data[4], + const int src_linesize[4], + enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + int i, j, nb_planes = 0, linesize[4]; + int size = av_image_get_buffer_size(pix_fmt, width, height, align); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int ret; + + if (size > dst_size || size < 0 || !desc) + return AVERROR(EINVAL); + + for (i = 0; i < desc->nb_components; i++) + nb_planes = FFMAX(desc->comp[i].plane, nb_planes); + + nb_planes++; + + ret = av_image_fill_linesizes(linesize, pix_fmt, width); + av_assert0(ret >= 0); // was checked previously + + for (i = 0; i < nb_planes; i++) { + int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + const uint8_t *src = src_data[i]; + h = (height + (1 << shift) - 1) >> shift; + + for (j = 0; j < h; j++) { + memcpy(dst, src, linesize[i]); + dst += FFALIGN(linesize[i], align); + src += src_linesize[i]; + } + } + + if (desc->flags & AV_PIX_FMT_FLAG_PAL) { + uint32_t *d32 = (uint32_t *)dst; + + for (i = 0; i<256; i++) + AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i)); + } + + return size; +} + +// Fill dst[0..dst_size] with the bytes in clear[0..clear_size]. The clear +// bytes are repeated until dst_size is reached. If dst_size is unaligned (i.e. +// dst_size%clear_size!=0), the remaining data will be filled with the beginning +// of the clear data only. +static void memset_bytes(uint8_t *dst, size_t dst_size, uint8_t *clear, + size_t clear_size) +{ + int same = 1; + int i; + + if (!clear_size) + return; + + // Reduce to memset() if possible. + for (i = 0; i < clear_size; i++) { + if (clear[i] != clear[0]) { + same = 0; + break; + } + } + if (same) + clear_size = 1; + + if (clear_size == 1) { + memset(dst, clear[0], dst_size); + } else { + if (clear_size > dst_size) + clear_size = dst_size; + memcpy(dst, clear, clear_size); + av_memcpy_backptr(dst + clear_size, clear_size, dst_size - clear_size); + } +} + +// Maximum size in bytes of a plane element (usually a pixel, or multiple pixels +// if it's a subsampled packed format). +#define MAX_BLOCK_SIZE 32 + +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int nb_planes = av_pix_fmt_count_planes(pix_fmt); + // A pixel or a group of pixels on each plane, with a value that represents black. + // Consider e.g. AV_PIX_FMT_UYVY422 for non-trivial cases. + uint8_t clear_block[4][MAX_BLOCK_SIZE] = {{0}}; // clear padding with 0 + int clear_block_size[4] = {0}; + ptrdiff_t plane_line_bytes[4] = {0}; + int rgb, limited; + int plane, c; + + if (!desc || nb_planes < 1 || nb_planes > 4 || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + rgb = !!(desc->flags & AV_PIX_FMT_FLAG_RGB); + limited = !rgb && range != AVCOL_RANGE_JPEG; + + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) { + ptrdiff_t bytewidth = av_image_get_linesize(pix_fmt, width, 0); + uint8_t *data; + int mono = pix_fmt == AV_PIX_FMT_MONOWHITE || pix_fmt == AV_PIX_FMT_MONOBLACK; + int fill = pix_fmt == AV_PIX_FMT_MONOWHITE ? 0xFF : 0; + if (nb_planes != 1 || !(rgb || mono) || bytewidth < 1) + return AVERROR(EINVAL); + + if (!dst_data) + return 0; + + data = dst_data[0]; + + // (Bitstream + alpha will be handled incorrectly - it'll remain transparent.) + for (;height > 0; height--) { + memset(data, fill, bytewidth); + data += dst_linesize[0]; + } + return 0; + } + + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + + // We try to operate on entire non-subsampled pixel groups (for + // AV_PIX_FMT_UYVY422 this would mean two consecutive pixels). + clear_block_size[comp.plane] = FFMAX(clear_block_size[comp.plane], comp.step); + + if (clear_block_size[comp.plane] > MAX_BLOCK_SIZE) + return AVERROR(EINVAL); + } + + // Create a byte array for clearing 1 pixel (sometimes several pixels). + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + // (Multiple pixels happen e.g. with AV_PIX_FMT_UYVY422.) + int w = clear_block_size[comp.plane] / comp.step; + uint8_t *c_data[4]; + const int c_linesize[4] = {0}; + uint16_t src_array[MAX_BLOCK_SIZE]; + uint16_t src = 0; + int x; + + if (comp.depth > 16) + return AVERROR(EINVAL); + if (!rgb && comp.depth < 8) + return AVERROR(EINVAL); + if (w < 1) + return AVERROR(EINVAL); + + if (c == 0 && limited) { + src = 16 << (comp.depth - 8); + } else if ((c == 1 || c == 2) && !rgb) { + src = 128 << (comp.depth - 8); + } else if (c == 3) { + // (Assume even limited YUV uses full range alpha.) + src = (1 << comp.depth) - 1; + } + + for (x = 0; x < w; x++) + src_array[x] = src; + + for (x = 0; x < 4; x++) + c_data[x] = &clear_block[x][0]; + + av_write_image_line(src_array, c_data, c_linesize, desc, 0, 0, c, w); + } + + for (plane = 0; plane < nb_planes; plane++) { + plane_line_bytes[plane] = av_image_get_linesize(pix_fmt, width, plane); + if (plane_line_bytes[plane] < 0) + return AVERROR(EINVAL); + } + + if (!dst_data) + return 0; + + for (plane = 0; plane < nb_planes; plane++) { + size_t bytewidth = plane_line_bytes[plane]; + uint8_t *data = dst_data[plane]; + int chroma_div = plane == 1 || plane == 2 ? desc->log2_chroma_h : 0; + int plane_h = ((height + ( 1 << chroma_div) - 1)) >> chroma_div; + + for (; plane_h > 0; plane_h--) { + memset_bytes(data, bytewidth, &clear_block[plane][0], clear_block_size[plane]); + data += dst_linesize[plane]; + } + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/imgutils.h b/arm/raspi/third_party/ffmpeg/libavutil/imgutils.h new file mode 100644 index 00000000..e10ac149 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/imgutils.h @@ -0,0 +1,331 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_H +#define AVUTIL_IMGUTILS_H + +/** + * @file + * misc image utilities + * + * @addtogroup lavu_picture + * @{ + */ + +#include +#include +#include "pixdesc.h" +#include "pixfmt.h" +#include "rational.h" + +/** + * Compute the max pixel step for each plane of an image with a + * format described by pixdesc. + * + * The pixel step is the distance in bytes between the first byte of + * the group of bytes which describe a pixel component and the first + * byte of the successive group in the same plane for the same + * component. + * + * @param max_pixsteps an array which is filled with the max pixel step + * for each plane. Since a plane may contain different pixel + * components, the computed max_pixsteps[plane] is relative to the + * component in the plane with the max pixel step. + * @param max_pixstep_comps an array which is filled with the component + * for each plane which has the max pixel step. May be NULL. + * @param pixdesc the AVPixFmtDescriptor for the image, describing its format + */ +void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc); + +/** + * Compute the size of an image line with format pix_fmt and width + * width for the plane plane. + * + * @return the computed size in bytes + */ +int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane); + +/** + * Fill plane linesizes for an image with pixel format pix_fmt and + * width width. + * + * @param linesizes array to be filled with the linesize for each plane + * @param pix_fmt the AVPixelFormat of the image + * @param width width of the image in pixels + * @return >= 0 in case of success, a negative error code otherwise + */ +int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width); + +/** + * Fill plane sizes for an image with pixel format pix_fmt and height height. + * + * @param size the array to be filled with the size of each image plane + * @param pix_fmt the AVPixelFormat of the image + * @param height height of the image in pixels + * @param linesizes the array containing the linesize for each + * plane, should be filled by av_image_fill_linesizes() + * @return >= 0 in case of success, a negative error code otherwise + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_fill_linesizes(). + */ +int av_image_fill_plane_sizes(size_t size[4], enum AVPixelFormat pix_fmt, + int height, const ptrdiff_t linesizes[4]); + +/** + * Fill plane data pointers for an image with pixel format pix_fmt and + * height height. + * + * @param data pointers array to be filled with the pointer for each image plane + * @param pix_fmt the AVPixelFormat of the image + * @param height height of the image in pixels + * @param ptr the pointer to a buffer which will contain the image + * @param linesizes the array containing the linesize for each + * plane, should be filled by av_image_fill_linesizes() + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]); + +/** + * Allocate an image with size w and h and pixel format pix_fmt, and + * fill pointers and linesizes accordingly. + * The allocated image buffer has to be freed by using + * av_freep(&pointers[0]). + * + * @param pointers array to be filled with the pointer for each image plane + * @param linesizes the array filled with the linesize for each plane + * @param w width of the image in pixels + * @param h height of the image in pixels + * @param pix_fmt the AVPixelFormat of the image + * @param align the value to use for buffer size alignment + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_alloc(uint8_t *pointers[4], int linesizes[4], + int w, int h, enum AVPixelFormat pix_fmt, int align); + +/** + * Copy image plane from src to dst. + * That is, copy "height" number of lines of "bytewidth" bytes each. + * The first byte of each successive line is separated by *_linesize + * bytes. + * + * bytewidth must be contained by both absolute values of dst_linesize + * and src_linesize, otherwise the function behavior is undefined. + * + * @param dst destination plane to copy to + * @param dst_linesize linesize for the image plane in dst + * @param src source plane to copy from + * @param src_linesize linesize for the image plane in src + * @param height height (number of lines) of the plane + */ +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height); + +/** + * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where + * available, this function will use special functionality for reading from such + * memory, which may result in greatly improved performance compared to plain + * av_image_copy_plane(). + * + * bytewidth must be contained by both absolute values of dst_linesize + * and src_linesize, otherwise the function behavior is undefined. + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_copy_plane(). + * @note On x86, the linesizes currently need to be aligned to the cacheline + * size (i.e. 64) to get improved performance. + */ +void av_image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + +/** + * Copy image in src_data to dst_data. + * + * @param dst_data destination image data buffer to copy to + * @param dst_linesizes linesizes for the image in dst_data + * @param src_data source image data buffer to copy from + * @param src_linesizes linesizes for the image in src_data + * @param pix_fmt the AVPixelFormat of the image + * @param width width of the image in pixels + * @param height height of the image in pixels + */ +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where + * available, this function will use special functionality for reading from such + * memory, which may result in greatly improved performance compared to plain + * av_image_copy(). + * + * The data pointers and the linesizes must be aligned to the maximum required + * by the CPU architecture. + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_copy(). + * @note On x86, the linesizes currently need to be aligned to the cacheline + * size (i.e. 64) to get improved performance. + */ +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Setup the data pointers and linesizes based on the specified image + * parameters and the provided array. + * + * The fields of the given image are filled in by using the src + * address which points to the image data buffer. Depending on the + * specified pixel format, one or multiple image data pointers and + * line sizes will be set. If a planar format is specified, several + * pointers will be set pointing to the different picture planes and + * the line sizes of the different planes will be stored in the + * lines_sizes array. Call with src == NULL to get the required + * size for the src buffer. + * + * To allocate the buffer and fill in the dst_data and dst_linesize in + * one call, use av_image_alloc(). + * + * @param dst_data data pointers to be filled in + * @param dst_linesize linesizes for the image in dst_data to be filled in + * @param src buffer which will contain or contains the actual image data, can be NULL + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the value used in src for linesize alignment + * @return the size in bytes required for src, a negative error code + * in case of failure + */ +int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], + const uint8_t *src, + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Return the size in bytes of the amount of data required to store an + * image with the given parameters. + * + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the assumed linesize alignment + * @return the buffer size in bytes, a negative error code in case of failure + */ +int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Copy image data from an image into a buffer. + * + * av_image_get_buffer_size() can be used to compute the required size + * for the buffer to fill. + * + * @param dst a buffer into which picture data will be copied + * @param dst_size the size in bytes of dst + * @param src_data pointers containing the source image data + * @param src_linesize linesizes for the image in src_data + * @param pix_fmt the pixel format of the source image + * @param width the width of the source image in pixels + * @param height the height of the source image in pixels + * @param align the assumed linesize alignment for dst + * @return the number of bytes written to dst, or a negative value + * (error code) on error + */ +int av_image_copy_to_buffer(uint8_t *dst, int dst_size, + const uint8_t * const src_data[4], const int src_linesize[4], + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of the image can be addressed with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of a plane of an image with the specified pix_fmt can be addressed + * with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param max_pixels the maximum number of pixels the user wants to accept + * @param pix_fmt the pixel format, can be AV_PIX_FMT_NONE if unknown. + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx); + +/** + * Check if the given sample aspect ratio of an image is valid. + * + * It is considered invalid if the denominator is 0 or if applying the ratio + * to the image size would make the smaller dimension less than 1. If the + * sar numerator is 0, it is considered unknown and will return as valid. + * + * @param w width of the image + * @param h height of the image + * @param sar sample aspect ratio of the image + * @return 0 if valid, a negative AVERROR code otherwise + */ +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar); + +/** + * Overwrite the image data with black. This is suitable for filling a + * sub-rectangle of an image, meaning the padding between the right most pixel + * and the left most pixel on the next line will not be overwritten. For some + * formats, the image size might be rounded up due to inherent alignment. + * + * If the pixel format has alpha, the alpha is cleared to opaque. + * + * This can return an error if the pixel format is not supported. Normally, all + * non-hwaccel pixel formats should be supported. + * + * Passing NULL for dst_data is allowed. Then the function returns whether the + * operation would have succeeded. (It can return an error if the pix_fmt is + * not supported.) + * + * @param dst_data data pointers to destination image + * @param dst_linesize linesizes for the destination image + * @param pix_fmt the pixel format of the image + * @param range the color range of the image (important for colorspaces such as YUV) + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return 0 if the image data was cleared, a negative AVERROR code otherwise + */ +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height); + +/** + * @} + */ + + +#endif /* AVUTIL_IMGUTILS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/imgutils_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/imgutils_internal.h new file mode 100644 index 00000000..d5158584 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/imgutils_internal.h @@ -0,0 +1,30 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_INTERNAL_H +#define AVUTIL_IMGUTILS_INTERNAL_H + +#include +#include + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + + +#endif /* AVUTIL_IMGUTILS_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/integer.c b/arm/raspi/third_party/ffmpeg/libavutil/integer.c new file mode 100644 index 00000000..ae87c467 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/integer.c @@ -0,0 +1,166 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * arbitrary precision integers + * @author Michael Niedermayer + */ + +#include + +#include "integer.h" +#include "avassert.h" +#include "intmath.h" + +static const AVInteger zero_i; + +AVInteger av_add_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i>16) + a.v[i] + b.v[i]; + a.v[i]= carry; + } + return a; +} + +AVInteger av_sub_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i>16) + a.v[i] - b.v[i]; + a.v[i]= carry; + } + return a; +} + +int av_log2_i(AVInteger a){ + int i; + + for(i=AV_INTEGER_SIZE-1; i>=0; i--){ + if(a.v[i]) + return av_log2_16bit(a.v[i]) + 16*i; + } + return -1; +} + +AVInteger av_mul_i(AVInteger a, AVInteger b){ + AVInteger out; + int i, j; + int na= (av_log2_i(a)+16) >> 4; + int nb= (av_log2_i(b)+16) >> 4; + + memset(&out, 0, sizeof(out)); + + for(i=0; i>16) + out.v[j] + a.v[i]*(unsigned)b.v[j-i]; + out.v[j]= carry; + } + } + + return out; +} + +int av_cmp_i(AVInteger a, AVInteger b){ + int i; + int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1]; + if(v) return (v>>16)|1; + + for(i=AV_INTEGER_SIZE-2; i>=0; i--){ + int v= a.v[i] - b.v[i]; + if(v) return (v>>16)|1; + } + return 0; +} + +AVInteger av_shr_i(AVInteger a, int s){ + AVInteger out; + int i; + + for(i=0; i>4); + unsigned int v=0; + if (index + 1 < AV_INTEGER_SIZE) v = a.v[index + 1] * (1U << 16); + if (index < AV_INTEGER_SIZE) v |= a.v[index]; + out.v[i]= v >> (s&15); + } + return out; +} + +AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){ + int i= av_log2_i(a) - av_log2_i(b); + AVInteger quot_temp; + if(!quot) quot = "_temp; + + if ((int16_t)a.v[AV_INTEGER_SIZE-1] < 0) { + a = av_mod_i(quot, av_sub_i(zero_i, a), b); + *quot = av_sub_i(zero_i, *quot); + return av_sub_i(zero_i, a); + } + + av_assert2((int16_t)a.v[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b.v[AV_INTEGER_SIZE-1] >= 0); + av_assert2(av_log2_i(b)>=0); + + if(i > 0) + b= av_shr_i(b, -i); + + memset(quot, 0, sizeof(AVInteger)); + + while(i-- >= 0){ + *quot= av_shr_i(*quot, -1); + if(av_cmp_i(a, b) >= 0){ + a= av_sub_i(a, b); + quot->v[0] += 1; + } + b= av_shr_i(b, 1); + } + return a; +} + +AVInteger av_div_i(AVInteger a, AVInteger b){ + AVInteger quot; + av_mod_i(", a, b); + return quot; +} + +AVInteger av_int2i(int64_t a){ + AVInteger out; + int i; + + for(i=0; i>=16; + } + return out; +} + +int64_t av_i2int(AVInteger a){ + uint64_t out = a.v[3]; + + for (int i = 2; i >= 0; i--) + out = (out << 16) | a.v[i]; + return out; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/integer.h b/arm/raspi/third_party/ffmpeg/libavutil/integer.h new file mode 100644 index 00000000..2d9b5bb1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/integer.h @@ -0,0 +1,86 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * arbitrary precision integers + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_INTEGER_H +#define AVUTIL_INTEGER_H + +#include +#include "attributes.h" + +#define AV_INTEGER_SIZE 8 + +typedef struct AVInteger{ + uint16_t v[AV_INTEGER_SIZE]; +} AVInteger; + +AVInteger av_add_i(AVInteger a, AVInteger b) av_const; +AVInteger av_sub_i(AVInteger a, AVInteger b) av_const; + +/** + * Return the rounded-down value of the base 2 logarithm of the given + * AVInteger. This is simply the index of the most significant bit + * which is 1, or 0 if all bits are 0. + */ +int av_log2_i(AVInteger a) av_const; +AVInteger av_mul_i(AVInteger a, AVInteger b) av_const; + +/** + * Return 0 if a==b, 1 if a>b and -1 if a + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal API header + */ + +#ifndef AVUTIL_INTERNAL_H +#define AVUTIL_INTERNAL_H + +#if !defined(DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif + +// This can be enabled to allow detection of additional integer overflows with ubsan +//#define CHECKED + +#include +#include +#include +#include +#include +#include "config.h" +#include "attributes.h" +#include "timer.h" +#include "macros.h" +#include "pixfmt.h" + +#if ARCH_X86 +# include "x86/emms.h" +#endif + +#ifndef emms_c +# define emms_c() do {} while(0) +#endif + +#ifndef attribute_align_arg +#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) +# define attribute_align_arg __attribute__((force_align_arg_pointer)) +#else +# define attribute_align_arg +#endif +#endif + +#if defined(_WIN32) && CONFIG_SHARED && !defined(BUILDING_avutil) +# define av_export_avutil __declspec(dllimport) +#else +# define av_export_avutil +#endif + +#if HAVE_PRAGMA_DEPRECATED +# if defined(__ICL) || defined (__INTEL_COMPILER) +# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478)) +# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) +# elif defined(_MSC_VER) +# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996)) +# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) +# else +# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic pop") +# endif +#else +# define FF_DISABLE_DEPRECATION_WARNINGS +# define FF_ENABLE_DEPRECATION_WARNINGS +#endif + + +#define FF_MEMORY_POISON 0x2a + +/* Check if the hard coded offset of a struct member still matches reality. + * Induce a compilation failure if not. + */ +#define AV_CHECK_OFFSET(s, m, o) struct check_##o { \ + int x_##o[offsetof(s, m) == o? 1: -1]; \ + } + + +#define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p))) +#define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_calloc(nelem, sizeof(*p))) + +#define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr)) + +/** + * Access a field in a structure by its offset. + */ +#define FF_FIELD_AT(type, off, obj) (*(type *)((char *)&(obj) + (off))) + +#include "libm.h" + +/** + * Return NULL if CONFIG_SMALL is true, otherwise the argument + * without modification. Used to disable the definition of strings. + */ +#if CONFIG_SMALL +# define NULL_IF_CONFIG_SMALL(x) NULL +#else +# define NULL_IF_CONFIG_SMALL(x) x +#endif + +/** + * Log a generic warning message about a missing feature. + * + * @param[in] avc a pointer to an arbitrary struct of which the first + * field is a pointer to an AVClass struct + * @param[in] msg string containing the name of the missing feature + */ +#if defined(CHROMIUM_NO_LOGGING) +#define avpriv_report_missing_feature(...) +#else +void avpriv_report_missing_feature(void *avc, + const char *msg, ...) av_printf_format(2, 3); +#endif + +/** + * Log a generic warning message about a missing feature. + * Additionally request that a sample showcasing the feature be uploaded. + * + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] msg string containing the name of the missing feature + */ +#if defined(CHROMIUM_NO_LOGGING) +#define avpriv_request_sample(...) +#else +void avpriv_request_sample(void *avc, + const char *msg, ...) av_printf_format(2, 3); +#endif + +#if HAVE_LIBC_MSVCRT +#include +#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14 +#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod") +#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf") +#endif + +#define PTRDIFF_SPECIFIER "Id" +#define SIZE_SPECIFIER "Iu" +#else +#define PTRDIFF_SPECIFIER "td" +#define SIZE_SPECIFIER "zu" +#endif + +#ifdef DEBUG +# define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__) +#elif defined(CHROMIUM_NO_LOGGING) +# define ff_dlog(ctx, ...) do { } while(0) // Prevent a [-Wempty-body] error. +#else +# define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) +#endif + +#ifdef TRACE +# define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) +#else +# define ff_tlog(ctx, ...) do { } while(0) +#endif + +// For debuging we use signed operations so overflows can be detected (by ubsan) +// For production we use unsigned so there are no undefined operations +#ifdef CHECKED +#define SUINT int +#define SUINT32 int32_t +#else +#define SUINT unsigned +#define SUINT32 uint32_t +#endif + +int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt); + +static av_always_inline av_const int avpriv_mirror(int x, int w) +{ + if (!w) + return 0; + + while ((unsigned)x > (unsigned)w) { + x = -x; + if (x < 0) + x += 2 * w; + } + return x; +} + +#endif /* AVUTIL_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/intfloat.h b/arm/raspi/third_party/ffmpeg/libavutil/intfloat.h new file mode 100644 index 00000000..fe3d7ec4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/intfloat.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_H +#define AVUTIL_INTFLOAT_H + +#include +#include "attributes.h" + +union av_intfloat32 { + uint32_t i; + float f; +}; + +union av_intfloat64 { + uint64_t i; + double f; +}; + +/** + * Reinterpret a 32-bit integer as a float. + */ +static av_always_inline float av_int2float(uint32_t i) +{ + union av_intfloat32 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a float as a 32-bit integer. + */ +static av_always_inline uint32_t av_float2int(float f) +{ + union av_intfloat32 v; + v.f = f; + return v.i; +} + +/** + * Reinterpret a 64-bit integer as a double. + */ +static av_always_inline double av_int2double(uint64_t i) +{ + union av_intfloat64 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a double as a 64-bit integer. + */ +static av_always_inline uint64_t av_double2int(double f) +{ + union av_intfloat64 v; + v.f = f; + return v.i; +} + +#endif /* AVUTIL_INTFLOAT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/intmath.c b/arm/raspi/third_party/ffmpeg/libavutil/intmath.c new file mode 100644 index 00000000..b0c00e1c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/intmath.c @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "intmath.h" + +/* undef these to get the function prototypes from common.h */ +#undef av_log2 +#undef av_log2_16bit +#include "common.h" + +int av_log2(unsigned v) +{ + return ff_log2(v); +} + +int av_log2_16bit(unsigned v) +{ + return ff_log2_16bit(v); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/intmath.h b/arm/raspi/third_party/ffmpeg/libavutil/intmath.h new file mode 100644 index 00000000..c54d23b7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/intmath.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTMATH_H +#define AVUTIL_INTMATH_H + +#include + +#include "config.h" +#include "attributes.h" + +#if ARCH_ARM +# include "arm/intmath.h" +#elif ARCH_RISCV +# include "riscv/intmath.h" +#elif ARCH_X86 +# include "x86/intmath.h" +#endif + +#if HAVE_FAST_CLZ +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef ff_log2 +# define ff_log2(x) (31 - __builtin_clz((x)|1)) +# ifndef ff_log2_16bit +# define ff_log2_16bit av_log2 +# endif +#endif /* ff_log2 */ +#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */ +#endif + +extern const uint8_t ff_log2_tab[256]; + +#ifndef ff_log2 +#define ff_log2 ff_log2_c +static av_always_inline av_const int ff_log2_c(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} +#endif + +#ifndef ff_log2_16bit +#define ff_log2_16bit ff_log2_16bit_c +static av_always_inline av_const int ff_log2_16bit_c(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} +#endif + +#define av_log2 ff_log2 +#define av_log2_16bit ff_log2_16bit + +/** + * @addtogroup lavu_math + * @{ + */ + +#if HAVE_FAST_CLZ +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef ff_ctz +#define ff_ctz(v) __builtin_ctz(v) +#endif +#ifndef ff_ctzll +#define ff_ctzll(v) __builtin_ctzll(v) +#endif +#ifndef ff_clz +#define ff_clz(v) __builtin_clz(v) +#endif +#endif +#endif + +#ifndef ff_ctz +#define ff_ctz ff_ctz_c +/** + * Trailing zero bit count. + * + * @param v input value. If v is 0, the result is undefined. + * @return the number of trailing 0-bits + */ +/* We use the De-Bruijn method outlined in: + * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ +static av_always_inline av_const int ff_ctz_c(int v) +{ + static const uint8_t debruijn_ctz32[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + return debruijn_ctz32[(uint32_t)((v & -v) * 0x077CB531U) >> 27]; +} +#endif + +#ifndef ff_ctzll +#define ff_ctzll ff_ctzll_c +/* We use the De-Bruijn method outlined in: + * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ +static av_always_inline av_const int ff_ctzll_c(long long v) +{ + static const uint8_t debruijn_ctz64[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + return debruijn_ctz64[(uint64_t)((v & -v) * 0x022FDD63CC95386DU) >> 58]; +} +#endif + +#ifndef ff_clz +#define ff_clz ff_clz_c +static av_always_inline av_const unsigned ff_clz_c(unsigned x) +{ + unsigned i = sizeof(x) * 8; + + while (x) { + x >>= 1; + i--; + } + + return i; +} +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef av_parity +#define av_parity __builtin_parity +#endif +#endif + +/** + * @} + */ +#endif /* AVUTIL_INTMATH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/intreadwrite.h new file mode 100644 index 00000000..4c8413a5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/intreadwrite.h @@ -0,0 +1,644 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTREADWRITE_H +#define AVUTIL_INTREADWRITE_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" +#include "bswap.h" + +typedef union { + uint64_t u64; + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8 [8]; + double f64; + float f32[2]; +} av_alias av_alias64; + +typedef union { + uint32_t u32; + uint16_t u16[2]; + uint8_t u8 [4]; + float f32; +} av_alias av_alias32; + +typedef union { + uint16_t u16; + uint8_t u8 [2]; +} av_alias av_alias16; + +/* + * Arch-specific headers can provide any combination of + * AV_[RW][BLN](16|24|32|48|64) and AV_(COPY|SWAP|ZERO)(64|128) macros. + * Preprocessor symbols must be defined, even if these are implemented + * as inline functions. + * + * R/W means read/write, B/L/N means big/little/native endianness. + * The following macros require aligned access, compared to their + * unaligned variants: AV_(COPY|SWAP|ZERO)(64|128), AV_[RW]N[8-64]A. + * Incorrect usage may range from abysmal performance to crash + * depending on the platform. + * + * The unaligned variants are AV_[RW][BLN][8-64] and AV_COPY*U. + */ + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_ARM +# include "arm/intreadwrite.h" +#elif ARCH_AVR32 +# include "avr32/intreadwrite.h" +#elif ARCH_MIPS +# include "mips/intreadwrite.h" +#elif ARCH_PPC +# include "ppc/intreadwrite.h" +#elif ARCH_TOMI +# include "tomi/intreadwrite.h" +#elif ARCH_X86 +# include "x86/intreadwrite.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +/* + * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. + */ + +#if AV_HAVE_BIGENDIAN + +# if defined(AV_RN16) && !defined(AV_RB16) +# define AV_RB16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RB16) +# define AV_RN16(p) AV_RB16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WB16) +# define AV_WB16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WB16) +# define AV_WN16(p, v) AV_WB16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RB24) +# define AV_RB24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RB24) +# define AV_RN24(p) AV_RB24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WB24) +# define AV_WB24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WB24) +# define AV_WN24(p, v) AV_WB24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RB32) +# define AV_RB32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RB32) +# define AV_RN32(p) AV_RB32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WB32) +# define AV_WB32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WB32) +# define AV_WN32(p, v) AV_WB32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RB48) +# define AV_RB48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RB48) +# define AV_RN48(p) AV_RB48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WB48) +# define AV_WB48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WB48) +# define AV_WN48(p, v) AV_WB48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RB64) +# define AV_RB64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RB64) +# define AV_RN64(p) AV_RB64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WB64) +# define AV_WB64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WB64) +# define AV_WN64(p, v) AV_WB64(p, v) +# endif + +#else /* AV_HAVE_BIGENDIAN */ + +# if defined(AV_RN16) && !defined(AV_RL16) +# define AV_RL16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RL16) +# define AV_RN16(p) AV_RL16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WL16) +# define AV_WL16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WL16) +# define AV_WN16(p, v) AV_WL16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RL24) +# define AV_RL24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RL24) +# define AV_RN24(p) AV_RL24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WL24) +# define AV_WL24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WL24) +# define AV_WN24(p, v) AV_WL24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RL32) +# define AV_RL32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RL32) +# define AV_RN32(p) AV_RL32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WL32) +# define AV_WL32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WL32) +# define AV_WN32(p, v) AV_WL32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RL48) +# define AV_RL48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RL48) +# define AV_RN48(p) AV_RL48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WL48) +# define AV_WL48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WL48) +# define AV_WN48(p, v) AV_WL48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RL64) +# define AV_RL64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RL64) +# define AV_RN64(p) AV_RL64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WL64) +# define AV_WL64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WL64) +# define AV_WN64(p, v) AV_WL64(p, v) +# endif + +#endif /* !AV_HAVE_BIGENDIAN */ + +/* + * Define AV_[RW]N helper macros to simplify definitions not provided + * by per-arch headers. + */ + +#if defined(__GNUC__) + +union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; +union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; +union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; + +# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) +# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) + +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64) || defined(_M_ARM64)) && AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) +# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) + +#elif AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) +# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#else + +#ifndef AV_RB16 +# define AV_RB16(x) \ + ((((const uint8_t*)(x))[0] << 8) | \ + ((const uint8_t*)(x))[1]) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[1] = (d); \ + ((uint8_t*)(p))[0] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RL16 +# define AV_RL16(x) \ + ((((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RB32 +# define AV_RB32(x) \ + (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[3] = (d); \ + ((uint8_t*)(p))[2] = (d)>>8; \ + ((uint8_t*)(p))[1] = (d)>>16; \ + ((uint8_t*)(p))[0] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RL32 +# define AV_RL32(x) \ + (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RB64 +# define AV_RB64(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ + (uint64_t)((const uint8_t*)(x))[7]) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[7] = (d); \ + ((uint8_t*)(p))[6] = (d)>>8; \ + ((uint8_t*)(p))[5] = (d)>>16; \ + ((uint8_t*)(p))[4] = (d)>>24; \ + ((uint8_t*)(p))[3] = (d)>>32; \ + ((uint8_t*)(p))[2] = (d)>>40; \ + ((uint8_t*)(p))[1] = (d)>>48; \ + ((uint8_t*)(p))[0] = (d)>>56; \ + } while(0) +#endif + +#ifndef AV_RL64 +# define AV_RL64(x) \ + (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + ((uint8_t*)(p))[6] = (d)>>48; \ + ((uint8_t*)(p))[7] = (d)>>56; \ + } while(0) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RN(s, p) AV_RB##s(p) +# define AV_WN(s, p, v) AV_WB##s(p, v) +#else +# define AV_RN(s, p) AV_RL##s(p) +# define AV_WN(s, p, v) AV_WL##s(p, v) +#endif + +#endif /* HAVE_FAST_UNALIGNED */ + +#ifndef AV_RN16 +# define AV_RN16(p) AV_RN(16, p) +#endif + +#ifndef AV_RN32 +# define AV_RN32(p) AV_RN(32, p) +#endif + +#ifndef AV_RN64 +# define AV_RN64(p) AV_RN(64, p) +#endif + +#ifndef AV_WN16 +# define AV_WN16(p, v) AV_WN(16, p, v) +#endif + +#ifndef AV_WN32 +# define AV_WN32(p, v) AV_WN(32, p, v) +#endif + +#ifndef AV_WN64 +# define AV_WN64(p, v) AV_WN(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RB(s, p) AV_RN##s(p) +# define AV_WB(s, p, v) AV_WN##s(p, v) +# define AV_RL(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v)) +#else +# define AV_RB(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v)) +# define AV_RL(s, p) AV_RN##s(p) +# define AV_WL(s, p, v) AV_WN##s(p, v) +#endif + +#define AV_RB8(x) (((const uint8_t*)(x))[0]) +#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, d) AV_WB8(p, d) + +#ifndef AV_RB16 +# define AV_RB16(p) AV_RB(16, p) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, v) AV_WB(16, p, v) +#endif + +#ifndef AV_RL16 +# define AV_RL16(p) AV_RL(16, p) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, v) AV_WL(16, p, v) +#endif + +#ifndef AV_RB32 +# define AV_RB32(p) AV_RB(32, p) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, v) AV_WB(32, p, v) +#endif + +#ifndef AV_RL32 +# define AV_RL32(p) AV_RL(32, p) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, v) AV_WL(32, p, v) +#endif + +#ifndef AV_RB64 +# define AV_RB64(p) AV_RB(64, p) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, v) AV_WB(64, p, v) +#endif + +#ifndef AV_RL64 +# define AV_RL64(p) AV_RL(64, p) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, v) AV_WL(64, p, v) +#endif + +#ifndef AV_RB24 +# define AV_RB24(x) \ + ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#endif +#ifndef AV_WB24 +# define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RL24 +# define AV_RL24(x) \ + ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL24 +# define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RB48 +# define AV_RB48(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 8) | \ + (uint64_t)((const uint8_t*)(x))[5]) +#endif +#ifndef AV_WB48 +# define AV_WB48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[5] = (d); \ + ((uint8_t*)(p))[4] = (d)>>8; \ + ((uint8_t*)(p))[3] = (d)>>16; \ + ((uint8_t*)(p))[2] = (d)>>24; \ + ((uint8_t*)(p))[1] = (d)>>32; \ + ((uint8_t*)(p))[0] = (d)>>40; \ + } while(0) +#endif + +#ifndef AV_RL48 +# define AV_RL48(x) \ + (((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL48 +# define AV_WL48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + } while(0) +#endif + +/* + * The AV_[RW]NA macros access naturally aligned data + * in a type-safe way. + */ + +#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) +#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#ifndef AV_RN16A +# define AV_RN16A(p) AV_RNA(16, p) +#endif + +#ifndef AV_RN32A +# define AV_RN32A(p) AV_RNA(32, p) +#endif + +#ifndef AV_RN64A +# define AV_RN64A(p) AV_RNA(64, p) +#endif + +#ifndef AV_WN16A +# define AV_WN16A(p, v) AV_WNA(16, p, v) +#endif + +#ifndef AV_WN32A +# define AV_WN32A(p, v) AV_WNA(32, p, v) +#endif + +#ifndef AV_WN64A +# define AV_WN64A(p, v) AV_WNA(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RLA(s, p) av_bswap##s(AV_RN##s##A(p)) +# define AV_WLA(s, p, v) AV_WN##s##A(p, av_bswap##s(v)) +#else +# define AV_RLA(s, p) AV_RN##s##A(p) +# define AV_WLA(s, p, v) AV_WN##s##A(p, v) +#endif + +#ifndef AV_RL64A +# define AV_RL64A(p) AV_RLA(64, p) +#endif +#ifndef AV_WL64A +# define AV_WL64A(p, v) AV_WLA(64, p, v) +#endif + +/* + * The AV_COPYxxU macros are suitable for copying data to/from unaligned + * memory locations. + */ + +#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); + +#ifndef AV_COPY16U +# define AV_COPY16U(d, s) AV_COPYU(16, d, s) +#endif + +#ifndef AV_COPY32U +# define AV_COPY32U(d, s) AV_COPYU(32, d, s) +#endif + +#ifndef AV_COPY64U +# define AV_COPY64U(d, s) AV_COPYU(64, d, s) +#endif + +#ifndef AV_COPY128U +# define AV_COPY128U(d, s) \ + do { \ + AV_COPY64U(d, s); \ + AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8); \ + } while(0) +#endif + +/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be + * naturally aligned. They may be implemented using MMX, + * so emms_c() must be called before using any float code + * afterwards. + */ + +#define AV_COPY(n, d, s) \ + (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) + +#ifndef AV_COPY16 +# define AV_COPY16(d, s) AV_COPY(16, d, s) +#endif + +#ifndef AV_COPY32 +# define AV_COPY32(d, s) AV_COPY(32, d, s) +#endif + +#ifndef AV_COPY64 +# define AV_COPY64(d, s) AV_COPY(64, d, s) +#endif + +#ifndef AV_COPY128 +# define AV_COPY128(d, s) \ + do { \ + AV_COPY64(d, s); \ + AV_COPY64((char*)(d)+8, (char*)(s)+8); \ + } while(0) +#endif + +#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) + +#ifndef AV_SWAP64 +# define AV_SWAP64(a, b) AV_SWAP(64, a, b) +#endif + +#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) + +#ifndef AV_ZERO16 +# define AV_ZERO16(d) AV_ZERO(16, d) +#endif + +#ifndef AV_ZERO32 +# define AV_ZERO32(d) AV_ZERO(32, d) +#endif + +#ifndef AV_ZERO64 +# define AV_ZERO64(d) AV_ZERO(64, d) +#endif + +#ifndef AV_ZERO128 +# define AV_ZERO128(d) \ + do { \ + AV_ZERO64(d); \ + AV_ZERO64((char*)(d)+8); \ + } while(0) +#endif + +#endif /* AVUTIL_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lfg.c b/arm/raspi/third_party/ffmpeg/libavutil/lfg.c new file mode 100644 index 00000000..46b04d24 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lfg.c @@ -0,0 +1,87 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "lfg.h" +#include "crc.h" +#include "md5.h" +#include "error.h" +#include "intreadwrite.h" +#include "attributes.h" + +av_cold void av_lfg_init(AVLFG *c, unsigned int seed) +{ + uint8_t tmp[16] = { 0 }; + int i; + + for (i = 8; i < 64; i += 4) { + AV_WL32(tmp, seed); + tmp[4] = i; + av_md5_sum(tmp, tmp, 16); + c->state[i ] = AV_RL32(tmp); + c->state[i + 1] = AV_RL32(tmp + 4); + c->state[i + 2] = AV_RL32(tmp + 8); + c->state[i + 3] = AV_RL32(tmp + 12); + } + c->index = 0; +} + +void av_bmg_get(AVLFG *lfg, double out[2]) +{ + double x1, x2, w; + + do { + x1 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0; + x2 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0; + w = x1 * x1 + x2 * x2; + } while (w >= 1.0); + + w = sqrt((-2.0 * log(w)) / w); + out[0] = x1 * w; + out[1] = x2 * w; +} + +int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length) { + unsigned int beg, end, segm; + const AVCRC *avcrc; + uint32_t crc = 1; + + /* avoid integer overflow in the loop below. */ + if (length > (UINT_MAX / 128U)) return AVERROR(EINVAL); + + c->index = 0; + avcrc = av_crc_get_table(AV_CRC_32_IEEE); /* This can't fail. It's a well-defined table in crc.c */ + + /* across 64 segments of the incoming data, + * do a running crc of each segment and store the crc as the state for that slot. + * this works even if the length of the segment is 0 bytes. */ + beg = 0; + for (segm = 0;segm < 64;segm++) { + end = (((segm + 1) * length) / 64); + crc = av_crc(avcrc, crc, data + beg, end - beg); + c->state[segm] = (unsigned int)crc; + beg = end; + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lfg.h b/arm/raspi/third_party/ffmpeg/libavutil/lfg.h new file mode 100644 index 00000000..e75a986f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lfg.h @@ -0,0 +1,81 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LFG_H +#define AVUTIL_LFG_H + +#include + +/** + * Context structure for the Lagged Fibonacci PRNG. + * The exact layout, types and content of this struct may change and should + * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same + * to allow easy instanciation. + */ +typedef struct AVLFG { + unsigned int state[64]; + int index; +} AVLFG; + +void av_lfg_init(AVLFG *c, unsigned int seed); + +/** + * Seed the state of the ALFG using binary data. + * + * @return 0 on success, negative value (AVERROR) on failure. + */ +int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length); + +/** + * Get the next random unsigned 32-bit number using an ALFG. + * + * Please also consider a simple LCG like state= state*1664525+1013904223, + * it may be good enough and faster for your specific use case. + */ +static inline unsigned int av_lfg_get(AVLFG *c){ + unsigned a = c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63]; + c->index += 1U; + return a; +} + +/** + * Get the next random unsigned 32-bit number using a MLFG. + * + * Please also consider av_lfg_get() above, it is faster. + */ +static inline unsigned int av_mlfg_get(AVLFG *c){ + unsigned int a= c->state[(c->index-55) & 63]; + unsigned int b= c->state[(c->index-24) & 63]; + a = c->state[c->index & 63] = 2*a*b+a+b; + c->index += 1U; + return a; +} + +/** + * Get the next two numbers generated by a Box-Muller Gaussian + * generator using the random numbers issued by lfg. + * + * @param lfg pointer to the contex structure + * @param out array where the two generated numbers are placed + */ +void av_bmg_get(AVLFG *lfg, double out[2]); + +#endif /* AVUTIL_LFG_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/libavutil.v b/arm/raspi/third_party/ffmpeg/libavutil/libavutil.v new file mode 100644 index 00000000..fb17058d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/libavutil.v @@ -0,0 +1,6 @@ +LIBAVUTIL_MAJOR { + global: + av*; + local: + *; +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/libm.h b/arm/raspi/third_party/ffmpeg/libavutil/libm.h new file mode 100644 index 00000000..a8199623 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/libm.h @@ -0,0 +1,471 @@ +/* + * erf function: Copyright (c) 2006 John Maddock + * 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 + * Replacements for frequently missing libm functions + */ + +#ifndef AVUTIL_LIBM_H +#define AVUTIL_LIBM_H + +#include +#include "config.h" +#include "attributes.h" +#include "intfloat.h" +#include "mathematics.h" + +#if HAVE_MIPSFPU && HAVE_INLINE_ASM +#include "libavutil/mips/libm_mips.h" +#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/ + +#if !HAVE_ATANF +#undef atanf +#define atanf(x) ((float)atan(x)) +#endif /* HAVE_ATANF */ + +#if !HAVE_ATAN2F +#undef atan2f +#define atan2f(y, x) ((float)atan2(y, x)) +#endif /* HAVE_ATAN2F */ + +#if !HAVE_POWF +#undef powf +#define powf(x, y) ((float)pow(x, y)) +#endif /* HAVE_POWF */ + +#if !HAVE_CBRT +static av_always_inline double cbrt(double x) +{ + return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0); +} +#endif /* HAVE_CBRT */ + +#if !HAVE_CBRTF +static av_always_inline float cbrtf(float x) +{ + return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0); +} +#endif /* HAVE_CBRTF */ + +#if !HAVE_COPYSIGN +static av_always_inline double copysign(double x, double y) +{ + uint64_t vx = av_double2int(x); + uint64_t vy = av_double2int(y); + return av_int2double((vx & UINT64_C(0x7fffffffffffffff)) | (vy & UINT64_C(0x8000000000000000))); +} +#endif /* HAVE_COPYSIGN */ + +#if !HAVE_COSF +#undef cosf +#define cosf(x) ((float)cos(x)) +#endif /* HAVE_COSF */ + +#if !HAVE_ERF +static inline double ff_eval_poly(const double *coeff, int size, double x) { + double sum = coeff[size-1]; + int i; + for (i = size-2; i >= 0; --i) { + sum *= x; + sum += coeff[i]; + } + return sum; +} + +/** + * erf function + * Algorithm taken from the Boost project, source: + * http://www.boost.org/doc/libs/1_46_1/boost/math/special_functions/erf.hpp + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0 (see notice below). + * Boost Software License - Version 1.0 - August 17th, 2003 +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + */ +static inline double erf(double z) +{ +#ifndef FF_ARRAY_ELEMS +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#endif + double result; + + /* handle the symmetry: erf(-x) = -erf(x) */ + if (z < 0) + return -erf(-z); + + /* branch based on range of z, and pick appropriate approximation */ + if (z == 0) + return 0; + else if (z < 1e-10) + return z * 1.125 + z * 0.003379167095512573896158903121545171688; + else if (z < 0.5) { + // Maximum Deviation Found: 1.561e-17 + // Expected Error Term: 1.561e-17 + // Maximum Relative Change in Control Points: 1.155e-04 + // Max Error found at double precision = 2.961182e-17 + + static const double y = 1.044948577880859375; + static const double p[] = { + 0.0834305892146531832907, + -0.338165134459360935041, + -0.0509990735146777432841, + -0.00772758345802133288487, + -0.000322780120964605683831, + }; + static const double q[] = { + 1, + 0.455004033050794024546, + 0.0875222600142252549554, + 0.00858571925074406212772, + 0.000370900071787748000569, + }; + double zz = z * z; + return z * (y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), zz) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), zz)); + } + /* here onwards compute erfc */ + else if (z < 1.5) { + // Maximum Deviation Found: 3.702e-17 + // Expected Error Term: 3.702e-17 + // Maximum Relative Change in Control Points: 2.845e-04 + // Max Error found at double precision = 4.841816e-17 + static const double y = 0.405935764312744140625; + static const double p[] = { + -0.098090592216281240205, + 0.178114665841120341155, + 0.191003695796775433986, + 0.0888900368967884466578, + 0.0195049001251218801359, + 0.00180424538297014223957, + }; + static const double q[] = { + 1, + 1.84759070983002217845, + 1.42628004845511324508, + 0.578052804889902404909, + 0.12385097467900864233, + 0.0113385233577001411017, + 0.337511472483094676155e-5, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 0.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 0.5); + result *= exp(-z * z) / z; + return 1 - result; + } + else if (z < 2.5) { + // Max Error found at double precision = 6.599585e-18 + // Maximum Deviation Found: 3.909e-18 + // Expected Error Term: 3.909e-18 + // Maximum Relative Change in Control Points: 9.886e-05 + static const double y = 0.50672817230224609375; + static const double p[] = { + -0.0243500476207698441272, + 0.0386540375035707201728, + 0.04394818964209516296, + 0.0175679436311802092299, + 0.00323962406290842133584, + 0.000235839115596880717416, + }; + static const double q[] = { + 1, + 1.53991494948552447182, + 0.982403709157920235114, + 0.325732924782444448493, + 0.0563921837420478160373, + 0.00410369723978904575884, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 1.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 1.5); + result *= exp(-z * z) / z; + return 1 - result; + } + else if (z < 4.5) { + // Maximum Deviation Found: 1.512e-17 + // Expected Error Term: 1.512e-17 + // Maximum Relative Change in Control Points: 2.222e-04 + // Max Error found at double precision = 2.062515e-17 + static const double y = 0.5405750274658203125; + static const double p[] = { + 0.00295276716530971662634, + 0.0137384425896355332126, + 0.00840807615555585383007, + 0.00212825620914618649141, + 0.000250269961544794627958, + 0.113212406648847561139e-4, + }; + static const double q[] = { + 1, + 1.04217814166938418171, + 0.442597659481563127003, + 0.0958492726301061423444, + 0.0105982906484876531489, + 0.000479411269521714493907, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 3.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 3.5); + result *= exp(-z * z) / z; + return 1 - result; + } + /* differ from Boost here, the claim of underflow of erfc(x) past 5.8 is + * slightly incorrect, change to 5.92 + * (really somewhere between 5.9125 and 5.925 is when it saturates) */ + else if (z < 5.92) { + // Max Error found at double precision = 2.997958e-17 + // Maximum Deviation Found: 2.860e-17 + // Expected Error Term: 2.859e-17 + // Maximum Relative Change in Control Points: 1.357e-05 + static const double y = 0.5579090118408203125; + static const double p[] = { + 0.00628057170626964891937, + 0.0175389834052493308818, + -0.212652252872804219852, + -0.687717681153649930619, + -2.5518551727311523996, + -3.22729451764143718517, + -2.8175401114513378771, + }; + static const double q[] = { + 1, + 2.79257750980575282228, + 11.0567237927800161565, + 15.930646027911794143, + 22.9367376522880577224, + 13.5064170191802889145, + 5.48409182238641741584, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), 1 / z) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), 1 / z); + result *= exp(-z * z) / z; + return 1 - result; + } + /* handle the nan case, but don't use isnan for max portability */ + else if (z != z) + return z; + /* finally return saturated result */ + else + return 1; +} +#endif /* HAVE_ERF */ + +#if !HAVE_EXPF +#undef expf +#define expf(x) ((float)exp(x)) +#endif /* HAVE_EXPF */ + +#if !HAVE_EXP2 +#undef exp2 +#define exp2(x) exp((x) * M_LN2) +#endif /* HAVE_EXP2 */ + +#if !HAVE_EXP2F +#undef exp2f +#define exp2f(x) ((float)exp2(x)) +#endif /* HAVE_EXP2F */ + +#if !HAVE_ISINF +#undef isinf +/* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for +-Inf, +1 for Inf, 0 otherwise, but merely follow the POSIX/ISO mandated spec of +returning a non-zero value for +/-Inf, 0 otherwise. */ +static av_always_inline av_const int avpriv_isinff(float x) +{ + uint32_t v = av_float2int(x); + if ((v & 0x7f800000) != 0x7f800000) + return 0; + return !(v & 0x007fffff); +} + +static av_always_inline av_const int avpriv_isinf(double x) +{ + uint64_t v = av_double2int(x); + if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) + return 0; + return !(v & 0x000fffffffffffff); +} + +#define isinf(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isinff(x) \ + : avpriv_isinf(x)) +#endif /* HAVE_ISINF */ + +#if !HAVE_ISNAN +static av_always_inline av_const int avpriv_isnanf(float x) +{ + uint32_t v = av_float2int(x); + if ((v & 0x7f800000) != 0x7f800000) + return 0; + return v & 0x007fffff; +} + +static av_always_inline av_const int avpriv_isnan(double x) +{ + uint64_t v = av_double2int(x); + if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) + return 0; + return (v & 0x000fffffffffffff) && 1; +} + +#define isnan(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isnanf(x) \ + : avpriv_isnan(x)) +#endif /* HAVE_ISNAN */ + +#if !HAVE_ISFINITE +static av_always_inline av_const int avpriv_isfinitef(float x) +{ + uint32_t v = av_float2int(x); + return (v & 0x7f800000) != 0x7f800000; +} + +static av_always_inline av_const int avpriv_isfinite(double x) +{ + uint64_t v = av_double2int(x); + return (v & 0x7ff0000000000000) != 0x7ff0000000000000; +} + +#define isfinite(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isfinitef(x) \ + : avpriv_isfinite(x)) +#endif /* HAVE_ISFINITE */ + +#if !HAVE_HYPOT +static inline av_const double hypot(double x, double y) +{ + double ret, temp; + x = fabs(x); + y = fabs(y); + + if (isinf(x) || isinf(y)) + return av_int2double(0x7ff0000000000000); + if (x == 0 || y == 0) + return x + y; + if (x < y) { + temp = x; + x = y; + y = temp; + } + + y = y/x; + return x*sqrt(1 + y*y); +} +#endif /* HAVE_HYPOT */ + +#if !HAVE_LDEXPF +#undef ldexpf +#define ldexpf(x, exp) ((float)ldexp(x, exp)) +#endif /* HAVE_LDEXPF */ + +#if !HAVE_LLRINT +#undef llrint +#define llrint(x) ((long long)rint(x)) +#endif /* HAVE_LLRINT */ + +#if !HAVE_LLRINTF +#undef llrintf +#define llrintf(x) ((long long)rint(x)) +#endif /* HAVE_LLRINT */ + +#if !HAVE_LOG2 +#undef log2 +#define log2(x) (log(x) * 1.44269504088896340736) +#endif /* HAVE_LOG2 */ + +#if !HAVE_LOG2F +#undef log2f +#define log2f(x) ((float)log2(x)) +#endif /* HAVE_LOG2F */ + +#if !HAVE_LOG10F +#undef log10f +#define log10f(x) ((float)log10(x)) +#endif /* HAVE_LOG10F */ + +#if !HAVE_SINF +#undef sinf +#define sinf(x) ((float)sin(x)) +#endif /* HAVE_SINF */ + +#if !HAVE_RINT +static inline double rint(double x) +{ + return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_RINT */ + +#if !HAVE_LRINT +static av_always_inline av_const long int lrint(double x) +{ + return rint(x); +} +#endif /* HAVE_LRINT */ + +#if !HAVE_LRINTF +static av_always_inline av_const long int lrintf(float x) +{ + return (int)(rint(x)); +} +#endif /* HAVE_LRINTF */ + +#if !HAVE_ROUND +static av_always_inline av_const double round(double x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUND */ + +#if !HAVE_ROUNDF +static av_always_inline av_const float roundf(float x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUNDF */ + +#if !HAVE_TRUNC +static av_always_inline av_const double trunc(double x) +{ + return (x > 0) ? floor(x) : ceil(x); +} +#endif /* HAVE_TRUNC */ + +#if !HAVE_TRUNCF +static av_always_inline av_const float truncf(float x) +{ + return (x > 0) ? floor(x) : ceil(x); +} +#endif /* HAVE_TRUNCF */ + +#endif /* AVUTIL_LIBM_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lls.c b/arm/raspi/third_party/ffmpeg/libavutil/lls.c new file mode 100644 index 00000000..c1e038da --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lls.c @@ -0,0 +1,123 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * linear least squares model + */ + +#include +#include + +#include "config.h" +#include "attributes.h" +#include "lls.h" + +static void update_lls(LLSModel *m, const double *var) +{ + int i, j; + + for (i = 0; i <= m->indep_count; i++) { + for (j = i; j <= m->indep_count; j++) { + m->covariance[i][j] += var[i] * var[j]; + } + } +} + +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) +{ + int i, j, k; + double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; + double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1]; + double *covar_y = m->covariance[0]; + int count = m->indep_count; + + for (i = 0; i < count; i++) { + for (j = i; j < count; j++) { + double sum = covar[i][j]; + + for (k = 0; k <= i-1; k++) + sum -= factor[i][k] * factor[j][k]; + + if (i == j) { + if (sum < threshold) + sum = 1.0; + factor[i][i] = sqrt(sum); + } else { + factor[j][i] = sum / factor[i][i]; + } + } + } + + for (i = 0; i < count; i++) { + double sum = covar_y[i + 1]; + + for (k = 0; k <= i-1; k++) + sum -= factor[i][k] * m->coeff[0][k]; + + m->coeff[0][i] = sum / factor[i][i]; + } + + for (j = count - 1; j >= min_order; j--) { + for (i = j; i >= 0; i--) { + double sum = m->coeff[0][i]; + + for (k = i + 1; k <= j; k++) + sum -= factor[k][i] * m->coeff[j][k]; + + m->coeff[j][i] = sum / factor[i][i]; + } + + m->variance[j] = covar_y[0]; + + for (i = 0; i <= j; i++) { + double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1]; + + for (k = 0; k < i; k++) + sum += 2 * m->coeff[j][k] * covar[k][i]; + + m->variance[j] += m->coeff[j][i] * sum; + } + } +} + +static double evaluate_lls(LLSModel *m, const double *param, int order) +{ + int i; + double out = 0; + + for (i = 0; i <= order; i++) + out += param[i] * m->coeff[order][i]; + + return out; +} + +av_cold void avpriv_init_lls(LLSModel *m, int indep_count) +{ + memset(m, 0, sizeof(LLSModel)); + m->indep_count = indep_count; + m->update_lls = update_lls; + m->evaluate_lls = evaluate_lls; +#if ARCH_X86 + ff_init_lls_x86(m); +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lls.h b/arm/raspi/third_party/ffmpeg/libavutil/lls.h new file mode 100644 index 00000000..07092758 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lls.h @@ -0,0 +1,63 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LLS_H +#define AVUTIL_LLS_H + +#include "macros.h" +#include "mem_internal.h" + +#define MAX_VARS 32 +#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4) + +//FIXME avoid direct access to LLSModel from outside + +/** + * Linear least squares model. + */ +typedef struct LLSModel { + DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]); + DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]); + double variance[MAX_VARS]; + int indep_count; + /** + * Take the outer-product of var[] with itself, and add to the covariance matrix. + * @param m this context + * @param var training samples, starting with the value to be predicted + * 32-byte aligned, and any padding elements must be initialized + * (i.e not denormal/nan). + */ + void (*update_lls)(struct LLSModel *m, const double *var); + /** + * Inner product of var[] and the LPC coefs. + * @param m this context + * @param var training samples, excluding the value to be predicted. unaligned. + * @param order lpc order + */ + double (*evaluate_lls)(struct LLSModel *m, const double *var, int order); +} LLSModel; + +void avpriv_init_lls(LLSModel *m, int indep_count); +void ff_init_lls_x86(LLSModel *m); +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); + +#endif /* AVUTIL_LLS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/log.c b/arm/raspi/third_party/ffmpeg/libavutil/log.c new file mode 100644 index 00000000..9e2ebcfd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/log.c @@ -0,0 +1,499 @@ +/* + * log functions + * Copyright (c) 2003 Michel Bardiaux + * + * 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 + * logging functions + */ + +#include "config.h" + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#include +#include +#include +#include +#include +#include "bprint.h" +#include "common.h" +#include "internal.h" +#include "log.h" +#include "thread.h" + +static AVMutex mutex = AV_MUTEX_INITIALIZER; + +#define LINE_SZ 1024 + +#if HAVE_VALGRIND_VALGRIND_H +#include +/* this is the log level at which valgrind will output a full backtrace */ +#define BACKTRACE_LOGLEVEL AV_LOG_ERROR +#endif + +static int av_log_level = AV_LOG_INFO; +static int flags; + +#define NB_LEVELS 8 +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE +#include +static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = { + [AV_LOG_PANIC /8] = 12, + [AV_LOG_FATAL /8] = 12, + [AV_LOG_ERROR /8] = 12, + [AV_LOG_WARNING/8] = 14, + [AV_LOG_INFO /8] = 7, + [AV_LOG_VERBOSE/8] = 10, + [AV_LOG_DEBUG /8] = 10, + [AV_LOG_TRACE /8] = 8, + [16+AV_CLASS_CATEGORY_NA ] = 7, + [16+AV_CLASS_CATEGORY_INPUT ] = 13, + [16+AV_CLASS_CATEGORY_OUTPUT ] = 5, + [16+AV_CLASS_CATEGORY_MUXER ] = 13, + [16+AV_CLASS_CATEGORY_DEMUXER ] = 5, + [16+AV_CLASS_CATEGORY_ENCODER ] = 11, + [16+AV_CLASS_CATEGORY_DECODER ] = 3, + [16+AV_CLASS_CATEGORY_FILTER ] = 10, + [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 9, + [16+AV_CLASS_CATEGORY_SWSCALER ] = 7, + [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 7, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 5, +}; + +static int16_t background, attr_orig; +static HANDLE con; +#else + +static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = { + [AV_LOG_PANIC /8] = 52 << 16 | 196 << 8 | 0x41, + [AV_LOG_FATAL /8] = 208 << 8 | 0x41, + [AV_LOG_ERROR /8] = 196 << 8 | 0x11, + [AV_LOG_WARNING/8] = 226 << 8 | 0x03, + [AV_LOG_INFO /8] = 253 << 8 | 0x09, + [AV_LOG_VERBOSE/8] = 40 << 8 | 0x02, + [AV_LOG_DEBUG /8] = 34 << 8 | 0x02, + [AV_LOG_TRACE /8] = 34 << 8 | 0x07, + [16+AV_CLASS_CATEGORY_NA ] = 250 << 8 | 0x09, + [16+AV_CLASS_CATEGORY_INPUT ] = 219 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_OUTPUT ] = 201 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_MUXER ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEMUXER ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_ENCODER ] = 51 << 8 | 0x16, + [16+AV_CLASS_CATEGORY_DECODER ] = 39 << 8 | 0x06, + [16+AV_CLASS_CATEGORY_FILTER ] = 155 << 8 | 0x12, + [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_SWSCALER ] = 153 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 147 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 207 << 8 | 0x05, +}; + +#endif +static int use_color = -1; + +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE +static void win_console_puts(const char *str) +{ + const uint8_t *q = str; + uint16_t line[LINE_SZ]; + + while (*q) { + uint16_t *buf = line; + DWORD nb_chars = 0; + DWORD written; + + while (*q && nb_chars < LINE_SZ - 1) { + uint32_t ch; + uint16_t tmp; + + GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd; goto continue_on_invalid;) +continue_on_invalid: + PUT_UTF16(ch, tmp, *buf++ = tmp; nb_chars++;) + } + + WriteConsoleW(con, line, nb_chars, &written, NULL); + } +} +#endif + +static void check_color_terminal(void) +{ + char *term = getenv("TERM"); + +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE + CONSOLE_SCREEN_BUFFER_INFO con_info; + DWORD dummy; + con = GetStdHandle(STD_ERROR_HANDLE); + if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &dummy)) + con = INVALID_HANDLE_VALUE; + if (con != INVALID_HANDLE_VALUE) { + GetConsoleScreenBufferInfo(con, &con_info); + attr_orig = con_info.wAttributes; + background = attr_orig & 0xF0; + } +#endif + + if (getenv("AV_LOG_FORCE_NOCOLOR")) { + use_color = 0; + } else if (getenv("AV_LOG_FORCE_COLOR")) { + use_color = 1; + } else { +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE + use_color = (con != INVALID_HANDLE_VALUE); +#elif HAVE_ISATTY + use_color = (term && isatty(2)); +#else + use_color = 0; +#endif + } + + if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color")) + use_color *= 256; +} + +static void ansi_fputs(int level, int tint, const char *str, int local_use_color) +{ + if (local_use_color == 1) { + fprintf(stderr, + "\033[%"PRIu32";3%"PRIu32"m%s\033[0m", + (color[level] >> 4) & 15, + color[level] & 15, + str); + } else if (tint && use_color == 256) { + fprintf(stderr, + "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m", + (color[level] >> 16) & 0xff, + tint, + str); + } else if (local_use_color == 256) { + fprintf(stderr, + "\033[48;5;%"PRIu32"m\033[38;5;%"PRIu32"m%s\033[0m", + (color[level] >> 16) & 0xff, + (color[level] >> 8) & 0xff, + str); + } else + fputs(str, stderr); +} + +static void colored_fputs(int level, int tint, const char *str) +{ + int local_use_color; + if (!*str) + return; + + if (use_color < 0) + check_color_terminal(); + + if (level == AV_LOG_INFO/8) local_use_color = 0; + else local_use_color = use_color; + +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE + if (con != INVALID_HANDLE_VALUE) { + if (local_use_color) + SetConsoleTextAttribute(con, background | color[level]); + win_console_puts(str); + if (local_use_color) + SetConsoleTextAttribute(con, attr_orig); + } else { + ansi_fputs(level, tint, str, local_use_color); + } +#else + ansi_fputs(level, tint, str, local_use_color); +#endif + +} + +const char *av_default_item_name(void *ptr) +{ + return (*(AVClass **) ptr)->class_name; +} + +AVClassCategory av_default_get_category(void *ptr) +{ + return (*(AVClass **) ptr)->category; +} + +static void sanitize(uint8_t *line){ + while(*line){ + if(*line < 0x08 || (*line > 0x0D && *line < 0x20)) + *line='?'; + line++; + } +} + +static int get_category(void *ptr){ + AVClass *avc = *(AVClass **) ptr; + if( !avc + || (avc->version&0xFF)<100 + || avc->version < (51 << 16 | 59 << 8) + || avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16; + + if(avc->get_category) + return avc->get_category(ptr) + 16; + + return avc->category + 16; +} + +static const char *get_level_str(int level) +{ + switch (level) { + case AV_LOG_QUIET: + return "quiet"; + case AV_LOG_DEBUG: + return "debug"; + case AV_LOG_TRACE: + return "trace"; + case AV_LOG_VERBOSE: + return "verbose"; + case AV_LOG_INFO: + return "info"; + case AV_LOG_WARNING: + return "warning"; + case AV_LOG_ERROR: + return "error"; + case AV_LOG_FATAL: + return "fatal"; + case AV_LOG_PANIC: + return "panic"; + default: + return ""; + } +} + +static void format_line(void *avcl, int level, const char *fmt, va_list vl, + AVBPrint part[4], int *print_prefix, int type[2]) +{ + AVClass* avc = avcl ? *(AVClass **) avcl : NULL; + av_bprint_init(part+0, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+1, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+2, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+3, 0, 65536); + + if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16; + if (*print_prefix && avc) { + if (avc->parent_log_context_offset) { + AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) + + avc->parent_log_context_offset); + if (parent && *parent) { + av_bprintf(part+0, "[%s @ %p] ", + (*parent)->item_name(parent), parent); + if(type) type[0] = get_category(parent); + } + } + av_bprintf(part+1, "[%s @ %p] ", + avc->item_name(avcl), avcl); + if(type) type[1] = get_category(avcl); + } + + if (*print_prefix && (level > AV_LOG_QUIET) && (flags & AV_LOG_PRINT_LEVEL)) + av_bprintf(part+2, "[%s] ", get_level_str(level)); + + av_vbprintf(part+3, fmt, vl); + + if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) { + char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0; + *print_prefix = lastc == '\n' || lastc == '\r'; + } +} + +void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix) +{ + av_log_format_line2(ptr, level, fmt, vl, line, line_size, print_prefix); +} + +int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix) +{ + AVBPrint part[4]; + int ret; + + format_line(ptr, level, fmt, vl, part, print_prefix, NULL); + ret = snprintf(line, line_size, "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str); + av_bprint_finalize(part+3, NULL); + return ret; +} + +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) +{ + static int print_prefix = 1; + static int count; + static char prev[LINE_SZ]; + AVBPrint part[4]; + char line[LINE_SZ]; + static int is_atty; + int type[2]; + unsigned tint = 0; + + if (level >= 0) { + tint = level & 0xff00; + level &= 0xff; + } + + if (level > av_log_level) + return; + ff_mutex_lock(&mutex); + + format_line(ptr, level, fmt, vl, part, &print_prefix, type); + snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str); + +#if HAVE_ISATTY + if (!is_atty) + is_atty = isatty(2) ? 1 : -1; +#endif + + if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) && + *line && line[strlen(line) - 1] != '\r'){ + count++; + if (is_atty == 1) + fprintf(stderr, " Last message repeated %d times\r", count); + goto end; + } + if (count > 0) { + fprintf(stderr, " Last message repeated %d times\n", count); + count = 0; + } + strcpy(prev, line); + sanitize(part[0].str); + colored_fputs(type[0], 0, part[0].str); + sanitize(part[1].str); + colored_fputs(type[1], 0, part[1].str); + sanitize(part[2].str); + colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str); + sanitize(part[3].str); + colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str); + +#if CONFIG_VALGRIND_BACKTRACE + if (level <= BACKTRACE_LOGLEVEL) + VALGRIND_PRINTF_BACKTRACE("%s", ""); +#endif +end: + av_bprint_finalize(part+3, NULL); + ff_mutex_unlock(&mutex); +} + +static void (*av_log_callback)(void*, int, const char*, va_list) = + av_log_default_callback; +#if !defined(CHROMIUM_NO_LOGGING) +void av_log(void* avcl, int level, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + av_vlog(avcl, level, fmt, vl); + va_end(vl); +} +#endif + +#if !defined(CHROMIUM_NO_LOGGING) +void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + av_vlog(avcl, *state ? subsequent_level : initial_level, fmt, vl); + va_end(vl); + *state = 1; +} +#endif + +#if !defined(CHROMIUM_NO_LOGGING) +void av_vlog(void* avcl, int level, const char *fmt, va_list vl) +{ + AVClass* avc = avcl ? *(AVClass **) avcl : NULL; + void (*log_callback)(void*, int, const char*, va_list) = av_log_callback; + if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) && + avc->log_level_offset_offset && level >= AV_LOG_FATAL) + level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset); + if (log_callback) + log_callback(avcl, level, fmt, vl); +} +#endif + +int av_log_get_level(void) +{ + return av_log_level; +} + +void av_log_set_level(int level) +{ + av_log_level = level; +} + +void av_log_set_flags(int arg) +{ + flags = arg; +} + +int av_log_get_flags(void) +{ + return flags; +} + +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) +{ + av_log_callback = callback; +} + +#if !defined(CHROMIUM_NO_LOGGING) +static void missing_feature_sample(int sample, void *avc, const char *msg, + va_list argument_list) +{ + av_vlog(avc, AV_LOG_WARNING, msg, argument_list); + av_log(avc, AV_LOG_WARNING, " is not implemented. Update your FFmpeg " + "version to the newest one from Git. If the problem still " + "occurs, it means that your file has a feature which has not " + "been implemented.\n"); + if (sample) + av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample " + "of this file to https://streams.videolan.org/upload/ " + "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n"); +} + +void avpriv_request_sample(void *avc, const char *msg, ...) +{ + va_list argument_list; + + va_start(argument_list, msg); + missing_feature_sample(1, avc, msg, argument_list); + va_end(argument_list); +} + +void avpriv_report_missing_feature(void *avc, const char *msg, ...) +{ + va_list argument_list; + + va_start(argument_list, msg); + missing_feature_sample(0, avc, msg, argument_list); + va_end(argument_list); +} +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/log.h b/arm/raspi/third_party/ffmpeg/libavutil/log.h new file mode 100644 index 00000000..08e4bd70 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/log.h @@ -0,0 +1,398 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include +#include "attributes.h" +#include "version.h" + +typedef enum { + AV_CLASS_CATEGORY_NA = 0, + AV_CLASS_CATEGORY_INPUT, + AV_CLASS_CATEGORY_OUTPUT, + AV_CLASS_CATEGORY_MUXER, + AV_CLASS_CATEGORY_DEMUXER, + AV_CLASS_CATEGORY_ENCODER, + AV_CLASS_CATEGORY_DECODER, + AV_CLASS_CATEGORY_FILTER, + AV_CLASS_CATEGORY_BITSTREAM_FILTER, + AV_CLASS_CATEGORY_SWSCALER, + AV_CLASS_CATEGORY_SWRESAMPLER, + AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, + AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, + AV_CLASS_CATEGORY_DEVICE_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_INPUT, + AV_CLASS_CATEGORY_NB ///< not part of ABI/API +}AVClassCategory; + +#define AV_IS_INPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_INPUT)) + +#define AV_IS_OUTPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_OUTPUT)) + +struct AVOptionRanges; + +/** + * Describe the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct AVClass { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; + + /** + * LIBAVUTIL_VERSION with which this structure was created. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. + */ + + int version; + + /** + * Offset in the structure where log_level_offset is stored. + * 0 means there is no such variable + */ + int log_level_offset_offset; + + /** + * Offset in the structure where a pointer to the parent context for + * logging is stored. For example a decoder could pass its AVCodecContext + * to eval as such a parent context, which an av_log() implementation + * could then leverage to display the parent context. + * The offset can be NULL. + */ + int parent_log_context_offset; + + /** + * Category used for visualization (like color) + * This is only set if the category is equal for all objects using this class. + * available since version (51 << 16 | 56 << 8 | 100) + */ + AVClassCategory category; + + /** + * Callback to return the category. + * available since version (51 << 16 | 59 << 8 | 100) + */ + AVClassCategory (*get_category)(void* ctx); + + /** + * Callback to return the supported/allowed ranges. + * available since version (52.12) + */ + int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); + + /** + * Return next AVOptions-enabled child or NULL + */ + void* (*child_next)(void *obj, void *prev); + + /** + * Iterate over the AVClasses corresponding to potential AVOptions-enabled + * children. + * + * @param iter pointer to opaque iteration state. The caller must initialize + * *iter to NULL before the first call. + * @return AVClass for the next AVOptions-enabled child or NULL if there are + * no more such children. + * + * @note The difference between child_next and this is that child_next + * iterates over _already existing_ objects, while child_class_iterate + * iterates over _all possible_ children. + */ + const struct AVClass* (*child_class_iterate)(void **iter); +} AVClass; + +/** + * @addtogroup lavu_log + * + * @{ + * + * @defgroup lavu_log_constants Logging Constants + * + * @{ + */ + +/** + * Print no output. + */ +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +/** + * Standard information. + */ +#define AV_LOG_INFO 32 + +/** + * Detailed information. + */ +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Extremely verbose debugging, useful for libav* development. + */ +#define AV_LOG_TRACE 56 + +#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) + +/** + * @} + */ + +/** + * Sets additional colors for extended debugging sessions. + * @code + av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); + @endcode + * Requires 256color terminal support. Uses outside debugging is not + * recommended. + */ +#define AV_LOG_C(x) ((x) << 8) + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct or NULL if general log. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + */ +#if defined(CHROMIUM_NO_LOGGING) +#define av_log(...) +#else +void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); +#endif + +/** + * Send the specified message to the log once with the initial_level and then with + * the subsequent_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct or NULL if general log. + * @param initial_level importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant" for the first occurance. + * @param subsequent_level importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant" after the first occurance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param state a variable to keep trak of if a message has already been printed + * this must be initialized to 0 before the first use. The same state + * must not be accessed by 2 Threads simultaneously. + */ +#if defined(CHROMIUM_NO_LOGGING) +#define av_log_once(...) +#else +void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...) av_printf_format(5, 6); +#endif + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +#if defined(CHROMIUM_NO_LOGGING) +#define av_vlog(...) +#else +void av_vlog(void *avcl, int level, const char *fmt, va_list vl); +#endif + +/** + * Get the current log level + * + * @see lavu_log_constants + * + * @return Current log level + */ +int av_log_get_level(void); + +/** + * Set the log level + * + * @see lavu_log_constants + * + * @param level Logging level + */ +void av_log_set_level(int level); + +/** + * Set the logging callback + * + * @note The callback must be thread safe, even if the application does not use + * threads itself as some codecs are multithreaded. + * + * @see av_log_default_callback + * + * @param callback A logging function with a compatible signature. + */ +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); + +/** + * Default logging callback + * + * It prints the message to stderr, optionally colorizing it. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_log_default_callback(void *avcl, int level, const char *fmt, + va_list vl); + +/** + * Return the context name + * + * @param ctx The AVClass context + * + * @return The AVClass class_name + */ +const char* av_default_item_name(void* ctx); +AVClassCategory av_default_get_category(void *ptr); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line + * @param line_size size of the buffer + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + */ +void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line; + * may be NULL if line_size is 0 + * @param line_size size of the buffer; at most line_size-1 characters will + * be written to the buffer, plus one null terminator + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + * @return Returns a negative value if an error occurred, otherwise returns + * the number of characters that would have been written for a + * sufficiently large buffer, not including the terminating null + * character. If the return value is not less than line_size, it means + * that the log message was truncated to fit the buffer. + */ +int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Skip repeated messages, this requires the user app to use av_log() instead of + * (f)printf as the 2 would otherwise interfere and lead to + * "Last message repeated x times" messages below (f)printf messages with some + * bad luck. + * Also to receive the last, "last repeated" line if any, the user app must + * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end + */ +#define AV_LOG_SKIP_REPEATED 1 + +/** + * Include the log severity in messages originating from codecs. + * + * Results in messages such as: + * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts + */ +#define AV_LOG_PRINT_LEVEL 2 + +void av_log_set_flags(int arg); +int av_log_get_flags(void); + +/** + * @} + */ + +#endif /* AVUTIL_LOG_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/log2_tab.c b/arm/raspi/third_party/ffmpeg/libavutil/log2_tab.c new file mode 100644 index 00000000..0dbf07d7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/log2_tab.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/loongarch/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/Makefile new file mode 100644 index 00000000..2addd935 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/Makefile @@ -0,0 +1 @@ +OBJS += loongarch/cpu.o diff --git a/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.c new file mode 100644 index 00000000..e4b240bc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Loongson Technology Corporation Limited + * Contributed by Shiyou Yin + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "cpu.h" + +#define LOONGARCH_CFG2 0x2 +#define LOONGARCH_CFG2_LSX (1 << 6) +#define LOONGARCH_CFG2_LASX (1 << 7) + +static int cpu_flags_cpucfg(void) +{ + int flags = 0; + uint32_t cfg2 = 0; + + __asm__ volatile( + "cpucfg %0, %1 \n\t" + : "+&r"(cfg2) + : "r"(LOONGARCH_CFG2) + ); + + if (cfg2 & LOONGARCH_CFG2_LSX) + flags |= AV_CPU_FLAG_LSX; + + if (cfg2 & LOONGARCH_CFG2_LASX) + flags |= AV_CPU_FLAG_LASX; + + return flags; +} + +int ff_get_cpu_flags_loongarch(void) +{ +#if defined __linux__ + return cpu_flags_cpucfg(); +#else + /* Assume no SIMD ASE supported */ + return 0; +#endif +} + +size_t ff_get_cpu_max_align_loongarch(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_LASX) + return 32; + if (flags & AV_CPU_FLAG_LSX) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.h new file mode 100644 index 00000000..1a445c69 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/cpu.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 Loongson Technology Corporation Limited + * Contributed by Shiyou Yin + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOONGARCH_CPU_H +#define AVUTIL_LOONGARCH_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_lsx(flags) CPUEXT(flags, LSX) +#define have_lasx(flags) CPUEXT(flags, LASX) + +#endif /* AVUTIL_LOONGARCH_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/loongarch/loongson_intrinsics.h b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/loongson_intrinsics.h new file mode 100644 index 00000000..eb256863 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/loongarch/loongson_intrinsics.h @@ -0,0 +1,1948 @@ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + * All rights reserved. + * Contributed by Shiyou Yin + * Xiwei Gu + * Lu Wang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef AVUTIL_LOONGARCH_LOONGSON_INTRINSICS_H +#define AVUTIL_LOONGARCH_LOONGSON_INTRINSICS_H + +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + * All rights reserved. + * Contributed by Shiyou Yin + * Xiwei Gu + * Lu Wang + * + * This file is a header file for loongarch builtin extension. + * + */ + +#ifndef LOONGSON_INTRINSICS_H +#define LOONGSON_INTRINSICS_H + +/** + * MAJOR version: Macro usage changes. + * MINOR version: Add new functions, or bug fixes. + * MICRO version: Comment changes or implementation changes. + */ +#define LSOM_VERSION_MAJOR 1 +#define LSOM_VERSION_MINOR 1 +#define LSOM_VERSION_MICRO 0 + +#define DUP2_ARG1(_INS, _IN0, _IN1, _OUT0, _OUT1) \ + { \ + _OUT0 = _INS(_IN0); \ + _OUT1 = _INS(_IN1); \ + } + +#define DUP2_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1) \ + { \ + _OUT0 = _INS(_IN0, _IN1); \ + _OUT1 = _INS(_IN2, _IN3); \ + } + +#define DUP2_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _OUT0, _OUT1) \ + { \ + _OUT0 = _INS(_IN0, _IN1, _IN2); \ + _OUT1 = _INS(_IN3, _IN4, _IN5); \ + } + +#define DUP4_ARG1(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1, _OUT2, _OUT3) \ + { \ + DUP2_ARG1(_INS, _IN0, _IN1, _OUT0, _OUT1); \ + DUP2_ARG1(_INS, _IN2, _IN3, _OUT2, _OUT3); \ + } + +#define DUP4_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _IN6, _IN7, _OUT0, \ + _OUT1, _OUT2, _OUT3) \ + { \ + DUP2_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1); \ + DUP2_ARG2(_INS, _IN4, _IN5, _IN6, _IN7, _OUT2, _OUT3); \ + } + +#define DUP4_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _IN6, _IN7, _IN8, \ + _IN9, _IN10, _IN11, _OUT0, _OUT1, _OUT2, _OUT3) \ + { \ + DUP2_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _OUT0, _OUT1); \ + DUP2_ARG3(_INS, _IN6, _IN7, _IN8, _IN9, _IN10, _IN11, _OUT2, _OUT3); \ + } + +#ifdef __loongarch_sx +#include +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Signed byte elements from in_h are multiplied by + * signed byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Then the results plus to signed half-word elements from in_c. + * Example : out = __lsx_vdp2add_h_b(in_c, in_h, in_l) + * in_c : 1,2,3,4, 1,2,3,4 + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 + * out : 23,40,41,26, 23,40,41,26 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2add_h_b(__m128i in_c, __m128i in_h, + __m128i in_l) { + __m128i out; + + out = __lsx_vmaddwev_h_b(in_c, in_h, in_l); + out = __lsx_vmaddwod_h_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied by + * unsigned byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * The results plus to signed half-word elements from in_c. + * Example : out = __lsx_vdp2add_h_bu(in_c, in_h, in_l) + * in_c : 1,2,3,4, 1,2,3,4 + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 + * out : 23,40,41,26, 23,40,41,26 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2add_h_bu(__m128i in_c, __m128i in_h, + __m128i in_l) { + __m128i out; + + out = __lsx_vmaddwev_h_bu(in_c, in_h, in_l); + out = __lsx_vmaddwod_h_bu(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied by + * signed byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * The results plus to signed half-word elements from in_c. + * Example : out = __lsx_vdp2add_h_bu_b(in_c, in_h, in_l) + * in_c : 1,1,1,1, 1,1,1,1 + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : -1,-2,-3,-4, -5,-6,-7,-8, 1,2,3,4, 5,6,7,8 + * out : -4,-24,-60,-112, 6,26,62,114 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2add_h_bu_b(__m128i in_c, __m128i in_h, + __m128i in_l) { + __m128i out; + + out = __lsx_vmaddwev_h_bu_b(in_c, in_h, in_l); + out = __lsx_vmaddwod_h_bu_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of half-word vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Outputs - out + * Return Type - __m128i + * Details : Signed half-word elements from in_h are multiplied by + * signed half-word elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Then the results plus to signed word elements from in_c. + * Example : out = __lsx_vdp2add_h_b(in_c, in_h, in_l) + * in_c : 1,2,3,4 + * in_h : 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1 + * out : 23,40,41,26 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2add_w_h(__m128i in_c, __m128i in_h, + __m128i in_l) { + __m128i out; + + out = __lsx_vmaddwev_w_h(in_c, in_h, in_l); + out = __lsx_vmaddwod_w_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Signed byte elements from in_h are multiplied by + * signed byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Example : out = __lsx_vdp2_h_b(in_h, in_l) + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 + * out : 22,38,38,22, 22,38,38,22 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2_h_b(__m128i in_h, __m128i in_l) { + __m128i out; + + out = __lsx_vmulwev_h_b(in_h, in_l); + out = __lsx_vmaddwod_h_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied by + * unsigned byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Example : out = __lsx_vdp2_h_bu(in_h, in_l) + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 + * out : 22,38,38,22, 22,38,38,22 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2_h_bu(__m128i in_h, __m128i in_l) { + __m128i out; + + out = __lsx_vmulwev_h_bu(in_h, in_l); + out = __lsx_vmaddwod_h_bu(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied by + * signed byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Example : out = __lsx_vdp2_h_bu_b(in_h, in_l) + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,-1 + * out : 22,38,38,22, 22,38,38,6 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2_h_bu_b(__m128i in_h, __m128i in_l) { + __m128i out; + + out = __lsx_vmulwev_h_bu_b(in_h, in_l); + out = __lsx_vmaddwod_h_bu_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Outputs - out + * Return Type - halfword + * Details : Signed byte elements from in_h are multiplied by + * signed byte elements from in_l, and then added adjacent to + * each other to get results with the twice size of input. + * Example : out = __lsx_vdp2_w_h(in_h, in_l) + * in_h : 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1 + * out : 22,38,38,22 + * ============================================================================= + */ +static inline __m128i __lsx_vdp2_w_h(__m128i in_h, __m128i in_l) { + __m128i out; + + out = __lsx_vmulwev_w_h(in_h, in_l); + out = __lsx_vmaddwod_w_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Clip all halfword elements of input vector between min & max + * out = ((_in) < (min)) ? (min) : (((_in) > (max)) ? (max) : + * (_in)) + * Arguments : Inputs - _in (input vector) + * - min (min threshold) + * - max (max threshold) + * Outputs - out (output vector with clipped elements) + * Return Type - signed halfword + * Example : out = __lsx_vclip_h(_in) + * _in : -8,2,280,249, -8,255,280,249 + * min : 1,1,1,1, 1,1,1,1 + * max : 9,9,9,9, 9,9,9,9 + * out : 1,2,9,9, 1,9,9,9 + * ============================================================================= + */ +static inline __m128i __lsx_vclip_h(__m128i _in, __m128i min, __m128i max) { + __m128i out; + + out = __lsx_vmax_h(min, _in); + out = __lsx_vmin_h(max, out); + return out; +} + +/* + * ============================================================================= + * Description : Set each element of vector between 0 and 255 + * Arguments : Inputs - _in + * Outputs - out + * Return Type - halfword + * Details : Signed byte elements from _in are clamped between 0 and 255. + * Example : out = __lsx_vclip255_h(_in) + * _in : -8,255,280,249, -8,255,280,249 + * out : 0,255,255,249, 0,255,255,249 + * ============================================================================= + */ +static inline __m128i __lsx_vclip255_h(__m128i _in) { + __m128i out; + + out = __lsx_vmaxi_h(_in, 0); + out = __lsx_vsat_hu(out, 7); + return out; +} + +/* + * ============================================================================= + * Description : Set each element of vector between 0 and 255 + * Arguments : Inputs - _in + * Outputs - out + * Return Type - word + * Details : Signed byte elements from _in are clamped between 0 and 255. + * Example : out = __lsx_vclip255_w(_in) + * _in : -8,255,280,249 + * out : 0,255,255,249 + * ============================================================================= + */ +static inline __m128i __lsx_vclip255_w(__m128i _in) { + __m128i out; + + out = __lsx_vmaxi_w(_in, 0); + out = __lsx_vsat_wu(out, 7); + return out; +} + +/* + * ============================================================================= + * Description : Swap two variables + * Arguments : Inputs - _in0, _in1 + * Outputs - _in0, _in1 (in-place) + * Details : Swapping of two input variables using xor + * Example : LSX_SWAP(_in0, _in1) + * _in0 : 1,2,3,4 + * _in1 : 5,6,7,8 + * _in0(out) : 5,6,7,8 + * _in1(out) : 1,2,3,4 + * ============================================================================= + */ +#define LSX_SWAP(_in0, _in1) \ + { \ + _in0 = __lsx_vxor_v(_in0, _in1); \ + _in1 = __lsx_vxor_v(_in0, _in1); \ + _in0 = __lsx_vxor_v(_in0, _in1); \ + } + +/* + * ============================================================================= + * Description : Transpose 4x4 block with word elements in vectors + * Arguments : Inputs - in0, in1, in2, in3 + * Outputs - out0, out1, out2, out3 + * Details : + * Example : + * 1, 2, 3, 4 1, 5, 9,13 + * 5, 6, 7, 8 to 2, 6,10,14 + * 9,10,11,12 =====> 3, 7,11,15 + * 13,14,15,16 4, 8,12,16 + * ============================================================================= + */ +#define LSX_TRANSPOSE4x4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + __m128i _t0, _t1, _t2, _t3; \ + \ + _t0 = __lsx_vilvl_w(_in1, _in0); \ + _t1 = __lsx_vilvh_w(_in1, _in0); \ + _t2 = __lsx_vilvl_w(_in3, _in2); \ + _t3 = __lsx_vilvh_w(_in3, _in2); \ + _out0 = __lsx_vilvl_d(_t2, _t0); \ + _out1 = __lsx_vilvh_d(_t2, _t0); \ + _out2 = __lsx_vilvl_d(_t3, _t1); \ + _out3 = __lsx_vilvh_d(_t3, _t1); \ + } + +/* + * ============================================================================= + * Description : Transpose 8x8 block with byte elements in vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 + * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, + * _out7 + * Details : The rows of the matrix become columns, and the columns + * become rows. + * Example : LSX_TRANSPOSE8x8_B + * _in0 : 00,01,02,03,04,05,06,07, 00,00,00,00,00,00,00,00 + * _in1 : 10,11,12,13,14,15,16,17, 00,00,00,00,00,00,00,00 + * _in2 : 20,21,22,23,24,25,26,27, 00,00,00,00,00,00,00,00 + * _in3 : 30,31,32,33,34,35,36,37, 00,00,00,00,00,00,00,00 + * _in4 : 40,41,42,43,44,45,46,47, 00,00,00,00,00,00,00,00 + * _in5 : 50,51,52,53,54,55,56,57, 00,00,00,00,00,00,00,00 + * _in6 : 60,61,62,63,64,65,66,67, 00,00,00,00,00,00,00,00 + * _in7 : 70,71,72,73,74,75,76,77, 00,00,00,00,00,00,00,00 + * + * _ out0 : 00,10,20,30,40,50,60,70, 00,00,00,00,00,00,00,00 + * _ out1 : 01,11,21,31,41,51,61,71, 00,00,00,00,00,00,00,00 + * _ out2 : 02,12,22,32,42,52,62,72, 00,00,00,00,00,00,00,00 + * _ out3 : 03,13,23,33,43,53,63,73, 00,00,00,00,00,00,00,00 + * _ out4 : 04,14,24,34,44,54,64,74, 00,00,00,00,00,00,00,00 + * _ out5 : 05,15,25,35,45,55,65,75, 00,00,00,00,00,00,00,00 + * _ out6 : 06,16,26,36,46,56,66,76, 00,00,00,00,00,00,00,00 + * _ out7 : 07,17,27,37,47,57,67,77, 00,00,00,00,00,00,00,00 + * ============================================================================= + */ +#define LSX_TRANSPOSE8x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + __m128i zero = { 0 }; \ + __m128i shuf8 = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; \ + __m128i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ + \ + _t0 = __lsx_vilvl_b(_in2, _in0); \ + _t1 = __lsx_vilvl_b(_in3, _in1); \ + _t2 = __lsx_vilvl_b(_in6, _in4); \ + _t3 = __lsx_vilvl_b(_in7, _in5); \ + _t4 = __lsx_vilvl_b(_t1, _t0); \ + _t5 = __lsx_vilvh_b(_t1, _t0); \ + _t6 = __lsx_vilvl_b(_t3, _t2); \ + _t7 = __lsx_vilvh_b(_t3, _t2); \ + _out0 = __lsx_vilvl_w(_t6, _t4); \ + _out2 = __lsx_vilvh_w(_t6, _t4); \ + _out4 = __lsx_vilvl_w(_t7, _t5); \ + _out6 = __lsx_vilvh_w(_t7, _t5); \ + _out1 = __lsx_vshuf_b(zero, _out0, shuf8); \ + _out3 = __lsx_vshuf_b(zero, _out2, shuf8); \ + _out5 = __lsx_vshuf_b(zero, _out4, shuf8); \ + _out7 = __lsx_vshuf_b(zero, _out6, shuf8); \ + } + +/* + * ============================================================================= + * Description : Transpose 8x8 block with half-word elements in vectors + * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + * Outputs - out0, out1, out2, out3, out4, out5, out6, out7 + * Details : + * Example : + * 00,01,02,03,04,05,06,07 00,10,20,30,40,50,60,70 + * 10,11,12,13,14,15,16,17 01,11,21,31,41,51,61,71 + * 20,21,22,23,24,25,26,27 02,12,22,32,42,52,62,72 + * 30,31,32,33,34,35,36,37 to 03,13,23,33,43,53,63,73 + * 40,41,42,43,44,45,46,47 ======> 04,14,24,34,44,54,64,74 + * 50,51,52,53,54,55,56,57 05,15,25,35,45,55,65,75 + * 60,61,62,63,64,65,66,67 06,16,26,36,46,56,66,76 + * 70,71,72,73,74,75,76,77 07,17,27,37,47,57,67,77 + * ============================================================================= + */ +#define LSX_TRANSPOSE8x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + __m128i _s0, _s1, _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ + \ + _s0 = __lsx_vilvl_h(_in6, _in4); \ + _s1 = __lsx_vilvl_h(_in7, _in5); \ + _t0 = __lsx_vilvl_h(_s1, _s0); \ + _t1 = __lsx_vilvh_h(_s1, _s0); \ + _s0 = __lsx_vilvh_h(_in6, _in4); \ + _s1 = __lsx_vilvh_h(_in7, _in5); \ + _t2 = __lsx_vilvl_h(_s1, _s0); \ + _t3 = __lsx_vilvh_h(_s1, _s0); \ + _s0 = __lsx_vilvl_h(_in2, _in0); \ + _s1 = __lsx_vilvl_h(_in3, _in1); \ + _t4 = __lsx_vilvl_h(_s1, _s0); \ + _t5 = __lsx_vilvh_h(_s1, _s0); \ + _s0 = __lsx_vilvh_h(_in2, _in0); \ + _s1 = __lsx_vilvh_h(_in3, _in1); \ + _t6 = __lsx_vilvl_h(_s1, _s0); \ + _t7 = __lsx_vilvh_h(_s1, _s0); \ + \ + _out0 = __lsx_vpickev_d(_t0, _t4); \ + _out2 = __lsx_vpickev_d(_t1, _t5); \ + _out4 = __lsx_vpickev_d(_t2, _t6); \ + _out6 = __lsx_vpickev_d(_t3, _t7); \ + _out1 = __lsx_vpickod_d(_t0, _t4); \ + _out3 = __lsx_vpickod_d(_t1, _t5); \ + _out5 = __lsx_vpickod_d(_t2, _t6); \ + _out7 = __lsx_vpickod_d(_t3, _t7); \ + } + +/* + * ============================================================================= + * Description : Transpose input 8x4 byte block into 4x8 + * Arguments : Inputs - _in0, _in1, _in2, _in3 (input 8x4 byte block) + * Outputs - _out0, _out1, _out2, _out3 (output 4x8 byte block) + * Return Type - as per RTYPE + * Details : The rows of the matrix become columns, and the columns become + * rows. + * Example : LSX_TRANSPOSE8x4_B + * _in0 : 00,01,02,03,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in1 : 10,11,12,13,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in2 : 20,21,22,23,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in3 : 30,31,32,33,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in4 : 40,41,42,43,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in5 : 50,51,52,53,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in6 : 60,61,62,63,00,00,00,00, 00,00,00,00,00,00,00,00 + * _in7 : 70,71,72,73,00,00,00,00, 00,00,00,00,00,00,00,00 + * + * _out0 : 00,10,20,30,40,50,60,70, 00,00,00,00,00,00,00,00 + * _out1 : 01,11,21,31,41,51,61,71, 00,00,00,00,00,00,00,00 + * _out2 : 02,12,22,32,42,52,62,72, 00,00,00,00,00,00,00,00 + * _out3 : 03,13,23,33,43,53,63,73, 00,00,00,00,00,00,00,00 + * ============================================================================= + */ +#define LSX_TRANSPOSE8x4_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3) \ + { \ + __m128i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + \ + _tmp0_m = __lsx_vpackev_w(_in4, _in0); \ + _tmp1_m = __lsx_vpackev_w(_in5, _in1); \ + _tmp2_m = __lsx_vilvl_b(_tmp1_m, _tmp0_m); \ + _tmp0_m = __lsx_vpackev_w(_in6, _in2); \ + _tmp1_m = __lsx_vpackev_w(_in7, _in3); \ + \ + _tmp3_m = __lsx_vilvl_b(_tmp1_m, _tmp0_m); \ + _tmp0_m = __lsx_vilvl_h(_tmp3_m, _tmp2_m); \ + _tmp1_m = __lsx_vilvh_h(_tmp3_m, _tmp2_m); \ + \ + _out0 = __lsx_vilvl_w(_tmp1_m, _tmp0_m); \ + _out2 = __lsx_vilvh_w(_tmp1_m, _tmp0_m); \ + _out1 = __lsx_vilvh_d(_out2, _out0); \ + _out3 = __lsx_vilvh_d(_out0, _out2); \ + } + +/* + * ============================================================================= + * Description : Transpose 16x8 block with byte elements in vectors + * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, in8 + * in9, in10, in11, in12, in13, in14, in15 + * Outputs - out0, out1, out2, out3, out4, out5, out6, out7 + * Details : + * Example : + * 000,001,002,003,004,005,006,007 + * 008,009,010,011,012,013,014,015 + * 016,017,018,019,020,021,022,023 + * 024,025,026,027,028,029,030,031 + * 032,033,034,035,036,037,038,039 + * 040,041,042,043,044,045,046,047 000,008,...,112,120 + * 048,049,050,051,052,053,054,055 001,009,...,113,121 + * 056,057,058,059,060,061,062,063 to 002,010,...,114,122 + * 064,068,066,067,068,069,070,071 =====> 003,011,...,115,123 + * 072,073,074,075,076,077,078,079 004,012,...,116,124 + * 080,081,082,083,084,085,086,087 005,013,...,117,125 + * 088,089,090,091,092,093,094,095 006,014,...,118,126 + * 096,097,098,099,100,101,102,103 007,015,...,119,127 + * 104,105,106,107,108,109,110,111 + * 112,113,114,115,116,117,118,119 + * 120,121,122,123,124,125,126,127 + * ============================================================================= + */ +#define LSX_TRANSPOSE16x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ + _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ + _out6, _out7) \ + { \ + __m128i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5, _tmp6, _tmp7; \ + __m128i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ + DUP4_ARG2(__lsx_vilvl_b, _in2, _in0, _in3, _in1, _in6, _in4, _in7, _in5, \ + _tmp0, _tmp1, _tmp2, _tmp3); \ + DUP4_ARG2(__lsx_vilvl_b, _in10, _in8, _in11, _in9, _in14, _in12, _in15, \ + _in13, _tmp4, _tmp5, _tmp6, _tmp7); \ + DUP2_ARG2(__lsx_vilvl_b, _tmp1, _tmp0, _tmp3, _tmp2, _t0, _t2); \ + DUP2_ARG2(__lsx_vilvh_b, _tmp1, _tmp0, _tmp3, _tmp2, _t1, _t3); \ + DUP2_ARG2(__lsx_vilvl_b, _tmp5, _tmp4, _tmp7, _tmp6, _t4, _t6); \ + DUP2_ARG2(__lsx_vilvh_b, _tmp5, _tmp4, _tmp7, _tmp6, _t5, _t7); \ + DUP2_ARG2(__lsx_vilvl_w, _t2, _t0, _t3, _t1, _tmp0, _tmp4); \ + DUP2_ARG2(__lsx_vilvh_w, _t2, _t0, _t3, _t1, _tmp2, _tmp6); \ + DUP2_ARG2(__lsx_vilvl_w, _t6, _t4, _t7, _t5, _tmp1, _tmp5); \ + DUP2_ARG2(__lsx_vilvh_w, _t6, _t4, _t7, _t5, _tmp3, _tmp7); \ + DUP2_ARG2(__lsx_vilvl_d, _tmp1, _tmp0, _tmp3, _tmp2, _out0, _out2); \ + DUP2_ARG2(__lsx_vilvh_d, _tmp1, _tmp0, _tmp3, _tmp2, _out1, _out3); \ + DUP2_ARG2(__lsx_vilvl_d, _tmp5, _tmp4, _tmp7, _tmp6, _out4, _out6); \ + DUP2_ARG2(__lsx_vilvh_d, _tmp5, _tmp4, _tmp7, _tmp6, _out5, _out7); \ + } + +/* + * ============================================================================= + * Description : Butterfly of 4 input vectors + * Arguments : Inputs - in0, in1, in2, in3 + * Outputs - out0, out1, out2, out3 + * Details : Butterfly operation + * Example : + * out0 = in0 + in3; + * out1 = in1 + in2; + * out2 = in1 - in2; + * out3 = in0 - in3; + * ============================================================================= + */ +#define LSX_BUTTERFLY_4_B(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lsx_vadd_b(_in0, _in3); \ + _out1 = __lsx_vadd_b(_in1, _in2); \ + _out2 = __lsx_vsub_b(_in1, _in2); \ + _out3 = __lsx_vsub_b(_in0, _in3); \ + } +#define LSX_BUTTERFLY_4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lsx_vadd_h(_in0, _in3); \ + _out1 = __lsx_vadd_h(_in1, _in2); \ + _out2 = __lsx_vsub_h(_in1, _in2); \ + _out3 = __lsx_vsub_h(_in0, _in3); \ + } +#define LSX_BUTTERFLY_4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lsx_vadd_w(_in0, _in3); \ + _out1 = __lsx_vadd_w(_in1, _in2); \ + _out2 = __lsx_vsub_w(_in1, _in2); \ + _out3 = __lsx_vsub_w(_in0, _in3); \ + } +#define LSX_BUTTERFLY_4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lsx_vadd_d(_in0, _in3); \ + _out1 = __lsx_vadd_d(_in1, _in2); \ + _out2 = __lsx_vsub_d(_in1, _in2); \ + _out3 = __lsx_vsub_d(_in0, _in3); \ + } + +/* + * ============================================================================= + * Description : Butterfly of 8 input vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3, ~ + * Outputs - _out0, _out1, _out2, _out3, ~ + * Details : Butterfly operation + * Example : + * _out0 = _in0 + _in7; + * _out1 = _in1 + _in6; + * _out2 = _in2 + _in5; + * _out3 = _in3 + _in4; + * _out4 = _in3 - _in4; + * _out5 = _in2 - _in5; + * _out6 = _in1 - _in6; + * _out7 = _in0 - _in7; + * ============================================================================= + */ +#define LSX_BUTTERFLY_8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lsx_vadd_b(_in0, _in7); \ + _out1 = __lsx_vadd_b(_in1, _in6); \ + _out2 = __lsx_vadd_b(_in2, _in5); \ + _out3 = __lsx_vadd_b(_in3, _in4); \ + _out4 = __lsx_vsub_b(_in3, _in4); \ + _out5 = __lsx_vsub_b(_in2, _in5); \ + _out6 = __lsx_vsub_b(_in1, _in6); \ + _out7 = __lsx_vsub_b(_in0, _in7); \ + } + +#define LSX_BUTTERFLY_8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lsx_vadd_h(_in0, _in7); \ + _out1 = __lsx_vadd_h(_in1, _in6); \ + _out2 = __lsx_vadd_h(_in2, _in5); \ + _out3 = __lsx_vadd_h(_in3, _in4); \ + _out4 = __lsx_vsub_h(_in3, _in4); \ + _out5 = __lsx_vsub_h(_in2, _in5); \ + _out6 = __lsx_vsub_h(_in1, _in6); \ + _out7 = __lsx_vsub_h(_in0, _in7); \ + } + +#define LSX_BUTTERFLY_8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lsx_vadd_w(_in0, _in7); \ + _out1 = __lsx_vadd_w(_in1, _in6); \ + _out2 = __lsx_vadd_w(_in2, _in5); \ + _out3 = __lsx_vadd_w(_in3, _in4); \ + _out4 = __lsx_vsub_w(_in3, _in4); \ + _out5 = __lsx_vsub_w(_in2, _in5); \ + _out6 = __lsx_vsub_w(_in1, _in6); \ + _out7 = __lsx_vsub_w(_in0, _in7); \ + } + +#define LSX_BUTTERFLY_8_D(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lsx_vadd_d(_in0, _in7); \ + _out1 = __lsx_vadd_d(_in1, _in6); \ + _out2 = __lsx_vadd_d(_in2, _in5); \ + _out3 = __lsx_vadd_d(_in3, _in4); \ + _out4 = __lsx_vsub_d(_in3, _in4); \ + _out5 = __lsx_vsub_d(_in2, _in5); \ + _out6 = __lsx_vsub_d(_in1, _in6); \ + _out7 = __lsx_vsub_d(_in0, _in7); \ + } + +#endif // LSX + +#ifdef __loongarch_asx +#include +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed halfword + * Details : Unsigned byte elements from in_h are multiplied with + * unsigned byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Then this multiplied results of adjacent odd-even elements + * are added to the out vector + * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2_h_bu(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_h_bu(in_h, in_l); + out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of byte vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed halfword + * Details : Signed byte elements from in_h are multiplied with + * signed byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Then this multiplication results of adjacent odd-even elements + * are added to the out vector + * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2_h_b(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_h_b(in_h, in_l); + out = __lasx_xvmaddwod_h_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed word + * Details : Signed halfword elements from in_h are multiplied with + * signed halfword elements from in_l producing a result + * twice the size of input i.e. signed word. + * Then this multiplied results of adjacent odd-even elements + * are added to the out vector. + * Example : out = __lasx_xvdp2_w_h(in_h, in_l) + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 + * out : 22,38,38,22, 22,38,38,22 + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2_w_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_w_h(in_h, in_l); + out = __lasx_xvmaddwod_w_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of word vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed double + * Details : Signed word elements from in_h are multiplied with + * signed word elements from in_l producing a result + * twice the size of input i.e. signed double-word. + * Then this multiplied results of adjacent odd-even elements + * are added to the out vector. + * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2_d_w(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_d_w(in_h, in_l); + out = __lasx_xvmaddwod_d_w(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed word + * Details : Unsigned halfword elements from in_h are multiplied with + * signed halfword elements from in_l producing a result + * twice the size of input i.e. unsigned word. + * Multiplication result of adjacent odd-even elements + * are added to the out vector + * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2_w_hu_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_w_hu_h(in_h, in_l); + out = __lasx_xvmaddwod_w_hu_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - halfword + * Details : Signed byte elements from in_h are multiplied with + * signed byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Then this multiplied results of adjacent odd-even elements + * are added to the in_c vector. + * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_h_b(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_h_b(in_c, in_h, in_l); + out = __lasx_xvmaddwod_h_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied with + * unsigned byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Then this multiplied results of adjacent odd-even elements + * are added to the in_c vector. + * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_h_bu(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_h_bu(in_c, in_h, in_l); + out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product & addition of byte vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - halfword + * Details : Unsigned byte elements from in_h are multiplied with + * signed byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Then this multiplied results of adjacent odd-even elements + * are added to the in_c vector. + * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_h_bu_b(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_h_bu_b(in_c, in_h, in_l); + out = __lasx_xvmaddwod_h_bu_b(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Return Type - per RTYPE + * Details : Signed halfword elements from in_h are multiplied with + * signed halfword elements from in_l producing a result + * twice the size of input i.e. signed word. + * Multiplication result of adjacent odd-even elements + * are added to the in_c vector. + * Example : out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * in_c : 1,2,3,4, 1,2,3,4 + * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8, + * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1, + * out : 23,40,41,26, 23,40,41,26 + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_w_h(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_w_h(in_c, in_h, in_l); + out = __lasx_xvmaddwod_w_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Return Type - signed word + * Details : Unsigned halfword elements from in_h are multiplied with + * unsigned halfword elements from in_l producing a result + * twice the size of input i.e. signed word. + * Multiplication result of adjacent odd-even elements + * are added to the in_c vector. + * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_w_hu(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_w_hu(in_c, in_h, in_l); + out = __lasx_xvmaddwod_w_hu(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Return Type - signed word + * Details : Unsigned halfword elements from in_h are multiplied with + * signed halfword elements from in_l producing a result + * twice the size of input i.e. signed word. + * Multiplication result of adjacent odd-even elements + * are added to the in_c vector + * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2add_w_hu_h(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmaddwev_w_hu_h(in_c, in_h, in_l); + out = __lasx_xvmaddwod_w_hu_h(out, in_h, in_l); + return out; +} + +/* + * ============================================================================= + * Description : Vector Unsigned Dot Product and Subtract + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Return Type - signed halfword + * Details : Unsigned byte elements from in_h are multiplied with + * unsigned byte elements from in_l producing a result + * twice the size of input i.e. signed halfword. + * Multiplication result of adjacent odd-even elements + * are added together and subtracted from double width elements + * in_c vector. + * Example : See out = __lasx_xvdp2sub_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2sub_h_bu(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_h_bu(in_h, in_l); + out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); + out = __lasx_xvsub_h(in_c, out); + return out; +} + +/* + * ============================================================================= + * Description : Vector Signed Dot Product and Subtract + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Return Type - signed word + * Details : Signed halfword elements from in_h are multiplied with + * Signed halfword elements from in_l producing a result + * twice the size of input i.e. signed word. + * Multiplication result of adjacent odd-even elements + * are added together and subtracted from double width elements + * in_c vector. + * Example : out = __lasx_xvdp2sub_w_h(in_c, in_h, in_l) + * in_c : 0,0,0,0, 0,0,0,0 + * in_h : 3,1,3,0, 0,0,0,1, 0,0,1,1, 0,0,0,1 + * in_l : 2,1,1,0, 1,0,0,0, 0,0,1,0, 1,0,0,1 + * out : -7,-3,0,0, 0,-1,0,-1 + * ============================================================================= + */ +static inline __m256i __lasx_xvdp2sub_w_h(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_w_h(in_h, in_l); + out = __lasx_xvmaddwod_w_h(out, in_h, in_l); + out = __lasx_xvsub_w(in_c, out); + return out; +} + +/* + * ============================================================================= + * Description : Dot product of halfword vector elements + * Arguments : Inputs - in_h, in_l + * Output - out + * Return Type - signed word + * Details : Signed halfword elements from in_h are multiplied with + * signed halfword elements from in_l producing a result + * four times the size of input i.e. signed doubleword. + * Then this multiplication results of four adjacent elements + * are added together and stored to the out vector. + * Example : out = __lasx_xvdp4_d_h(in_h, in_l) + * in_h : 3,1,3,0, 0,0,0,1, 0,0,1,-1, 0,0,0,1 + * in_l : -2,1,1,0, 1,0,0,0, 0,0,1, 0, 1,0,0,1 + * out : -2,0,1,1 + * ============================================================================= + */ +static inline __m256i __lasx_xvdp4_d_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvmulwev_w_h(in_h, in_l); + out = __lasx_xvmaddwod_w_h(out, in_h, in_l); + out = __lasx_xvhaddw_d_w(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The high half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are added after the + * higher half of the two-fold sign extension (signed byte + * to signed halfword) and stored to the out vector. + * Example : See out = __lasx_xvaddwh_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvaddwh_h_b(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvilvh_b(in_h, in_l); + out = __lasx_xvhaddw_h_b(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The high half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are added after the + * higher half of the two-fold sign extension (signed halfword + * to signed word) and stored to the out vector. + * Example : out = __lasx_xvaddwh_w_h(in_h, in_l) + * in_h : 3, 0,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 + * in_l : 2,-1,1,2, 1,0,0, 0, 1,0,1, 0, 1,0,0,1 + * out : 1,0,0,-1, 1,0,0, 2 + * ============================================================================= + */ +static inline __m256i __lasx_xvaddwh_w_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvilvh_h(in_h, in_l); + out = __lasx_xvhaddw_w_h(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are added after the + * lower half of the two-fold sign extension (signed byte + * to signed halfword) and stored to the out vector. + * Example : See out = __lasx_xvaddwl_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvaddwl_h_b(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvilvl_b(in_h, in_l); + out = __lasx_xvhaddw_h_b(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are added after the + * lower half of the two-fold sign extension (signed halfword + * to signed word) and stored to the out vector. + * Example : out = __lasx_xvaddwl_w_h(in_h, in_l) + * in_h : 3, 0,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 + * in_l : 2,-1,1,2, 1,0,0, 0, 1,0,1, 0, 1,0,0,1 + * out : 5,-1,4,2, 1,0,2,-1 + * ============================================================================= + */ +static inline __m256i __lasx_xvaddwl_w_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvilvl_h(in_h, in_l); + out = __lasx_xvhaddw_w_h(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The out vector and the out vector are added after the + * lower half of the two-fold zero extension (unsigned byte + * to unsigned halfword) and stored to the out vector. + * Example : See out = __lasx_xvaddwl_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvaddwl_h_bu(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvilvl_b(in_h, in_l); + out = __lasx_xvhaddw_hu_bu(out, out); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_l vector after double zero extension (unsigned byte to + * signed halfword),added to the in_h vector. + * Example : See out = __lasx_xvaddw_w_w_h(in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvaddw_h_h_bu(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvsllwil_hu_bu(in_l, 0); + out = __lasx_xvadd_h(in_h, out); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are expanded and + * added after being doubled. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_l vector after double sign extension (signed halfword to + * signed word), added to the in_h vector. + * Example : out = __lasx_xvaddw_w_w_h(in_h, in_l) + * in_h : 0, 1,0,0, -1,0,0,1, + * in_l : 2,-1,1,2, 1,0,0,0, 0,0,1,0, 1,0,0,1, + * out : 2, 0,1,2, -1,0,1,1, + * ============================================================================= + */ +static inline __m256i __lasx_xvaddw_w_w_h(__m256i in_h, __m256i in_l) { + __m256i out; + + out = __lasx_xvsllwil_w_h(in_l, 0); + out = __lasx_xvadd_w(in_h, out); + return out; +} + +/* + * ============================================================================= + * Description : Multiplication and addition calculation after expansion + * of the lower half of the vector. + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are multiplied after + * the lower half of the two-fold sign extension (signed halfword + * to signed word), and the result is added to the vector in_c, + * then stored to the out vector. + * Example : out = __lasx_xvmaddwl_w_h(in_c, in_h, in_l) + * in_c : 1,2,3,4, 5,6,7,8 + * in_h : 1,2,3,4, 1,2,3,4, 5,6,7,8, 5,6,7,8 + * in_l : 200, 300, 400, 500, 2000, 3000, 4000, 5000, + * -200,-300,-400,-500, -2000,-3000,-4000,-5000 + * out : 201, 602,1203,2004, -995, -1794,-2793,-3992 + * ============================================================================= + */ +static inline __m256i __lasx_xvmaddwl_w_h(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i tmp0, tmp1, out; + + tmp0 = __lasx_xvsllwil_w_h(in_h, 0); + tmp1 = __lasx_xvsllwil_w_h(in_l, 0); + tmp0 = __lasx_xvmul_w(tmp0, tmp1); + out = __lasx_xvadd_w(tmp0, in_c); + return out; +} + +/* + * ============================================================================= + * Description : Multiplication and addition calculation after expansion + * of the higher half of the vector. + * Arguments : Inputs - in_c, in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are multiplied after + * the higher half of the two-fold sign extension (signed + * halfword to signed word), and the result is added to + * the vector in_c, then stored to the out vector. + * Example : See out = __lasx_xvmaddwl_w_h(in_c, in_h, in_l) + * ============================================================================= + */ +static inline __m256i __lasx_xvmaddwh_w_h(__m256i in_c, __m256i in_h, + __m256i in_l) { + __m256i tmp0, tmp1, out; + + tmp0 = __lasx_xvilvh_h(in_h, in_h); + tmp1 = __lasx_xvilvh_h(in_l, in_l); + tmp0 = __lasx_xvmulwev_w_h(tmp0, tmp1); + out = __lasx_xvadd_w(tmp0, in_c); + return out; +} + +/* + * ============================================================================= + * Description : Multiplication calculation after expansion of the lower + * half of the vector. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are multiplied after + * the lower half of the two-fold sign extension (signed + * halfword to signed word), then stored to the out vector. + * Example : out = __lasx_xvmulwl_w_h(in_h, in_l) + * in_h : 3,-1,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 + * in_l : 2,-1,1,2, 1,0,0, 0, 0,0,1, 0, 1,0,0,1 + * out : 6,1,3,0, 0,0,1,0 + * ============================================================================= + */ +static inline __m256i __lasx_xvmulwl_w_h(__m256i in_h, __m256i in_l) { + __m256i tmp0, tmp1, out; + + tmp0 = __lasx_xvsllwil_w_h(in_h, 0); + tmp1 = __lasx_xvsllwil_w_h(in_l, 0); + out = __lasx_xvmul_w(tmp0, tmp1); + return out; +} + +/* + * ============================================================================= + * Description : Multiplication calculation after expansion of the lower + * half of the vector. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector and the in_l vector are multiplied after + * the lower half of the two-fold sign extension (signed + * halfword to signed word), then stored to the out vector. + * Example : out = __lasx_xvmulwh_w_h(in_h, in_l) + * in_h : 3,-1,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 + * in_l : 2,-1,1,2, 1,0,0, 0, 0,0,1, 0, 1,0,0,1 + * out : 0,0,0,0, 0,0,0,1 + * ============================================================================= + */ +static inline __m256i __lasx_xvmulwh_w_h(__m256i in_h, __m256i in_l) { + __m256i tmp0, tmp1, out; + + tmp0 = __lasx_xvilvh_h(in_h, in_h); + tmp1 = __lasx_xvilvh_h(in_l, in_l); + out = __lasx_xvmulwev_w_h(tmp0, tmp1); + return out; +} + +/* + * ============================================================================= + * Description : The low half of the vector elements are added to the high half + * after being doubled, then saturated. + * Arguments : Inputs - in_h, in_l + * Output - out + * Details : The in_h vector adds the in_l vector after the lower half of + * the two-fold zero extension (unsigned byte to unsigned + * halfword) and then saturated. The results are stored to the out + * vector. + * Example : out = __lasx_xvsaddw_hu_hu_bu(in_h, in_l) + * in_h : 2,65532,1,2, 1,0,0,0, 0,0,1,0, 1,0,0,1 + * in_l : 3,6,3,0, 0,0,0,1, 0,0,1,1, 0,0,0,1, 3,18,3,0, 0,0,0,1, 0,0,1,1, + * 0,0,0,1 + * out : 5,65535,4,2, 1,0,0,1, 3,18,4,0, 1,0,0,2, + * ============================================================================= + */ +static inline __m256i __lasx_xvsaddw_hu_hu_bu(__m256i in_h, __m256i in_l) { + __m256i tmp1, out; + __m256i zero = { 0 }; + + tmp1 = __lasx_xvilvl_b(zero, in_l); + out = __lasx_xvsadd_hu(in_h, tmp1); + return out; +} + +/* + * ============================================================================= + * Description : Clip all halfword elements of input vector between min & max + * out = ((in) < (min)) ? (min) : (((in) > (max)) ? (max) : (in)) + * Arguments : Inputs - in (input vector) + * - min (min threshold) + * - max (max threshold) + * Outputs - in (output vector with clipped elements) + * Return Type - signed halfword + * Example : out = __lasx_xvclip_h(in, min, max) + * in : -8,2,280,249, -8,255,280,249, 4,4,4,4, 5,5,5,5 + * min : 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 + * max : 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9 + * out : 1,2,9,9, 1,9,9,9, 4,4,4,4, 5,5,5,5 + * ============================================================================= + */ +static inline __m256i __lasx_xvclip_h(__m256i in, __m256i min, __m256i max) { + __m256i out; + + out = __lasx_xvmax_h(min, in); + out = __lasx_xvmin_h(max, out); + return out; +} + +/* + * ============================================================================= + * Description : Clip all signed halfword elements of input vector + * between 0 & 255 + * Arguments : Inputs - in (input vector) + * Outputs - out (output vector with clipped elements) + * Return Type - signed halfword + * Example : See out = __lasx_xvclip255_w(in) + * ============================================================================= + */ +static inline __m256i __lasx_xvclip255_h(__m256i in) { + __m256i out; + + out = __lasx_xvmaxi_h(in, 0); + out = __lasx_xvsat_hu(out, 7); + return out; +} + +/* + * ============================================================================= + * Description : Clip all signed word elements of input vector + * between 0 & 255 + * Arguments : Inputs - in (input vector) + * Output - out (output vector with clipped elements) + * Return Type - signed word + * Example : out = __lasx_xvclip255_w(in) + * in : -8,255,280,249, -8,255,280,249 + * out : 0,255,255,249, 0,255,255,249 + * ============================================================================= + */ +static inline __m256i __lasx_xvclip255_w(__m256i in) { + __m256i out; + + out = __lasx_xvmaxi_w(in, 0); + out = __lasx_xvsat_wu(out, 7); + return out; +} + +/* + * ============================================================================= + * Description : Indexed halfword element values are replicated to all + * elements in output vector. If 'idx < 8' use xvsplati_l_*, + * if 'idx >= 8' use xvsplati_h_*. + * Arguments : Inputs - in, idx + * Output - out + * Details : Idx element value from in vector is replicated to all + * elements in out vector. + * Valid index range for halfword operation is 0-7 + * Example : out = __lasx_xvsplati_l_h(in, idx) + * in : 20,10,11,12, 13,14,15,16, 0,0,2,0, 0,0,0,0 + * idx : 0x02 + * out : 11,11,11,11, 11,11,11,11, 11,11,11,11, 11,11,11,11 + * ============================================================================= + */ +static inline __m256i __lasx_xvsplati_l_h(__m256i in, int idx) { + __m256i out; + + out = __lasx_xvpermi_q(in, in, 0x02); + out = __lasx_xvreplve_h(out, idx); + return out; +} + +/* + * ============================================================================= + * Description : Indexed halfword element values are replicated to all + * elements in output vector. If 'idx < 8' use xvsplati_l_*, + * if 'idx >= 8' use xvsplati_h_*. + * Arguments : Inputs - in, idx + * Output - out + * Details : Idx element value from in vector is replicated to all + * elements in out vector. + * Valid index range for halfword operation is 0-7 + * Example : out = __lasx_xvsplati_h_h(in, idx) + * in : 20,10,11,12, 13,14,15,16, 0,2,0,0, 0,0,0,0 + * idx : 0x09 + * out : 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2 + * ============================================================================= + */ +static inline __m256i __lasx_xvsplati_h_h(__m256i in, int idx) { + __m256i out; + + out = __lasx_xvpermi_q(in, in, 0x13); + out = __lasx_xvreplve_h(out, idx); + return out; +} + +/* + * ============================================================================= + * Description : Transpose 4x4 block with double-word elements in vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3 + * Outputs - _out0, _out1, _out2, _out3 + * Example : LASX_TRANSPOSE4x4_D + * _in0 : 1,2,3,4 + * _in1 : 1,2,3,4 + * _in2 : 1,2,3,4 + * _in3 : 1,2,3,4 + * + * _out0 : 1,1,1,1 + * _out1 : 2,2,2,2 + * _out2 : 3,3,3,3 + * _out3 : 4,4,4,4 + * ============================================================================= + */ +#define LASX_TRANSPOSE4x4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, \ + _out3) \ + { \ + __m256i _tmp0, _tmp1, _tmp2, _tmp3; \ + _tmp0 = __lasx_xvilvl_d(_in1, _in0); \ + _tmp1 = __lasx_xvilvh_d(_in1, _in0); \ + _tmp2 = __lasx_xvilvl_d(_in3, _in2); \ + _tmp3 = __lasx_xvilvh_d(_in3, _in2); \ + _out0 = __lasx_xvpermi_q(_tmp2, _tmp0, 0x20); \ + _out2 = __lasx_xvpermi_q(_tmp2, _tmp0, 0x31); \ + _out1 = __lasx_xvpermi_q(_tmp3, _tmp1, 0x20); \ + _out3 = __lasx_xvpermi_q(_tmp3, _tmp1, 0x31); \ + } + +/* + * ============================================================================= + * Description : Transpose 8x8 block with word elements in vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 + * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, + * _out7 + * Example : LASX_TRANSPOSE8x8_W + * _in0 : 1,2,3,4,5,6,7,8 + * _in1 : 2,2,3,4,5,6,7,8 + * _in2 : 3,2,3,4,5,6,7,8 + * _in3 : 4,2,3,4,5,6,7,8 + * _in4 : 5,2,3,4,5,6,7,8 + * _in5 : 6,2,3,4,5,6,7,8 + * _in6 : 7,2,3,4,5,6,7,8 + * _in7 : 8,2,3,4,5,6,7,8 + * + * _out0 : 1,2,3,4,5,6,7,8 + * _out1 : 2,2,2,2,2,2,2,2 + * _out2 : 3,3,3,3,3,3,3,3 + * _out3 : 4,4,4,4,4,4,4,4 + * _out4 : 5,5,5,5,5,5,5,5 + * _out5 : 6,6,6,6,6,6,6,6 + * _out6 : 7,7,7,7,7,7,7,7 + * _out7 : 8,8,8,8,8,8,8,8 + * ============================================================================= + */ +#define LASX_TRANSPOSE8x8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + __m256i _s0_m, _s1_m; \ + __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ + \ + _s0_m = __lasx_xvilvl_w(_in2, _in0); \ + _s1_m = __lasx_xvilvl_w(_in3, _in1); \ + _tmp0_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ + _tmp1_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ + _s0_m = __lasx_xvilvh_w(_in2, _in0); \ + _s1_m = __lasx_xvilvh_w(_in3, _in1); \ + _tmp2_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ + _tmp3_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ + _s0_m = __lasx_xvilvl_w(_in6, _in4); \ + _s1_m = __lasx_xvilvl_w(_in7, _in5); \ + _tmp4_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ + _tmp5_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ + _s0_m = __lasx_xvilvh_w(_in6, _in4); \ + _s1_m = __lasx_xvilvh_w(_in7, _in5); \ + _tmp6_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ + _tmp7_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ + _out0 = __lasx_xvpermi_q(_tmp4_m, _tmp0_m, 0x20); \ + _out1 = __lasx_xvpermi_q(_tmp5_m, _tmp1_m, 0x20); \ + _out2 = __lasx_xvpermi_q(_tmp6_m, _tmp2_m, 0x20); \ + _out3 = __lasx_xvpermi_q(_tmp7_m, _tmp3_m, 0x20); \ + _out4 = __lasx_xvpermi_q(_tmp4_m, _tmp0_m, 0x31); \ + _out5 = __lasx_xvpermi_q(_tmp5_m, _tmp1_m, 0x31); \ + _out6 = __lasx_xvpermi_q(_tmp6_m, _tmp2_m, 0x31); \ + _out7 = __lasx_xvpermi_q(_tmp7_m, _tmp3_m, 0x31); \ + } + +/* + * ============================================================================= + * Description : Transpose input 16x8 byte block + * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, + * _in8, _in9, _in10, _in11, _in12, _in13, _in14, _in15 + * (input 16x8 byte block) + * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, + * _out7 (output 8x16 byte block) + * Details : The rows of the matrix become columns, and the columns become + * rows. + * Example : See LASX_TRANSPOSE16x8_H + * ============================================================================= + */ +#define LASX_TRANSPOSE16x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ + _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ + _out6, _out7) \ + { \ + __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ + \ + _tmp0_m = __lasx_xvilvl_b(_in2, _in0); \ + _tmp1_m = __lasx_xvilvl_b(_in3, _in1); \ + _tmp2_m = __lasx_xvilvl_b(_in6, _in4); \ + _tmp3_m = __lasx_xvilvl_b(_in7, _in5); \ + _tmp4_m = __lasx_xvilvl_b(_in10, _in8); \ + _tmp5_m = __lasx_xvilvl_b(_in11, _in9); \ + _tmp6_m = __lasx_xvilvl_b(_in14, _in12); \ + _tmp7_m = __lasx_xvilvl_b(_in15, _in13); \ + _out0 = __lasx_xvilvl_b(_tmp1_m, _tmp0_m); \ + _out1 = __lasx_xvilvh_b(_tmp1_m, _tmp0_m); \ + _out2 = __lasx_xvilvl_b(_tmp3_m, _tmp2_m); \ + _out3 = __lasx_xvilvh_b(_tmp3_m, _tmp2_m); \ + _out4 = __lasx_xvilvl_b(_tmp5_m, _tmp4_m); \ + _out5 = __lasx_xvilvh_b(_tmp5_m, _tmp4_m); \ + _out6 = __lasx_xvilvl_b(_tmp7_m, _tmp6_m); \ + _out7 = __lasx_xvilvh_b(_tmp7_m, _tmp6_m); \ + _tmp0_m = __lasx_xvilvl_w(_out2, _out0); \ + _tmp2_m = __lasx_xvilvh_w(_out2, _out0); \ + _tmp4_m = __lasx_xvilvl_w(_out3, _out1); \ + _tmp6_m = __lasx_xvilvh_w(_out3, _out1); \ + _tmp1_m = __lasx_xvilvl_w(_out6, _out4); \ + _tmp3_m = __lasx_xvilvh_w(_out6, _out4); \ + _tmp5_m = __lasx_xvilvl_w(_out7, _out5); \ + _tmp7_m = __lasx_xvilvh_w(_out7, _out5); \ + _out0 = __lasx_xvilvl_d(_tmp1_m, _tmp0_m); \ + _out1 = __lasx_xvilvh_d(_tmp1_m, _tmp0_m); \ + _out2 = __lasx_xvilvl_d(_tmp3_m, _tmp2_m); \ + _out3 = __lasx_xvilvh_d(_tmp3_m, _tmp2_m); \ + _out4 = __lasx_xvilvl_d(_tmp5_m, _tmp4_m); \ + _out5 = __lasx_xvilvh_d(_tmp5_m, _tmp4_m); \ + _out6 = __lasx_xvilvl_d(_tmp7_m, _tmp6_m); \ + _out7 = __lasx_xvilvh_d(_tmp7_m, _tmp6_m); \ + } + +/* + * ============================================================================= + * Description : Transpose input 16x8 byte block + * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, + * _in8, _in9, _in10, _in11, _in12, _in13, _in14, _in15 + * (input 16x8 byte block) + * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, + * _out7 (output 8x16 byte block) + * Details : The rows of the matrix become columns, and the columns become + * rows. + * Example : LASX_TRANSPOSE16x8_H + * _in0 : 1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in1 : 2,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in2 : 3,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in3 : 4,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in4 : 5,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in5 : 6,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in6 : 7,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in7 : 8,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in8 : 9,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in9 : 1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in10 : 0,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in11 : 2,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in12 : 3,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in13 : 7,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in14 : 5,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * _in15 : 6,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 + * + * _out0 : 1,2,3,4,5,6,7,8,9,1,0,2,3,7,5,6 + * _out1 : 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 + * _out2 : 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + * _out3 : 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 + * _out4 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 + * _out5 : 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 + * _out6 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + * _out7 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + * ============================================================================= + */ +#define LASX_TRANSPOSE16x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ + _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ + _out6, _out7) \ + { \ + __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ + __m256i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ + \ + _tmp0_m = __lasx_xvilvl_h(_in2, _in0); \ + _tmp1_m = __lasx_xvilvl_h(_in3, _in1); \ + _tmp2_m = __lasx_xvilvl_h(_in6, _in4); \ + _tmp3_m = __lasx_xvilvl_h(_in7, _in5); \ + _tmp4_m = __lasx_xvilvl_h(_in10, _in8); \ + _tmp5_m = __lasx_xvilvl_h(_in11, _in9); \ + _tmp6_m = __lasx_xvilvl_h(_in14, _in12); \ + _tmp7_m = __lasx_xvilvl_h(_in15, _in13); \ + _t0 = __lasx_xvilvl_h(_tmp1_m, _tmp0_m); \ + _t1 = __lasx_xvilvh_h(_tmp1_m, _tmp0_m); \ + _t2 = __lasx_xvilvl_h(_tmp3_m, _tmp2_m); \ + _t3 = __lasx_xvilvh_h(_tmp3_m, _tmp2_m); \ + _t4 = __lasx_xvilvl_h(_tmp5_m, _tmp4_m); \ + _t5 = __lasx_xvilvh_h(_tmp5_m, _tmp4_m); \ + _t6 = __lasx_xvilvl_h(_tmp7_m, _tmp6_m); \ + _t7 = __lasx_xvilvh_h(_tmp7_m, _tmp6_m); \ + _tmp0_m = __lasx_xvilvl_d(_t2, _t0); \ + _tmp2_m = __lasx_xvilvh_d(_t2, _t0); \ + _tmp4_m = __lasx_xvilvl_d(_t3, _t1); \ + _tmp6_m = __lasx_xvilvh_d(_t3, _t1); \ + _tmp1_m = __lasx_xvilvl_d(_t6, _t4); \ + _tmp3_m = __lasx_xvilvh_d(_t6, _t4); \ + _tmp5_m = __lasx_xvilvl_d(_t7, _t5); \ + _tmp7_m = __lasx_xvilvh_d(_t7, _t5); \ + _out0 = __lasx_xvpermi_q(_tmp1_m, _tmp0_m, 0x20); \ + _out1 = __lasx_xvpermi_q(_tmp3_m, _tmp2_m, 0x20); \ + _out2 = __lasx_xvpermi_q(_tmp5_m, _tmp4_m, 0x20); \ + _out3 = __lasx_xvpermi_q(_tmp7_m, _tmp6_m, 0x20); \ + \ + _tmp0_m = __lasx_xvilvh_h(_in2, _in0); \ + _tmp1_m = __lasx_xvilvh_h(_in3, _in1); \ + _tmp2_m = __lasx_xvilvh_h(_in6, _in4); \ + _tmp3_m = __lasx_xvilvh_h(_in7, _in5); \ + _tmp4_m = __lasx_xvilvh_h(_in10, _in8); \ + _tmp5_m = __lasx_xvilvh_h(_in11, _in9); \ + _tmp6_m = __lasx_xvilvh_h(_in14, _in12); \ + _tmp7_m = __lasx_xvilvh_h(_in15, _in13); \ + _t0 = __lasx_xvilvl_h(_tmp1_m, _tmp0_m); \ + _t1 = __lasx_xvilvh_h(_tmp1_m, _tmp0_m); \ + _t2 = __lasx_xvilvl_h(_tmp3_m, _tmp2_m); \ + _t3 = __lasx_xvilvh_h(_tmp3_m, _tmp2_m); \ + _t4 = __lasx_xvilvl_h(_tmp5_m, _tmp4_m); \ + _t5 = __lasx_xvilvh_h(_tmp5_m, _tmp4_m); \ + _t6 = __lasx_xvilvl_h(_tmp7_m, _tmp6_m); \ + _t7 = __lasx_xvilvh_h(_tmp7_m, _tmp6_m); \ + _tmp0_m = __lasx_xvilvl_d(_t2, _t0); \ + _tmp2_m = __lasx_xvilvh_d(_t2, _t0); \ + _tmp4_m = __lasx_xvilvl_d(_t3, _t1); \ + _tmp6_m = __lasx_xvilvh_d(_t3, _t1); \ + _tmp1_m = __lasx_xvilvl_d(_t6, _t4); \ + _tmp3_m = __lasx_xvilvh_d(_t6, _t4); \ + _tmp5_m = __lasx_xvilvl_d(_t7, _t5); \ + _tmp7_m = __lasx_xvilvh_d(_t7, _t5); \ + _out4 = __lasx_xvpermi_q(_tmp1_m, _tmp0_m, 0x20); \ + _out5 = __lasx_xvpermi_q(_tmp3_m, _tmp2_m, 0x20); \ + _out6 = __lasx_xvpermi_q(_tmp5_m, _tmp4_m, 0x20); \ + _out7 = __lasx_xvpermi_q(_tmp7_m, _tmp6_m, 0x20); \ + } + +/* + * ============================================================================= + * Description : Transpose 4x4 block with halfword elements in vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3 + * Outputs - _out0, _out1, _out2, _out3 + * Return Type - signed halfword + * Details : The rows of the matrix become columns, and the columns become + * rows. + * Example : See LASX_TRANSPOSE8x8_H + * ============================================================================= + */ +#define LASX_TRANSPOSE4x4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, \ + _out3) \ + { \ + __m256i _s0_m, _s1_m; \ + \ + _s0_m = __lasx_xvilvl_h(_in1, _in0); \ + _s1_m = __lasx_xvilvl_h(_in3, _in2); \ + _out0 = __lasx_xvilvl_w(_s1_m, _s0_m); \ + _out2 = __lasx_xvilvh_w(_s1_m, _s0_m); \ + _out1 = __lasx_xvilvh_d(_out0, _out0); \ + _out3 = __lasx_xvilvh_d(_out2, _out2); \ + } + +/* + * ============================================================================= + * Description : Transpose input 8x8 byte block + * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 + * (input 8x8 byte block) + * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, + * _out7 (output 8x8 byte block) + * Example : See LASX_TRANSPOSE8x8_H + * ============================================================================= + */ +#define LASX_TRANSPOSE8x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ + _tmp0_m = __lasx_xvilvl_b(_in2, _in0); \ + _tmp1_m = __lasx_xvilvl_b(_in3, _in1); \ + _tmp2_m = __lasx_xvilvl_b(_in6, _in4); \ + _tmp3_m = __lasx_xvilvl_b(_in7, _in5); \ + _tmp4_m = __lasx_xvilvl_b(_tmp1_m, _tmp0_m); \ + _tmp5_m = __lasx_xvilvh_b(_tmp1_m, _tmp0_m); \ + _tmp6_m = __lasx_xvilvl_b(_tmp3_m, _tmp2_m); \ + _tmp7_m = __lasx_xvilvh_b(_tmp3_m, _tmp2_m); \ + _out0 = __lasx_xvilvl_w(_tmp6_m, _tmp4_m); \ + _out2 = __lasx_xvilvh_w(_tmp6_m, _tmp4_m); \ + _out4 = __lasx_xvilvl_w(_tmp7_m, _tmp5_m); \ + _out6 = __lasx_xvilvh_w(_tmp7_m, _tmp5_m); \ + _out1 = __lasx_xvbsrl_v(_out0, 8); \ + _out3 = __lasx_xvbsrl_v(_out2, 8); \ + _out5 = __lasx_xvbsrl_v(_out4, 8); \ + _out7 = __lasx_xvbsrl_v(_out6, 8); \ + } + +/* + * ============================================================================= + * Description : Transpose 8x8 block with halfword elements in vectors. + * Arguments : Inputs - _in0, _in1, ~ + * Outputs - _out0, _out1, ~ + * Details : The rows of the matrix become columns, and the columns become + * rows. + * Example : LASX_TRANSPOSE8x8_H + * _in0 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * _in1 : 8,2,3,4, 5,6,7,8, 8,2,3,4, 5,6,7,8 + * _in2 : 8,2,3,4, 5,6,7,8, 8,2,3,4, 5,6,7,8 + * _in3 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * _in4 : 9,2,3,4, 5,6,7,8, 9,2,3,4, 5,6,7,8 + * _in5 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * _in6 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 + * _in7 : 9,2,3,4, 5,6,7,8, 9,2,3,4, 5,6,7,8 + * + * _out0 : 1,8,8,1, 9,1,1,9, 1,8,8,1, 9,1,1,9 + * _out1 : 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2 + * _out2 : 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3 + * _out3 : 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4 + * _out4 : 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5 + * _out5 : 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6 + * _out6 : 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7 + * _out7 : 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8 + * ============================================================================= + */ +#define LASX_TRANSPOSE8x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + __m256i _s0_m, _s1_m; \ + __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ + __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ + \ + _s0_m = __lasx_xvilvl_h(_in6, _in4); \ + _s1_m = __lasx_xvilvl_h(_in7, _in5); \ + _tmp0_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ + _tmp1_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ + _s0_m = __lasx_xvilvh_h(_in6, _in4); \ + _s1_m = __lasx_xvilvh_h(_in7, _in5); \ + _tmp2_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ + _tmp3_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ + \ + _s0_m = __lasx_xvilvl_h(_in2, _in0); \ + _s1_m = __lasx_xvilvl_h(_in3, _in1); \ + _tmp4_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ + _tmp5_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ + _s0_m = __lasx_xvilvh_h(_in2, _in0); \ + _s1_m = __lasx_xvilvh_h(_in3, _in1); \ + _tmp6_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ + _tmp7_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ + \ + _out0 = __lasx_xvpickev_d(_tmp0_m, _tmp4_m); \ + _out2 = __lasx_xvpickev_d(_tmp1_m, _tmp5_m); \ + _out4 = __lasx_xvpickev_d(_tmp2_m, _tmp6_m); \ + _out6 = __lasx_xvpickev_d(_tmp3_m, _tmp7_m); \ + _out1 = __lasx_xvpickod_d(_tmp0_m, _tmp4_m); \ + _out3 = __lasx_xvpickod_d(_tmp1_m, _tmp5_m); \ + _out5 = __lasx_xvpickod_d(_tmp2_m, _tmp6_m); \ + _out7 = __lasx_xvpickod_d(_tmp3_m, _tmp7_m); \ + } + +/* + * ============================================================================= + * Description : Butterfly of 4 input vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3 + * Outputs - _out0, _out1, _out2, _out3 + * Details : Butterfly operation + * Example : LASX_BUTTERFLY_4 + * _out0 = _in0 + _in3; + * _out1 = _in1 + _in2; + * _out2 = _in1 - _in2; + * _out3 = _in0 - _in3; + * ============================================================================= + */ +#define LASX_BUTTERFLY_4_B(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lasx_xvadd_b(_in0, _in3); \ + _out1 = __lasx_xvadd_b(_in1, _in2); \ + _out2 = __lasx_xvsub_b(_in1, _in2); \ + _out3 = __lasx_xvsub_b(_in0, _in3); \ + } +#define LASX_BUTTERFLY_4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lasx_xvadd_h(_in0, _in3); \ + _out1 = __lasx_xvadd_h(_in1, _in2); \ + _out2 = __lasx_xvsub_h(_in1, _in2); \ + _out3 = __lasx_xvsub_h(_in0, _in3); \ + } +#define LASX_BUTTERFLY_4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lasx_xvadd_w(_in0, _in3); \ + _out1 = __lasx_xvadd_w(_in1, _in2); \ + _out2 = __lasx_xvsub_w(_in1, _in2); \ + _out3 = __lasx_xvsub_w(_in0, _in3); \ + } +#define LASX_BUTTERFLY_4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ + { \ + _out0 = __lasx_xvadd_d(_in0, _in3); \ + _out1 = __lasx_xvadd_d(_in1, _in2); \ + _out2 = __lasx_xvsub_d(_in1, _in2); \ + _out3 = __lasx_xvsub_d(_in0, _in3); \ + } + +/* + * ============================================================================= + * Description : Butterfly of 8 input vectors + * Arguments : Inputs - _in0, _in1, _in2, _in3, ~ + * Outputs - _out0, _out1, _out2, _out3, ~ + * Details : Butterfly operation + * Example : LASX_BUTTERFLY_8 + * _out0 = _in0 + _in7; + * _out1 = _in1 + _in6; + * _out2 = _in2 + _in5; + * _out3 = _in3 + _in4; + * _out4 = _in3 - _in4; + * _out5 = _in2 - _in5; + * _out6 = _in1 - _in6; + * _out7 = _in0 - _in7; + * ============================================================================= + */ +#define LASX_BUTTERFLY_8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lasx_xvadd_b(_in0, _in7); \ + _out1 = __lasx_xvadd_b(_in1, _in6); \ + _out2 = __lasx_xvadd_b(_in2, _in5); \ + _out3 = __lasx_xvadd_b(_in3, _in4); \ + _out4 = __lasx_xvsub_b(_in3, _in4); \ + _out5 = __lasx_xvsub_b(_in2, _in5); \ + _out6 = __lasx_xvsub_b(_in1, _in6); \ + _out7 = __lasx_xvsub_b(_in0, _in7); \ + } + +#define LASX_BUTTERFLY_8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lasx_xvadd_h(_in0, _in7); \ + _out1 = __lasx_xvadd_h(_in1, _in6); \ + _out2 = __lasx_xvadd_h(_in2, _in5); \ + _out3 = __lasx_xvadd_h(_in3, _in4); \ + _out4 = __lasx_xvsub_h(_in3, _in4); \ + _out5 = __lasx_xvsub_h(_in2, _in5); \ + _out6 = __lasx_xvsub_h(_in1, _in6); \ + _out7 = __lasx_xvsub_h(_in0, _in7); \ + } + +#define LASX_BUTTERFLY_8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lasx_xvadd_w(_in0, _in7); \ + _out1 = __lasx_xvadd_w(_in1, _in6); \ + _out2 = __lasx_xvadd_w(_in2, _in5); \ + _out3 = __lasx_xvadd_w(_in3, _in4); \ + _out4 = __lasx_xvsub_w(_in3, _in4); \ + _out5 = __lasx_xvsub_w(_in2, _in5); \ + _out6 = __lasx_xvsub_w(_in1, _in6); \ + _out7 = __lasx_xvsub_w(_in0, _in7); \ + } + +#define LASX_BUTTERFLY_8_D(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ + _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ + _out7) \ + { \ + _out0 = __lasx_xvadd_d(_in0, _in7); \ + _out1 = __lasx_xvadd_d(_in1, _in6); \ + _out2 = __lasx_xvadd_d(_in2, _in5); \ + _out3 = __lasx_xvadd_d(_in3, _in4); \ + _out4 = __lasx_xvsub_d(_in3, _in4); \ + _out5 = __lasx_xvsub_d(_in2, _in5); \ + _out6 = __lasx_xvsub_d(_in1, _in6); \ + _out7 = __lasx_xvsub_d(_in0, _in7); \ + } + +#endif // LASX + +/* + * ============================================================================= + * Description : Print out elements in vector. + * Arguments : Inputs - RTYPE, _element_num, _in0, _enter + * Outputs - + * Details : Print out '_element_num' elements in 'RTYPE' vector '_in0', if + * '_enter' is TRUE, prefix "\nVP:" will be added first. + * Example : VECT_PRINT(v4i32,4,in0,1); // in0: 1,2,3,4 + * VP:1,2,3,4, + * ============================================================================= + */ +#define VECT_PRINT(RTYPE, element_num, in0, enter) \ + { \ + RTYPE _tmp0 = (RTYPE)in0; \ + int _i = 0; \ + if (enter) printf("\nVP:"); \ + for (_i = 0; _i < element_num; _i++) printf("%d,", _tmp0[_i]); \ + } + +#endif /* LOONGSON_INTRINSICS_H */ +#endif /* AVUTIL_LOONGARCH_LOONGSON_INTRINSICS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lzo.c b/arm/raspi/third_party/ffmpeg/libavutil/lzo.c new file mode 100644 index 00000000..bcbe2c86 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lzo.c @@ -0,0 +1,207 @@ +/* + * LZO 1x decompression + * Copyright (c) 2006 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "avassert.h" +#include "intreadwrite.h" +#include "lzo.h" +#include "macros.h" +#include "mem.h" + +/// Define if we may write up to 12 bytes beyond the output buffer. +#define OUTBUF_PADDED 1 +/// Define if we may read up to 8 bytes beyond the input buffer. +#define INBUF_PADDED 1 + +typedef struct LZOContext { + const uint8_t *in, *in_end; + uint8_t *out_start, *out, *out_end; + int error; +} LZOContext; + +/** + * @brief Reads one byte from the input buffer, avoiding an overrun. + * @return byte read + */ +static inline int get_byte(LZOContext *c) +{ + if (c->in < c->in_end) + return *c->in++; + c->error |= AV_LZO_INPUT_DEPLETED; + return 1; +} + +#ifdef INBUF_PADDED +#define GETB(c) (*(c).in++) +#else +#define GETB(c) get_byte(&(c)) +#endif + +/** + * @brief Decodes a length value in the coding used by lzo. + * @param x previous byte value + * @param mask bits used from x + * @return decoded length value + */ +static inline int get_len(LZOContext *c, int x, int mask) +{ + int cnt = x & mask; + if (!cnt) { + while (!(x = get_byte(c))) { + if (cnt >= INT_MAX - 1000) { + c->error |= AV_LZO_ERROR; + break; + } + cnt += 255; + } + cnt += mask + x; + } + return cnt; +} + +/** + * @brief Copies bytes from input to output buffer with checking. + * @param cnt number of bytes to copy, must be >= 0 + */ +static inline void copy(LZOContext *c, int cnt) +{ + register const uint8_t *src = c->in; + register uint8_t *dst = c->out; + av_assert0(cnt >= 0); + if (cnt > c->in_end - src) { + cnt = FFMAX(c->in_end - src, 0); + c->error |= AV_LZO_INPUT_DEPLETED; + } + if (cnt > c->out_end - dst) { + cnt = FFMAX(c->out_end - dst, 0); + c->error |= AV_LZO_OUTPUT_FULL; + } +#if defined(INBUF_PADDED) && defined(OUTBUF_PADDED) + AV_COPY32U(dst, src); + src += 4; + dst += 4; + cnt -= 4; + if (cnt > 0) +#endif + memcpy(dst, src, cnt); + c->in = src + cnt; + c->out = dst + cnt; +} + +/** + * @brief Copies previously decoded bytes to current position. + * @param back how many bytes back we start, must be > 0 + * @param cnt number of bytes to copy, must be > 0 + * + * cnt > back is valid, this will copy the bytes we just copied, + * thus creating a repeating pattern with a period length of back. + */ +static inline void copy_backptr(LZOContext *c, int back, int cnt) +{ + register uint8_t *dst = c->out; + av_assert0(cnt > 0); + if (dst - c->out_start < back) { + c->error |= AV_LZO_INVALID_BACKPTR; + return; + } + if (cnt > c->out_end - dst) { + cnt = FFMAX(c->out_end - dst, 0); + c->error |= AV_LZO_OUTPUT_FULL; + } + av_memcpy_backptr(dst, back, cnt); + c->out = dst + cnt; +} + +int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen) +{ + int state = 0; + int x; + LZOContext c; + if (*outlen <= 0 || *inlen <= 0) { + int res = 0; + if (*outlen <= 0) + res |= AV_LZO_OUTPUT_FULL; + if (*inlen <= 0) + res |= AV_LZO_INPUT_DEPLETED; + return res; + } + c.in = in; + c.in_end = (const uint8_t *)in + *inlen; + c.out = c.out_start = out; + c.out_end = (uint8_t *)out + *outlen; + c.error = 0; + x = GETB(c); + if (x > 17) { + copy(&c, x - 17); + x = GETB(c); + if (x < 16) + c.error |= AV_LZO_ERROR; + } + if (c.in > c.in_end) + c.error |= AV_LZO_INPUT_DEPLETED; + while (!c.error) { + int cnt, back; + if (x > 15) { + if (x > 63) { + cnt = (x >> 5) - 1; + back = (GETB(c) << 3) + ((x >> 2) & 7) + 1; + } else if (x > 31) { + cnt = get_len(&c, x, 31); + x = GETB(c); + back = (GETB(c) << 6) + (x >> 2) + 1; + } else { + cnt = get_len(&c, x, 7); + back = (1 << 14) + ((x & 8) << 11); + x = GETB(c); + back += (GETB(c) << 6) + (x >> 2); + if (back == (1 << 14)) { + if (cnt != 1) + c.error |= AV_LZO_ERROR; + break; + } + } + } else if (!state) { + cnt = get_len(&c, x, 15); + copy(&c, cnt + 3); + x = GETB(c); + if (x > 15) + continue; + cnt = 1; + back = (1 << 11) + (GETB(c) << 2) + (x >> 2) + 1; + } else { + cnt = 0; + back = (GETB(c) << 2) + (x >> 2) + 1; + } + copy_backptr(&c, back, cnt + 2); + state = + cnt = x & 3; + copy(&c, cnt); + x = GETB(c); + } + *inlen = c.in_end - c.in; + if (c.in > c.in_end) + *inlen = 0; + *outlen = c.out_end - c.out; + return c.error; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/lzo.h b/arm/raspi/third_party/ffmpeg/libavutil/lzo.h new file mode 100644 index 00000000..c0340399 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/lzo.h @@ -0,0 +1,66 @@ +/* + * LZO 1x decompression + * copyright (c) 2006 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LZO_H +#define AVUTIL_LZO_H + +/** + * @defgroup lavu_lzo LZO + * @ingroup lavu_crypto + * + * @{ + */ + +#include + +/** @name Error flags returned by av_lzo1x_decode + * @{ */ +/// end of the input buffer reached before decoding finished +#define AV_LZO_INPUT_DEPLETED 1 +/// decoded data did not fit into output buffer +#define AV_LZO_OUTPUT_FULL 2 +/// a reference to previously decoded data was wrong +#define AV_LZO_INVALID_BACKPTR 4 +/// a non-specific error in the compressed bitstream +#define AV_LZO_ERROR 8 +/** @} */ + +#define AV_LZO_INPUT_PADDING 8 +#define AV_LZO_OUTPUT_PADDING 12 + +/** + * @brief Decodes LZO 1x compressed data. + * @param out output buffer + * @param outlen size of output buffer, number of bytes left are returned here + * @param in input buffer + * @param inlen size of input buffer, number of bytes left are returned here + * @return 0 on success, otherwise a combination of the error flags above + * + * Make sure all buffers are appropriately padded, in must provide + * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. + */ +int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); + +/** + * @} + */ + +#endif /* AVUTIL_LZO_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/macros.h b/arm/raspi/third_party/ffmpeg/libavutil/macros.h new file mode 100644 index 00000000..2a7567c3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/macros.h @@ -0,0 +1,80 @@ +/* + * 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 + * @ingroup lavu + * Utility Preprocessor macros + */ + +#ifndef AVUTIL_MACROS_H +#define AVUTIL_MACROS_H + +#include "libavutil/avconfig.h" + +#if AV_HAVE_BIGENDIAN +# define AV_NE(be, le) (be) +#else +# define AV_NE(be, le) (le) +#endif + +/** + * Comparator. + * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 + * if x == y. This is useful for instance in a qsort comparator callback. + * Furthermore, compilers are able to optimize this to branchless code, and + * there is no risk of overflow with signed types. + * As with many macros, this evaluates its argument multiple times, it thus + * must not have a side-effect. + */ +#define FFDIFFSIGN(x,y) (((x)>(y)) - ((x)<(y))) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) +#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24)) + +/** + * @addtogroup preproc_misc Preprocessor String Macros + * + * String manipulation macros + * + * @{ + */ + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +/** + * @} + */ + +#define AV_PRAGMA(s) _Pragma(#s) + +#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +#endif /* AVUTIL_MACROS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.c b/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.c new file mode 100644 index 00000000..60693476 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.c @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 Neil Birkbeck + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "mastering_display_metadata.h" +#include "mem.h" + +AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void) +{ + return av_mallocz(sizeof(AVMasteringDisplayMetadata)); +} + +AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, + sizeof(AVMasteringDisplayMetadata)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVMasteringDisplayMetadata)); + + return (AVMasteringDisplayMetadata *)side_data->data; +} + +AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size) +{ + AVContentLightMetadata *metadata = av_mallocz(sizeof(AVContentLightMetadata)); + + if (size) + *size = sizeof(*metadata); + + return metadata; +} + +AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + sizeof(AVContentLightMetadata)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVContentLightMetadata)); + + return (AVContentLightMetadata *)side_data->data; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.h b/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.h new file mode 100644 index 00000000..c23b07c3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mastering_display_metadata.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 Neil Birkbeck + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MASTERING_DISPLAY_METADATA_H +#define AVUTIL_MASTERING_DISPLAY_METADATA_H + +#include "frame.h" +#include "rational.h" + + +/** + * Mastering display metadata capable of representing the color volume of + * the display used to master the content (SMPTE 2086:2014). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_mastering_display_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVMasteringDisplayMetadata { + /** + * CIE 1931 xy chromaticity coords of color primaries (r, g, b order). + */ + AVRational display_primaries[3][2]; + + /** + * CIE 1931 xy chromaticity coords of white point. + */ + AVRational white_point[2]; + + /** + * Min luminance of mastering display (cd/m^2). + */ + AVRational min_luminance; + + /** + * Max luminance of mastering display (cd/m^2). + */ + AVRational max_luminance; + + /** + * Flag indicating whether the display primaries (and white point) are set. + */ + int has_primaries; + + /** + * Flag indicating whether the luminance (min_ and max_) have been set. + */ + int has_luminance; + +} AVMasteringDisplayMetadata; + +/** + * Allocate an AVMasteringDisplayMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVMasteringDisplayMetadata filled with default values or NULL + * on failure. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void); + +/** + * Allocate a complete AVMasteringDisplayMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVMasteringDisplayMetadata structure to be filled by caller. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame); + +/** + * Content light level needed by to transmit HDR over HDMI (CTA-861.3). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_content_light_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVContentLightMetadata { + /** + * Max content light level (cd/m^2). + */ + unsigned MaxCLL; + + /** + * Max average light level per frame (cd/m^2). + */ + unsigned MaxFALL; +} AVContentLightMetadata; + +/** + * Allocate an AVContentLightMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVContentLightMetadata filled with default values or NULL + * on failure. + */ +AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size); + +/** + * Allocate a complete AVContentLightMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVContentLightMetadata structure to be filled by caller. + */ +AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_MASTERING_DISPLAY_METADATA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mathematics.c b/arm/raspi/third_party/ffmpeg/libavutil/mathematics.c new file mode 100644 index 00000000..b878317d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mathematics.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2005-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * miscellaneous math routines and tables + */ + +#include +#include + +#include "avutil.h" +#include "mathematics.h" +#include "libavutil/intmath.h" +#include "libavutil/common.h" +#include "avassert.h" + +/* Stein's binary GCD algorithm: + * https://en.wikipedia.org/wiki/Binary_GCD_algorithm */ +int64_t av_gcd(int64_t a, int64_t b) { + int za, zb, k; + int64_t u, v; + if (a == 0) + return b; + if (b == 0) + return a; + za = ff_ctzll(a); + zb = ff_ctzll(b); + k = FFMIN(za, zb); + u = llabs(a >> za); + v = llabs(b >> zb); + while (u != v) { + if (u > v) + FFSWAP(int64_t, v, u); + v -= u; + v >>= ff_ctzll(v); + } + return (uint64_t)u << k; +} + +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) +{ + int64_t r = 0; + av_assert2(c > 0); + av_assert2(b >=0); + av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4); + + if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4)) + return INT64_MIN; + + if (rnd & AV_ROUND_PASS_MINMAX) { + if (a == INT64_MIN || a == INT64_MAX) + return a; + rnd -= AV_ROUND_PASS_MINMAX; + } + + if (a < 0) + return -(uint64_t)av_rescale_rnd(-FFMAX(a, -INT64_MAX), b, c, rnd ^ ((rnd >> 1) & 1)); + + if (rnd == AV_ROUND_NEAR_INF) + r = c / 2; + else if (rnd & 1) + r = c - 1; + + if (b <= INT_MAX && c <= INT_MAX) { + if (a <= INT_MAX) + return (a * b + r) / c; + else { + int64_t ad = a / c; + int64_t a2 = (a % c * b + r) / c; + if (ad >= INT32_MAX && b && ad > (INT64_MAX - a2) / b) + return INT64_MIN; + return ad * b + a2; + } + } else { +#if 1 + uint64_t a0 = a & 0xFFFFFFFF; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xFFFFFFFF; + uint64_t b1 = b >> 32; + uint64_t t1 = a0 * b1 + a1 * b0; + uint64_t t1a = t1 << 32; + int i; + + a0 = a0 * b0 + t1a; + a1 = a1 * b1 + (t1 >> 32) + (a0 < t1a); + a0 += r; + a1 += a0 < r; + + for (i = 63; i >= 0; i--) { + a1 += a1 + ((a0 >> i) & 1); + t1 += t1; + if (c <= a1) { + a1 -= c; + t1++; + } + } + if (t1 > INT64_MAX) + return INT64_MIN; + return t1; +#else + /* reference code doing (a*b + r) / c, requires libavutil/integer.h */ + AVInteger ai; + ai = av_mul_i(av_int2i(a), av_int2i(b)); + ai = av_add_i(ai, av_int2i(r)); + + return av_i2int(av_div_i(ai, av_int2i(c))); +#endif + } +} + +int64_t av_rescale(int64_t a, int64_t b, int64_t c) +{ + return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +} + +int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, + enum AVRounding rnd) +{ + int64_t b = bq.num * (int64_t)cq.den; + int64_t c = cq.num * (int64_t)bq.den; + return av_rescale_rnd(a, b, c, rnd); +} + +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) +{ + return av_rescale_q_rnd(a, bq, cq, AV_ROUND_NEAR_INF); +} + +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b) +{ + int64_t a = tb_a.num * (int64_t)tb_b.den; + int64_t b = tb_b.num * (int64_t)tb_a.den; + if ((FFABS64U(ts_a)|a|FFABS64U(ts_b)|b) <= INT_MAX) + return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b); + if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) + return -1; + if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) + return 1; + return 0; +} + +int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod) +{ + int64_t c = (a - b) & (mod - 1); + if (c > (mod >> 1)) + c -= mod; + return c; +} + +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb){ + int64_t a, b, this; + + av_assert0(in_ts != AV_NOPTS_VALUE); + av_assert0(duration >= 0); + + if (*last == AV_NOPTS_VALUE || !duration || in_tb.num*(int64_t)out_tb.den <= out_tb.num*(int64_t)in_tb.den) { +simple_round: + *last = av_rescale_q(in_ts, in_tb, fs_tb) + duration; + return av_rescale_q(in_ts, in_tb, out_tb); + } + + a = av_rescale_q_rnd(2*in_ts-1, in_tb, fs_tb, AV_ROUND_DOWN) >>1; + b = (av_rescale_q_rnd(2*in_ts+1, in_tb, fs_tb, AV_ROUND_UP )+1)>>1; + if (*last < 2*a - b || *last > 2*b - a) + goto simple_round; + + this = av_clip64(*last, a, b); + *last = this + duration; + + return av_rescale_q(this, fs_tb, out_tb); +} + +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc) +{ + int64_t m, d; + + if (inc != 1) + inc_tb = av_mul_q(inc_tb, (AVRational) {inc, 1}); + + m = inc_tb.num * (int64_t)ts_tb.den; + d = inc_tb.den * (int64_t)ts_tb.num; + + if (m % d == 0 && ts <= INT64_MAX - m / d) + return ts + m / d; + if (m < d) + return ts; + + { + int64_t old = av_rescale_q(ts, ts_tb, inc_tb); + int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb); + + if (old == INT64_MAX || old == AV_NOPTS_VALUE || old_ts == AV_NOPTS_VALUE) + return ts; + + return av_sat_add64(av_rescale_q(old + 1, inc_tb, ts_tb), ts - old_ts); + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mathematics.h b/arm/raspi/third_party/ffmpeg/libavutil/mathematics.h new file mode 100644 index 00000000..e4aff1e9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mathematics.h @@ -0,0 +1,245 @@ +/* + * copyright (c) 2005-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @addtogroup lavu_math + * Mathematical utilities for working with timestamp and time base. + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include +#include +#include "attributes.h" +#include "rational.h" +#include "intfloat.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_LOG2_10 +#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ +#endif +#ifndef M_PHI +#define M_PHI 1.61803398874989484820 /* phi / golden ratio */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif +#ifndef NAN +#define NAN av_int2float(0x7fc00000) +#endif +#ifndef INFINITY +#define INFINITY av_int2float(0x7f800000) +#endif + +/** + * @addtogroup lavu_math + * + * @{ + */ + +/** + * Rounding methods. + */ +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. + /** + * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through + * unchanged, avoiding special cases for #AV_NOPTS_VALUE. + * + * Unlike other values of the enumeration AVRounding, this value is a + * bitmask that must be used in conjunction with another value of the + * enumeration through a bitwise OR, in order to set behavior for normal + * cases. + * + * @code{.c} + * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling 3: + * // Calculating 3 * 1 / 2 + * // 3 / 2 is rounded up to 2 + * // => 2 + * + * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling AV_NOPTS_VALUE: + * // AV_NOPTS_VALUE == INT64_MIN + * // AV_NOPTS_VALUE is passed through + * // => AV_NOPTS_VALUE + * @endcode + */ + AV_ROUND_PASS_MINMAX = 8192, +}; + +/** + * Compute the greatest common divisor of two integer operands. + * + * @param a Operand + * @param b Operand + * @return GCD of a and b up to sign; if a >= 0 and b >= 0, return value is >= 0; + * if a == 0 and b == 0, returns 0. + */ +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescale a 64-bit integer with rounding to nearest. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow. + * + * This function is equivalent to av_rescale_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale_rnd(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * Rescale a 64-bit integer with specified rounding. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow, and does not support different rounding methods. + * If the result is not representable then INT64_MIN is returned. + * + * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd() + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers with specified rounding. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q() + */ +int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, + enum AVRounding rnd) av_const; + +/** + * Compare two timestamps each in its own time base. + * + * @return One of the following values: + * - -1 if `ts_a` is before `ts_b` + * - 1 if `ts_a` is after `ts_b` + * - 0 if they represent the same position + * + * @warning + * The result of the function is undefined if one of the timestamps is outside + * the `int64_t` range when represented in the other's timebase. + */ +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); + +/** + * Compare the remainders of two integer operands divided by a common divisor. + * + * In other words, compare the least significant `log2(mod)` bits of integers + * `a` and `b`. + * + * @code{.c} + * av_compare_mod(0x11, 0x02, 0x10) < 0 // since 0x11 % 0x10 (0x1) < 0x02 % 0x10 (0x2) + * av_compare_mod(0x11, 0x02, 0x20) > 0 // since 0x11 % 0x20 (0x11) > 0x02 % 0x20 (0x02) + * @endcode + * + * @param a Operand + * @param b Operand + * @param mod Divisor; must be a power of 2 + * @return + * - a negative value if `a % mod < b % mod` + * - a positive value if `a % mod > b % mod` + * - zero if `a % mod == b % mod` + */ +int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); + +/** + * Rescale a timestamp while preserving known durations. + * + * This function is designed to be called per audio packet to scale the input + * timestamp to a different time base. Compared to a simple av_rescale_q() + * call, this function is robust against possible inconsistent frame durations. + * + * The `last` parameter is a state variable that must be preserved for all + * subsequent calls for the same stream. For the first call, `*last` should be + * initialized to #AV_NOPTS_VALUE. + * + * @param[in] in_tb Input time base + * @param[in] in_ts Input timestamp + * @param[in] fs_tb Duration time base; typically this is finer-grained + * (greater) than `in_tb` and `out_tb` + * @param[in] duration Duration till the next call to this function (i.e. + * duration of the current packet/frame) + * @param[in,out] last Pointer to a timestamp expressed in terms of + * `fs_tb`, acting as a state variable + * @param[in] out_tb Output timebase + * @return Timestamp expressed in terms of `out_tb` + * + * @note In the context of this function, "duration" is in term of samples, not + * seconds. + */ +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb); + +/** + * Add a value to a timestamp. + * + * This function guarantees that when the same value is repeatly added that + * no accumulation of rounding errors occurs. + * + * @param[in] ts Input timestamp + * @param[in] ts_tb Input timestamp time base + * @param[in] inc Value to be added + * @param[in] inc_tb Time base of `inc` + */ +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc); + + +/** + * @} + */ + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/md5.c b/arm/raspi/third_party/ffmpeg/libavutil/md5.c new file mode 100644 index 00000000..0170d8dd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/md5.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at) + * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org) + * + * References: + * IETF RFC 1321: The MD5 Message-Digest Algorithm + * Ron Rivest. IETF, April, 1992 + * + * based on http://ubiqx.org/libcifs/source/Auth/MD5.c + * from Christopher R. Hertel (crh@ubiqx.mn.org) + * Simplified, cleaned and IMO redundant comments removed by Michael. + * + * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is + * strongly recommended. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "bswap.h" +#include "intreadwrite.h" +#include "mem.h" +#include "md5.h" + +typedef struct AVMD5 { + uint64_t len; + uint8_t block[64]; + uint32_t ABCD[4]; +} AVMD5; + +const int av_md5_size = sizeof(AVMD5); + +struct AVMD5 *av_md5_alloc(void) +{ + return av_mallocz(sizeof(struct AVMD5)); +} + +static const uint8_t S[4][4] = { + { 7, 12, 17, 22 }, /* round 1 */ + { 5, 9, 14, 20 }, /* round 2 */ + { 4, 11, 16, 23 }, /* round 3 */ + { 6, 10, 15, 21 } /* round 4 */ +}; + +static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */ + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */ + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */ + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */ + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +#define CORE(i, a, b, c, d) \ + do { \ + t = S[i >> 4][i & 3]; \ + a += T[i]; \ + \ + if (i < 32) { \ + if (i < 16) \ + a += (d ^ (b & (c ^ d))) + AV_RL32(X+( i & 15));\ + else \ + a += ((d & b) | (~d & c)) + AV_RL32(X+((1 + 5*i) & 15));\ + } else { \ + if (i < 48) \ + a += (b ^ c ^ d) + AV_RL32(X+((5 + 3*i) & 15));\ + else \ + a += (c ^ (b | ~d)) + AV_RL32(X+(( 7*i) & 15));\ + } \ + a = b + (a << t | a >> (32 - t)); \ + } while (0) + +static void body(uint32_t ABCD[4], const uint8_t *src, size_t nblocks) +{ + const uint32_t *X; + uint32_t a, b, c, d, t; + + for (size_t n = 0; n < nblocks; n++) { + a = ABCD[3]; + b = ABCD[2]; + c = ABCD[1]; + d = ABCD[0]; + + X = (const uint32_t *)src + n * 16; + +#if CONFIG_SMALL + for (int i = 0; i < 64; i++) { + CORE(i, a, b, c, d); + t = d; + d = c; + c = b; + b = a; + a = t; + } +#else +#define CORE2(i) \ + CORE(i, a, b, c, d); CORE((i + 1), d, a, b, c); \ + CORE((i + 2), c, d, a, b); CORE((i + 3), b, c, d, a) +#define CORE4(i) CORE2(i); CORE2((i + 4)); CORE2((i + 8)); CORE2((i + 12)) + CORE4(0); + CORE4(16); + CORE4(32); + CORE4(48); +#endif + + ABCD[0] += d; + ABCD[1] += c; + ABCD[2] += b; + ABCD[3] += a; + } +} + +void av_md5_init(AVMD5 *ctx) +{ + ctx->len = 0; + + ctx->ABCD[0] = 0x10325476; + ctx->ABCD[1] = 0x98badcfe; + ctx->ABCD[2] = 0xefcdab89; + ctx->ABCD[3] = 0x67452301; +} + +void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len) +{ + const uint8_t *end; + int j; + + j = ctx->len & 63; + ctx->len += len; + + if (j) { + int cnt = FFMIN(len, 64 - j); + memcpy(ctx->block + j, src, cnt); + src += cnt; + len -= cnt; + if (j + cnt < 64) + return; + body(ctx->ABCD, ctx->block, 1); + } + + end = src + (len & ~63); + if (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3)) { + while (src < end) { + memcpy(ctx->block, src, 64); + body(ctx->ABCD, ctx->block, 1); + src += 64; + } + } else { + size_t nblocks = len / 64; + body(ctx->ABCD, src, nblocks); + src = end; + } + len &= 63; + if (len > 0) + memcpy(ctx->block, src, len); +} + +void av_md5_final(AVMD5 *ctx, uint8_t *dst) +{ + int i; + uint64_t finalcount = av_le2ne64(ctx->len << 3); + + av_md5_update(ctx, "\200", 1); + while ((ctx->len & 63) != 56) + av_md5_update(ctx, "", 1); + + av_md5_update(ctx, (uint8_t *) &finalcount, 8); + + for (i = 0; i < 4; i++) + AV_WL32(dst + 4 * i, ctx->ABCD[3 - i]); +} + +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len) +{ + AVMD5 ctx; + + av_md5_init(&ctx); + av_md5_update(&ctx, src, len); + av_md5_final(&ctx, dst); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/md5.h b/arm/raspi/third_party/ffmpeg/libavutil/md5.h new file mode 100644 index 00000000..fc2eabdb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/md5.h @@ -0,0 +1,89 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_md5 + * Public header for MD5 hash function implementation. + */ + +#ifndef AVUTIL_MD5_H +#define AVUTIL_MD5_H + +#include +#include + +#include "attributes.h" + +/** + * @defgroup lavu_md5 MD5 + * @ingroup lavu_hash + * MD5 hash function implementation. + * + * @{ + */ + +extern const int av_md5_size; + +struct AVMD5; + +/** + * Allocate an AVMD5 context. + */ +struct AVMD5 *av_md5_alloc(void); + +/** + * Initialize MD5 hashing. + * + * @param ctx pointer to the function context (of size av_md5_size) + */ +void av_md5_init(struct AVMD5 *ctx); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param src input data to update hash with + * @param len input data length + */ +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, size_t len); + +/** + * Finish hashing and output digest value. + * + * @param ctx hash function context + * @param dst buffer where output digest value is stored + */ +void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); + +/** + * Hash an array of data. + * + * @param dst The output buffer to write the digest into + * @param src The data to hash + * @param len The length of the data, in bytes + */ +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len); + +/** + * @} + */ + +#endif /* AVUTIL_MD5_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mem.c b/arm/raspi/third_party/ffmpeg/libavutil/mem.c new file mode 100644 index 00000000..2bb13149 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mem.c @@ -0,0 +1,579 @@ +/* + * default memory allocator for libavutil + * Copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * default memory allocator for libavutil + */ + +#define _XOPEN_SOURCE 600 + +#include "config.h" + +#include +#include +#include +#include +#include +#if HAVE_MALLOC_H +#include +#endif + +#include "attributes.h" +#include "avassert.h" +#include "dynarray.h" +#include "error.h" +#include "internal.h" +#include "intreadwrite.h" +#include "macros.h" +#include "mem.h" + +#ifdef MALLOC_PREFIX + +#define malloc AV_JOIN(MALLOC_PREFIX, malloc) +#define memalign AV_JOIN(MALLOC_PREFIX, memalign) +#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign) +#define realloc AV_JOIN(MALLOC_PREFIX, realloc) +#define free AV_JOIN(MALLOC_PREFIX, free) + +void *malloc(size_t size); +void *memalign(size_t align, size_t size); +int posix_memalign(void **ptr, size_t align, size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); + +#endif /* MALLOC_PREFIX */ + +#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16)) + +/* NOTE: if you want to override these functions with your own + * implementations (not recommended) you have to link libav* as + * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags. + * Note that this will cost performance. */ + +static atomic_size_t max_alloc_size = ATOMIC_VAR_INIT(INT_MAX); + +/* Set to 0 to remove the maximum allocation size. */ +void av_max_alloc(size_t max){ + atomic_store_explicit(&max_alloc_size, max, memory_order_relaxed); +} + +static int size_mult(size_t a, size_t b, size_t *r) +{ + size_t t; + +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow) + if (__builtin_mul_overflow(a, b, &t)) + return AVERROR(EINVAL); +#else + t = a * b; + /* Hack inspired from glibc: don't try the division if nelem and elsize + * are both less than sqrt(SIZE_MAX). */ + if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) + return AVERROR(EINVAL); +#endif + *r = t; + return 0; +} + +void *av_malloc(size_t size) +{ + void *ptr = NULL; + + if (size > atomic_load_explicit(&max_alloc_size, memory_order_relaxed)) + return NULL; + +#if HAVE_POSIX_MEMALIGN + if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation + if (posix_memalign(&ptr, ALIGN, size)) + ptr = NULL; +#elif HAVE_ALIGNED_MALLOC + ptr = _aligned_malloc(size, ALIGN); +#elif HAVE_MEMALIGN +#ifndef __DJGPP__ + ptr = memalign(ALIGN, size); +#else + ptr = memalign(size, ALIGN); +#endif + /* Why 64? + * Indeed, we should align it: + * on 4 for 386 + * on 16 for 486 + * on 32 for 586, PPro - K6-III + * on 64 for K7 (maybe for P3 too). + * Because L1 and L2 caches are aligned on those values. + * But I don't want to code such logic here! + */ + /* Why 32? + * For AVX ASM. SSE / NEON needs only 16. + * Why not larger? Because I did not see a difference in benchmarks ... + */ + /* benchmarks with P3 + * memalign(64) + 1 3071, 3051, 3032 + * memalign(64) + 2 3051, 3032, 3041 + * memalign(64) + 4 2911, 2896, 2915 + * memalign(64) + 8 2545, 2554, 2550 + * memalign(64) + 16 2543, 2572, 2563 + * memalign(64) + 32 2546, 2545, 2571 + * memalign(64) + 64 2570, 2533, 2558 + * + * BTW, malloc seems to do 8-byte alignment by default here. + */ +#else + ptr = malloc(size); +#endif + if(!ptr && !size) { + size = 1; + ptr= av_malloc(1); + } +#if CONFIG_MEMORY_POISONING + if (ptr) + memset(ptr, FF_MEMORY_POISON, size); +#endif + return ptr; +} + +void *av_realloc(void *ptr, size_t size) +{ + void *ret; + if (size > atomic_load_explicit(&max_alloc_size, memory_order_relaxed)) + return NULL; + +#if HAVE_ALIGNED_MALLOC + ret = _aligned_realloc(ptr, size + !size, ALIGN); +#else + ret = realloc(ptr, size + !size); +#endif +#if CONFIG_MEMORY_POISONING + if (ret && !ptr) + memset(ret, FF_MEMORY_POISON, size); +#endif + return ret; +} + +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize) +{ + size_t size; + void *r; + + if (size_mult(elsize, nelem, &size)) { + av_free(ptr); + return NULL; + } + r = av_realloc(ptr, size); + if (!r) + av_free(ptr); + return r; +} + +int av_reallocp(void *ptr, size_t size) +{ + void *val; + + if (!size) { + av_freep(ptr); + return 0; + } + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc(val, size); + + if (!val) { + av_freep(ptr); + return AVERROR(ENOMEM); + } + + memcpy(ptr, &val, sizeof(val)); + return 0; +} + +void *av_malloc_array(size_t nmemb, size_t size) +{ + size_t result; + if (size_mult(nmemb, size, &result) < 0) + return NULL; + return av_malloc(result); +} + +#if FF_API_AV_MALLOCZ_ARRAY +void *av_mallocz_array(size_t nmemb, size_t size) +{ + size_t result; + if (size_mult(nmemb, size, &result) < 0) + return NULL; + return av_mallocz(result); +} +#endif + +void *av_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + size_t result; + if (size_mult(nmemb, size, &result) < 0) + return NULL; + return av_realloc(ptr, result); +} + +int av_reallocp_array(void *ptr, size_t nmemb, size_t size) +{ + void *val; + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc_f(val, nmemb, size); + memcpy(ptr, &val, sizeof(val)); + if (!val && nmemb && size) + return AVERROR(ENOMEM); + + return 0; +} + +void av_free(void *ptr) +{ +#if HAVE_ALIGNED_MALLOC + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +void av_freep(void *arg) +{ + void *val; + + memcpy(&val, arg, sizeof(val)); + memcpy(arg, &(void *){ NULL }, sizeof(val)); + av_free(val); +} + +void *av_mallocz(size_t size) +{ + void *ptr = av_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void *av_calloc(size_t nmemb, size_t size) +{ + size_t result; + if (size_mult(nmemb, size, &result) < 0) + return NULL; + return av_mallocz(result); +} + +char *av_strdup(const char *s) +{ + char *ptr = NULL; + if (s) { + size_t len = strlen(s) + 1; + ptr = av_realloc(NULL, len); + if (ptr) + memcpy(ptr, s, len); + } + return ptr; +} + +char *av_strndup(const char *s, size_t len) +{ + char *ret = NULL, *end; + + if (!s) + return NULL; + + end = memchr(s, 0, len); + if (end) + len = end - s; + + ret = av_realloc(NULL, len + 1); + if (!ret) + return NULL; + + memcpy(ret, s, len); + ret[len] = 0; + return ret; +} + +void *av_memdup(const void *p, size_t size) +{ + void *ptr = NULL; + if (p) { + ptr = av_malloc(size); + if (ptr) + memcpy(ptr, p, size); + } + return ptr; +} + +int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem) +{ + void **tab; + memcpy(&tab, tab_ptr, sizeof(tab)); + + FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, { + tab[*nb_ptr] = elem; + memcpy(tab_ptr, &tab, sizeof(tab)); + }, { + return AVERROR(ENOMEM); + }); + return 0; +} + +void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) +{ + void **tab; + memcpy(&tab, tab_ptr, sizeof(tab)); + + FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, { + tab[*nb_ptr] = elem; + memcpy(tab_ptr, &tab, sizeof(tab)); + }, { + *nb_ptr = 0; + av_freep(tab_ptr); + }); +} + +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data) +{ + uint8_t *tab_elem_data = NULL; + + FF_DYNARRAY_ADD(INT_MAX, elem_size, *tab_ptr, *nb_ptr, { + tab_elem_data = (uint8_t *)*tab_ptr + (*nb_ptr) * elem_size; + if (elem_data) + memcpy(tab_elem_data, elem_data, elem_size); + else if (CONFIG_MEMORY_POISONING) + memset(tab_elem_data, FF_MEMORY_POISON, elem_size); + }, { + av_freep(tab_ptr); + *nb_ptr = 0; + }); + return tab_elem_data; +} + +static void fill16(uint8_t *dst, int len) +{ + uint32_t v = AV_RN16(dst - 2); + + v |= v << 16; + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-2]; + dst++; + } +} + +static void fill24(uint8_t *dst, int len) +{ +#if HAVE_BIGENDIAN + uint32_t v = AV_RB24(dst - 3); + uint32_t a = v << 8 | v >> 16; + uint32_t b = v << 16 | v >> 8; + uint32_t c = v << 24 | v; +#else + uint32_t v = AV_RL24(dst - 3); + uint32_t a = v | v << 24; + uint32_t b = v >> 8 | v << 16; + uint32_t c = v >> 16 | v << 8; +#endif + + while (len >= 12) { + AV_WN32(dst, a); + AV_WN32(dst + 4, b); + AV_WN32(dst + 8, c); + dst += 12; + len -= 12; + } + + if (len >= 4) { + AV_WN32(dst, a); + dst += 4; + len -= 4; + } + + if (len >= 4) { + AV_WN32(dst, b); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-3]; + dst++; + } +} + +static void fill32(uint8_t *dst, int len) +{ + uint32_t v = AV_RN32(dst - 4); + +#if HAVE_FAST_64BIT + uint64_t v2= v + ((uint64_t)v<<32); + while (len >= 32) { + AV_WN64(dst , v2); + AV_WN64(dst+ 8, v2); + AV_WN64(dst+16, v2); + AV_WN64(dst+24, v2); + dst += 32; + len -= 32; + } +#endif + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-4]; + dst++; + } +} + +void av_memcpy_backptr(uint8_t *dst, int back, int cnt) +{ + const uint8_t *src = &dst[-back]; + if (!back) + return; + + if (back == 1) { + memset(dst, *src, cnt); + } else if (back == 2) { + fill16(dst, cnt); + } else if (back == 3) { + fill24(dst, cnt); + } else if (back == 4) { + fill32(dst, cnt); + } else { + if (cnt >= 16) { + int blocklen = back; + while (cnt > blocklen) { + memcpy(dst, src, blocklen); + dst += blocklen; + cnt -= blocklen; + blocklen <<= 1; + } + memcpy(dst, src, cnt); + return; + } + if (cnt >= 8) { + AV_COPY32U(dst, src); + AV_COPY32U(dst + 4, src + 4); + src += 8; + dst += 8; + cnt -= 8; + } + if (cnt >= 4) { + AV_COPY32U(dst, src); + src += 4; + dst += 4; + cnt -= 4; + } + if (cnt >= 2) { + AV_COPY16U(dst, src); + src += 2; + dst += 2; + cnt -= 2; + } + if (cnt) + *dst = *src; + } +} + +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +{ + size_t max_size; + + if (min_size <= *size) + return ptr; + + max_size = atomic_load_explicit(&max_alloc_size, memory_order_relaxed); + /* *size is an unsigned, so the real maximum is <= UINT_MAX. */ + max_size = FFMIN(max_size, UINT_MAX); + + if (min_size > max_size) { + *size = 0; + return NULL; + } + + min_size = FFMIN(max_size, FFMAX(min_size + min_size / 16 + 32, min_size)); + + ptr = av_realloc(ptr, min_size); + /* we could set this to the unmodified min_size but this is safer + * if the user lost the ptr and uses NULL now + */ + if (!ptr) + min_size = 0; + + *size = min_size; + + return ptr; +} + +static inline void fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) +{ + size_t max_size; + void *val; + + memcpy(&val, ptr, sizeof(val)); + if (min_size <= *size) { + av_assert0(val || !min_size); + return; + } + + max_size = atomic_load_explicit(&max_alloc_size, memory_order_relaxed); + /* *size is an unsigned, so the real maximum is <= UINT_MAX. */ + max_size = FFMIN(max_size, UINT_MAX); + + if (min_size > max_size) { + av_freep(ptr); + *size = 0; + return; + } + min_size = FFMIN(max_size, FFMAX(min_size + min_size / 16 + 32, min_size)); + av_freep(ptr); + val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size); + memcpy(ptr, &val, sizeof(val)); + if (!val) + min_size = 0; + *size = min_size; + return; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + fast_malloc(ptr, size, min_size, 0); +} + +void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size) +{ + fast_malloc(ptr, size, min_size, 1); +} + +int av_size_mult(size_t a, size_t b, size_t *r) +{ + return size_mult(a, b, r); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mem.h b/arm/raspi/third_party/ffmpeg/libavutil/mem.h new file mode 100644 index 00000000..c9c4fcf1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mem.h @@ -0,0 +1,697 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_mem + * Memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include +#include + +#include "attributes.h" +#include "avutil.h" +#include "version.h" + +/** + * @addtogroup lavu_mem + * Utilities for manipulating memory. + * + * FFmpeg has several applications of memory that are not required of a typical + * program. For example, the computing-heavy components like video decoding and + * encoding can be sped up significantly through the use of aligned memory. + * + * However, for each of FFmpeg's applications of memory, there might not be a + * recognized or standardized API for that specific use. Memory alignment, for + * instance, varies wildly depending on operating systems, architectures, and + * compilers. Hence, this component of @ref libavutil is created to make + * dealing with memory consistently possible on all platforms. + * + * @{ + */ + +#if FF_API_DECLARE_ALIGNED +/** + * + * @defgroup lavu_mem_macros Alignment Macros + * Helper macros for declaring aligned variables. + * @{ + */ + +/** + * @def DECLARE_ALIGNED(n,t,v) + * Declare a variable that is aligned in memory. + * + * @code{.c} + * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; + * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; + * + * // The default-alignment equivalent would be + * uint16_t aligned_int = 42; + * uint8_t aligned_array[128]; + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_CONST(n,t,v) + * Declare a static constant aligned variable appropriate for use in inline + * assembly code. + * + * @code{.c} + * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v +#elif defined(__GNUC__) || defined(__clang__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +/** + * @} + */ +#endif + +/** + * @defgroup lavu_mem_attrs Function Attributes + * Function attributes applicable to memory handling functions. + * + * These function attributes can help compilers emit more useful warnings, or + * generate better code. + * @{ + */ + +/** + * @def av_malloc_attrib + * Function attribute denoting a malloc-like function. + * + * @see Function attribute `malloc` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +/** + * @def av_alloc_size(...) + * Function attribute used on a function that allocates memory, whose size is + * given by the specified parameter(s). + * + * @code{.c} + * void *av_malloc(size_t size) av_alloc_size(1); + * void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2); + * @endcode + * + * @param ... One or two parameter indexes, separated by a comma + * + * @see Function attribute `alloc_size` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) +#else + #define av_alloc_size(...) +#endif + +/** + * @} + */ + +/** + * @defgroup lavu_mem_funcs Heap Management + * Functions responsible for allocating, freeing, and copying memory. + * + * All memory allocation functions have a built-in upper limit of `INT_MAX` + * bytes. This may be changed with av_max_alloc(), although exercise extreme + * caution when doing so. + * + * @{ + */ + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU). + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_mallocz() + */ +void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU) and zero all the bytes of the + * block. + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if it cannot be allocated + * @see av_malloc() + */ +void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block for an array with av_malloc(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of element + * @param size Size of a single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_malloc() + */ +av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); + +/** + * Allocate a memory block for an array with av_mallocz(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of elements + * @param size Size of the single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * + * @see av_mallocz() + * @see av_malloc_array() + */ +void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib av_alloc_size(1, 2); + +#if FF_API_AV_MALLOCZ_ARRAY +/** + * @deprecated use av_calloc() + */ +attribute_deprecated +void *av_mallocz_array(size_t nmemb, size_t size) av_malloc_attrib av_alloc_size(1, 2); +#endif + +/** + * Allocate, reallocate, or free a block of memory. + * + * If `ptr` is `NULL` and `size` > 0, allocate a new block. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param size Size in bytes of the memory block to be allocated or + * reallocated + * + * @return Pointer to a newly-reallocated block or `NULL` if the block + * cannot be reallocated + * + * @warning Unlike av_malloc(), the returned pointer is not guaranteed to be + * correctly aligned. The returned pointer must be freed after even + * if size is zero. + * @see av_fast_realloc() + * @see av_reallocp() + */ +void *av_realloc(void *ptr, size_t size) av_alloc_size(2); + +/** + * Allocate, reallocate, or free a block of memory through a pointer to a + * pointer. + * + * If `*ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is + * zero, free the memory block pointed to by `*ptr`. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already allocated + * with av_realloc(), or a pointer to `NULL`. The pointer + * is updated on success, or freed on failure. + * @param[in] size Size in bytes for the memory block to be allocated or + * reallocated + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + */ +av_warn_unused_result +int av_reallocp(void *ptr, size_t size); + +/** + * Allocate, reallocate, or free a block of memory. + * + * This function does the same thing as av_realloc(), except: + * - It takes two size arguments and allocates `nelem * elsize` bytes, + * after checking the result of the multiplication for integer overflow. + * - It frees the input block in case of failure, thus avoiding the memory + * leak with the classic + * @code{.c} + * buf = realloc(buf); + * if (!buf) + * return -1; + * @endcode + * pattern. + */ +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize); + +/** + * Allocate, reallocate, or free an array. + * + * If `ptr` is `NULL` and `nmemb` > 0, allocate a new block. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param nmemb Number of elements in the array + * @param size Size of the single element of the array + * + * @return Pointer to a newly-reallocated block or NULL if the block + * cannot be reallocated + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. The returned pointer must be freed after even if + * nmemb is zero. + * @see av_reallocp_array() + */ +av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size); + +/** + * Allocate, reallocate an array through a pointer to a pointer. + * + * If `*ptr` is `NULL` and `nmemb` > 0, allocate a new block. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already + * allocated with av_realloc(), or a pointer to `NULL`. + * The pointer is updated on success, or freed on failure. + * @param[in] nmemb Number of elements + * @param[in] size Size of the single element + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. *ptr must be freed after even if nmemb is zero. + */ +int av_reallocp_array(void *ptr, size_t nmemb, size_t size); + +/** + * Reallocate the given buffer if it is not large enough, otherwise do nothing. + * + * If the given buffer is `NULL`, then a new uninitialized buffer is allocated. + * + * If the given buffer is not large enough, and reallocation fails, `NULL` is + * returned and `*size` is set to 0, but the original buffer is not changed or + * freed. + * + * A typical use pattern follows: + * + * @code{.c} + * uint8_t *buf = ...; + * uint8_t *new_buf = av_fast_realloc(buf, ¤t_size, size_needed); + * if (!new_buf) { + * // Allocation failed; clean up original buffer + * av_freep(&buf); + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Already allocated buffer, or `NULL` + * @param[in,out] size Pointer to the size of buffer `ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `ptr` + * @return `ptr` if the buffer is large enough, a pointer to newly reallocated + * buffer if the buffer was not large enough, or `NULL` in case of + * error + * @see av_realloc() + * @see av_fast_malloc() + */ +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc(), the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special handling to + * avoid memleaks is necessary. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @code{.c} + * uint8_t *buf = ...; + * av_fast_malloc(&buf, ¤t_size, size_needed); + * if (!buf) { + * // Allocation failed; buf already freed + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_realloc() + * @see av_fast_mallocz() + */ +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate and clear a buffer, reusing the given one if large enough. + * + * Like av_fast_malloc(), but all newly allocated space is initially cleared. + * Reused buffer is not cleared. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_fast_malloc() + */ +void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family. + * + * @param ptr Pointer to the memory block which should be freed. + * + * @note `ptr = NULL` is explicitly allowed. + * @note It is recommended that you use av_freep() instead, to prevent leaving + * behind dangling pointers. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family, and set the pointer pointing to it to `NULL`. + * + * @code{.c} + * uint8_t *buf = av_malloc(16); + * av_free(buf); + * // buf now contains a dangling pointer to freed memory, and accidental + * // dereference of buf will result in a use-after-free, which may be a + * // security risk. + * + * uint8_t *buf = av_malloc(16); + * av_freep(&buf); + * // buf is now NULL, and accidental dereference will only result in a + * // NULL-pointer dereference. + * @endcode + * + * @param ptr Pointer to the pointer to the memory block which should be freed + * @note `*ptr = NULL` is safe and leads to no action. + * @see av_free() + */ +void av_freep(void *ptr); + +/** + * Duplicate a string. + * + * @param s String to be duplicated + * @return Pointer to a newly-allocated string containing a + * copy of `s` or `NULL` if the string cannot be allocated + * @see av_strndup() + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Duplicate a substring of a string. + * + * @param s String to be duplicated + * @param len Maximum length of the resulting string (not counting the + * terminating byte) + * @return Pointer to a newly-allocated string containing a + * substring of `s` or `NULL` if the string cannot be allocated + */ +char *av_strndup(const char *s, size_t len) av_malloc_attrib; + +/** + * Duplicate a buffer with av_malloc(). + * + * @param p Buffer to be duplicated + * @param size Size in bytes of the buffer copied + * @return Pointer to a newly allocated buffer containing a + * copy of `p` or `NULL` if the buffer cannot be allocated + */ +void *av_memdup(const void *p, size_t size); + +/** + * Overlapping memcpy() implementation. + * + * @param dst Destination buffer + * @param back Number of bytes back to start copying (i.e. the initial size of + * the overlapping window); must be > 0 + * @param cnt Number of bytes to copy; must be >= 0 + * + * @note `cnt > back` is valid, this will copy the bytes we just copied, + * thus creating a repeating pattern with a period length of `back`. + */ +void av_memcpy_backptr(uint8_t *dst, int back, int cnt); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_dynarray Dynamic Array + * + * Utilities to make an array grow when needed. + * + * Sometimes, the programmer would want to have an array that can grow when + * needed. The libavutil dynamic array utilities fill that need. + * + * libavutil supports two systems of appending elements onto a dynamically + * allocated array, the first one storing the pointer to the value in the + * array, and the second storing the value directly. In both systems, the + * caller is responsible for maintaining a variable containing the length of + * the array, as well as freeing of the array after use. + * + * The first system stores pointers to values in a block of dynamically + * allocated memory. Since only pointers are stored, the function does not need + * to know the size of the type. Both av_dynarray_add() and + * av_dynarray_add_nofree() implement this system. + * + * @code + * type **array = NULL; //< an array of pointers to values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * av_dynarray_add(&array, &nb, &to_be_added); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * av_dynarray_add(&array, &nb, &to_be_added2); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // &to_be_added == array[0] + * // &to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * The second system stores the value directly in a block of memory. As a + * result, the function has to know the size of the type. av_dynarray2_add() + * implements this mechanism. + * + * @code + * type *array = NULL; //< an array of values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL); + * if (!addr) + * return AVERROR(ENOMEM); + * memcpy(addr, &to_be_added, sizeof(to_be_added)); + * + * // Shortcut of the above. + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), + * (const void *)&to_be_added2); + * if (!addr) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // to_be_added == array[0] + * // to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * @{ + */ + +/** + * Add the pointer to an element to a dynamic array. + * + * The array to grow is supposed to be an array of pointers to + * structures, and the element to add must be a pointer to an already + * allocated structure. + * + * The array is reallocated when its size reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem Element to add + * @see av_dynarray_add_nofree(), av_dynarray2_add() + */ +void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element to a dynamic array. + * + * Function has the same functionality as av_dynarray_add(), + * but it doesn't free memory on fails. It returns error code + * instead and leave current buffer untouched. + * + * @return >=0 on success, negative otherwise + * @see av_dynarray_add(), av_dynarray2_add() + */ +av_warn_unused_result +int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element of size `elem_size` to a dynamic array. + * + * The array is reallocated when its number of elements reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem_size Size in bytes of an element in the array + * @param[in] elem_data Pointer to the data of the element to add. If + * `NULL`, the space of the newly added element is + * allocated but left uninitialized. + * + * @return Pointer to the data of the element to copy in the newly allocated + * space + * @see av_dynarray_add(), av_dynarray_add_nofree() + */ +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_misc Miscellaneous Functions + * + * Other functions related to memory allocation. + * + * @{ + */ + +/** + * Multiply two `size_t` values checking for overflow. + * + * @param[in] a Operand of multiplication + * @param[in] b Operand of multiplication + * @param[out] r Pointer to the result of the operation + * @return 0 on success, AVERROR(EINVAL) on overflow + */ +int av_size_mult(size_t a, size_t b, size_t *r); + +/** + * Set the maximum size that may be allocated in one block. + * + * The value specified with this function is effective for all libavutil's @ref + * lavu_mem_funcs "heap management functions." + * + * By default, the max value is defined as `INT_MAX`. + * + * @param max Value to be set as the new maximum size + * + * @warning Exercise extreme caution when using this function. Don't touch + * this if you do not understand the full consequence of doing so. + */ +void av_max_alloc(size_t max); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_MEM_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mem_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/mem_internal.h new file mode 100644 index 00000000..955e31a6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mem_internal.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MEM_INTERNAL_H +#define AVUTIL_MEM_INTERNAL_H + +#include "config.h" + +#include + +#include "attributes.h" +#include "macros.h" +#include "mem.h" +#include "version.h" + +#if !FF_API_DECLARE_ALIGNED +/** + * @def DECLARE_ALIGNED(n,t,v) + * Declare a variable that is aligned in memory. + * + * @code{.c} + * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; + * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; + * + * // The default-alignment equivalent would be + * uint16_t aligned_int = 42; + * uint8_t aligned_array[128]; + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_CONST(n,t,v) + * Declare a static constant aligned variable appropriate for use in inline + * assembly code. + * + * @code{.c} + * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v +#elif defined(__GNUC__) || defined(__clang__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif +#endif + +// Some broken preprocessors need a second expansion +// to be forced to tokenize __VA_ARGS__ +#define E1(x) x + +#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \ + uint8_t la_##v[sizeof(t s o) + (a)]; \ + t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a) + +#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \ + DECLARE_ALIGNED(a, t, la_##v) s o; \ + t (*v) o = la_##v + +#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) +#endif + +#endif /* AVUTIL_MEM_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/mips/Makefile new file mode 100644 index 00000000..5f8c9b64 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/Makefile @@ -0,0 +1 @@ +OBJS += mips/float_dsp_mips.o mips/cpu.o diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/asmdefs.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/asmdefs.h new file mode 100644 index 00000000..659342ba --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/asmdefs.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015 Imagination Technologies Ltd + * + * 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 + * MIPS assembly defines from sys/asm.h but rewritten for use with C inline + * assembly (rather than from within .s files). + */ + +#ifndef AVUTIL_MIPS_ASMDEFS_H +#define AVUTIL_MIPS_ASMDEFS_H + +#include + +#if defined(_ABI64) && _MIPS_SIM == _ABI64 +# define mips_reg int64_t +# define PTRSIZE " 8 " +# define PTRLOG " 3 " +# define PTR_ADDU "daddu " +# define PTR_ADDIU "daddiu " +# define PTR_ADDI "daddi " +# define PTR_SUBU "dsubu " +# define PTR_L "ld " +# define PTR_S "sd " +# define PTR_SRA "dsra " +# define PTR_SRL "dsrl " +# define PTR_SLL "dsll " +#else +# define mips_reg int32_t +# define PTRSIZE " 4 " +# define PTRLOG " 2 " +# define PTR_ADDU "addu " +# define PTR_ADDIU "addiu " +# define PTR_ADDI "addi " +# define PTR_SUBU "subu " +# define PTR_L "lw " +# define PTR_S "sw " +# define PTR_SRA "sra " +# define PTR_SRL "srl " +# define PTR_SLL "sll " +#endif + +/* + * parse_r var, r - Helper assembler macro for parsing register names. + * + * This converts the register name in $n form provided in \r to the + * corresponding register number, which is assigned to the variable \var. It is + * needed to allow explicit encoding of instructions in inline assembly where + * registers are chosen by the compiler in $n form, allowing us to avoid using + * fixed register numbers. + * + * It also allows newer instructions (not implemented by the assembler) to be + * transparently implemented using assembler macros, instead of needing separate + * cases depending on toolchain support. + * + * Simple usage example: + * __asm__ __volatile__("parse_r __rt, %0\n\t" + * ".insn\n\t" + * "# di %0\n\t" + * ".word (0x41606000 | (__rt << 16))" + * : "=r" (status); + */ + +/* Match an individual register number and assign to \var */ +#define _IFC_REG(n) \ + ".ifc \\r, $" #n "\n\t" \ + "\\var = " #n "\n\t" \ + ".endif\n\t" + +__asm__(".macro parse_r var r\n\t" + "\\var = -1\n\t" + _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) + _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) + _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) + _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) + _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) + _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) + _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) + _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) + ".iflt \\var\n\t" + ".error \"Unable to parse register name \\r\"\n\t" + ".endif\n\t" + ".endm"); + +/* General union structure for clang adaption */ +union mmi_intfloat64 { + int64_t i; + double f; +}; + +#endif /* AVCODEC_MIPS_ASMDEFS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.c new file mode 100644 index 00000000..59619d54 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.c @@ -0,0 +1,134 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "config.h" +#if defined __linux__ || defined __ANDROID__ +#include +#include +#include +#include +#include "asmdefs.h" +#include "libavutil/avstring.h" +#endif + +#if defined __linux__ || defined __ANDROID__ + +#define HWCAP_LOONGSON_CPUCFG (1 << 14) + +static int cpucfg_available(void) +{ + return getauxval(AT_HWCAP) & HWCAP_LOONGSON_CPUCFG; +} + +/* Most toolchains have no CPUCFG support yet */ +static uint32_t read_cpucfg(uint32_t reg) +{ + uint32_t __res; + + __asm__ __volatile__( + "parse_r __res,%0\n\t" + "parse_r reg,%1\n\t" + ".insn \n\t" + ".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t" + :"=r"(__res) + :"r"(reg) + : + ); + return __res; +} + +#define LOONGSON_CFG1 0x1 + +#define LOONGSON_CFG1_MMI (1 << 4) +#define LOONGSON_CFG1_MSA1 (1 << 5) + +static int cpu_flags_cpucfg(void) +{ + int flags = 0; + uint32_t cfg1 = read_cpucfg(LOONGSON_CFG1); + + if (cfg1 & LOONGSON_CFG1_MMI) + flags |= AV_CPU_FLAG_MMI; + + if (cfg1 & LOONGSON_CFG1_MSA1) + flags |= AV_CPU_FLAG_MSA; + + return flags; +} + +static int cpu_flags_cpuinfo(void) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + int flags = 0; + + if (!f) + return -1; + + while (fgets(buf, sizeof(buf), f)) { + /* Legacy kernel may not export MMI in ASEs implemented */ + if (av_strstart(buf, "cpu model", NULL)) { + if (strstr(buf, "Loongson-3 ")) + flags |= AV_CPU_FLAG_MMI; + } + + if (av_strstart(buf, "ASEs implemented", NULL)) { + if (strstr(buf, " loongson-mmi")) + flags |= AV_CPU_FLAG_MMI; + if (strstr(buf, " msa")) + flags |= AV_CPU_FLAG_MSA; + + break; + } + } + fclose(f); + return flags; +} +#endif + +int ff_get_cpu_flags_mips(void) +{ +#if defined __linux__ || defined __ANDROID__ + if (cpucfg_available()) + return cpu_flags_cpucfg(); + else + return cpu_flags_cpuinfo(); +#else + /* Assume no SIMD ASE supported */ + return 0; +#endif +} + +size_t ff_get_cpu_max_align_mips(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_MSA) + return 16; + + /* + * MMI itself is 64-bit but quad word load & store + * needs 128-bit align. + */ + if (flags & AV_CPU_FLAG_MMI) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.h new file mode 100644 index 00000000..615dc497 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/cpu.h @@ -0,0 +1,28 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MIPS_CPU_H +#define AVUTIL_MIPS_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_mmi(flags) CPUEXT(flags, MMI) +#define have_msa(flags) CPUEXT(flags, MSA) + +#endif /* AVUTIL_MIPS_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/float_dsp_mips.c b/arm/raspi/third_party/ffmpeg/libavutil/mips/float_dsp_mips.c new file mode 100644 index 00000000..0943d6f3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/float_dsp_mips.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * 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. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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. + * + * Author: Branimir Vasic (bvasic@mips.com) + * Author: Zoran Lukic (zoranl@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Reference: libavutil/float_dsp.c + */ + +#include "config.h" +#include "libavutil/float_dsp.h" +#include "libavutil/mips/asmdefs.h" + +#if HAVE_INLINE_ASM && HAVE_MIPSFPU +#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6 +static void vector_fmul_mips(float *dst, const float *src0, const float *src1, + int len) +{ + int i; + + if (len & 3) { + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i]; + } else { + float *d = (float *)dst; + float *d_end = d + len; + float *s0 = (float *)src0; + float *s1 = (float *)src1; + + float src0_0, src0_1, src0_2, src0_3; + float src1_0, src1_1, src1_2, src1_3; + + __asm__ volatile ( + "1: \n\t" + "lwc1 %[src0_0], 0(%[s0]) \n\t" + "lwc1 %[src1_0], 0(%[s1]) \n\t" + "lwc1 %[src0_1], 4(%[s0]) \n\t" + "lwc1 %[src1_1], 4(%[s1]) \n\t" + "lwc1 %[src0_2], 8(%[s0]) \n\t" + "lwc1 %[src1_2], 8(%[s1]) \n\t" + "lwc1 %[src0_3], 12(%[s0]) \n\t" + "lwc1 %[src1_3], 12(%[s1]) \n\t" + "mul.s %[src0_0], %[src0_0], %[src1_0] \n\t" + "mul.s %[src0_1], %[src0_1], %[src1_1] \n\t" + "mul.s %[src0_2], %[src0_2], %[src1_2] \n\t" + "mul.s %[src0_3], %[src0_3], %[src1_3] \n\t" + "swc1 %[src0_0], 0(%[d]) \n\t" + "swc1 %[src0_1], 4(%[d]) \n\t" + "swc1 %[src0_2], 8(%[d]) \n\t" + "swc1 %[src0_3], 12(%[d]) \n\t" + PTR_ADDIU "%[s0], %[s0], 16 \n\t" + PTR_ADDIU "%[s1], %[s1], 16 \n\t" + PTR_ADDIU "%[d], %[d], 16 \n\t" + "bne %[d], %[d_end], 1b \n\t" + + : [src0_0]"=&f"(src0_0), [src0_1]"=&f"(src0_1), + [src0_2]"=&f"(src0_2), [src0_3]"=&f"(src0_3), + [src1_0]"=&f"(src1_0), [src1_1]"=&f"(src1_1), + [src1_2]"=&f"(src1_2), [src1_3]"=&f"(src1_3), + [d]"+r"(d), [s0]"+r"(s0), [s1]"+r"(s1) + : [d_end]"r"(d_end) + : "memory" + ); + } +} + +static void vector_fmul_scalar_mips(float *dst, const float *src, float mul, + int len) +{ + float temp0, temp1, temp2, temp3; + float *local_src = (float*)src; + float *end = local_src + len; + + /* loop unrolled 4 times */ + __asm__ volatile( + ".set push \n\t" + ".set noreorder \n\t" + "1: \n\t" + "lwc1 %[temp0], 0(%[src]) \n\t" + "lwc1 %[temp1], 4(%[src]) \n\t" + "lwc1 %[temp2], 8(%[src]) \n\t" + "lwc1 %[temp3], 12(%[src]) \n\t" + PTR_ADDIU "%[dst], %[dst], 16 \n\t" + "mul.s %[temp0], %[temp0], %[mul] \n\t" + "mul.s %[temp1], %[temp1], %[mul] \n\t" + "mul.s %[temp2], %[temp2], %[mul] \n\t" + "mul.s %[temp3], %[temp3], %[mul] \n\t" + PTR_ADDIU "%[src], %[src], 16 \n\t" + "swc1 %[temp0], -16(%[dst]) \n\t" + "swc1 %[temp1], -12(%[dst]) \n\t" + "swc1 %[temp2], -8(%[dst]) \n\t" + "bne %[src], %[end], 1b \n\t" + " swc1 %[temp3], -4(%[dst]) \n\t" + ".set pop \n\t" + + : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), + [temp2]"=&f"(temp2), [temp3]"=&f"(temp3), + [dst]"+r"(dst), [src]"+r"(local_src) + : [end]"r"(end), [mul]"f"(mul) + : "memory" + ); +} + +static void vector_fmul_window_mips(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + float * dst_j, *win_j, *src0_i, *src1_j, *dst_i, *win_i; + float temp, temp1, temp2, temp3; + float s0, s01, s1, s11; + float wi, wi1, wi2, wi3; + float wj, wj1, wj2, wj3; + const float * lp_end = win + len; + + win_i = (float *)win; + win_j = (float *)(win + 2 * len -1); + src1_j = (float *)(src1 + len - 1); + src0_i = (float *)src0; + dst_i = (float *)dst; + dst_j = (float *)(dst + 2 * len -1); + + /* loop unrolled 4 times */ + __asm__ volatile ( + "1:" + "lwc1 %[s1], 0(%[src1_j]) \n\t" + "lwc1 %[wi], 0(%[win_i]) \n\t" + "lwc1 %[wj], 0(%[win_j]) \n\t" + "lwc1 %[s11], -4(%[src1_j]) \n\t" + "lwc1 %[wi1], 4(%[win_i]) \n\t" + "lwc1 %[wj1], -4(%[win_j]) \n\t" + "lwc1 %[s0], 0(%[src0_i]) \n\t" + "lwc1 %[s01], 4(%[src0_i]) \n\t" + "mul.s %[temp], %[s1], %[wi] \n\t" + "mul.s %[temp1], %[s1], %[wj] \n\t" + "mul.s %[temp2], %[s11], %[wi1] \n\t" + "mul.s %[temp3], %[s11], %[wj1] \n\t" + "lwc1 %[s1], -8(%[src1_j]) \n\t" + "lwc1 %[wi2], 8(%[win_i]) \n\t" + "lwc1 %[wj2], -8(%[win_j]) \n\t" + "lwc1 %[s11], -12(%[src1_j]) \n\t" + "msub.s %[temp], %[temp], %[s0], %[wj] \n\t" + "madd.s %[temp1], %[temp1], %[s0], %[wi] \n\t" + "msub.s %[temp2], %[temp2], %[s01], %[wj1] \n\t" + "madd.s %[temp3], %[temp3], %[s01], %[wi1] \n\t" + "lwc1 %[wi3], 12(%[win_i]) \n\t" + "lwc1 %[wj3], -12(%[win_j]) \n\t" + "lwc1 %[s0], 8(%[src0_i]) \n\t" + "lwc1 %[s01], 12(%[src0_i]) \n\t" + PTR_ADDIU "%[src1_j],-16 \n\t" + PTR_ADDIU "%[win_i],16 \n\t" + PTR_ADDIU "%[win_j],-16 \n\t" + PTR_ADDIU "%[src0_i],16 \n\t" + "swc1 %[temp], 0(%[dst_i]) \n\t" /* dst[i] = s0*wj - s1*wi; */ + "swc1 %[temp1], 0(%[dst_j]) \n\t" /* dst[j] = s0*wi + s1*wj; */ + "swc1 %[temp2], 4(%[dst_i]) \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */ + "swc1 %[temp3], -4(%[dst_j]) \n\t" /* dst[j-1] = s01*wi1 + s11*wj1; */ + "mul.s %[temp], %[s1], %[wi2] \n\t" + "mul.s %[temp1], %[s1], %[wj2] \n\t" + "mul.s %[temp2], %[s11], %[wi3] \n\t" + "mul.s %[temp3], %[s11], %[wj3] \n\t" + "msub.s %[temp], %[temp], %[s0], %[wj2] \n\t" + "madd.s %[temp1], %[temp1], %[s0], %[wi2] \n\t" + "msub.s %[temp2], %[temp2], %[s01], %[wj3] \n\t" + "madd.s %[temp3], %[temp3], %[s01], %[wi3] \n\t" + "swc1 %[temp], 8(%[dst_i]) \n\t" /* dst[i+2] = s0*wj2 - s1*wi2; */ + "swc1 %[temp1], -8(%[dst_j]) \n\t" /* dst[j-2] = s0*wi2 + s1*wj2; */ + "swc1 %[temp2], 12(%[dst_i]) \n\t" /* dst[i+2] = s01*wj3 - s11*wi3; */ + "swc1 %[temp3], -12(%[dst_j]) \n\t" /* dst[j-3] = s01*wi3 + s11*wj3; */ + PTR_ADDIU "%[dst_i],16 \n\t" + PTR_ADDIU "%[dst_j],-16 \n\t" + "bne %[win_i], %[lp_end], 1b \n\t" + : [temp]"=&f"(temp), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), + [temp3]"=&f"(temp3), [src0_i]"+r"(src0_i), [win_i]"+r"(win_i), + [src1_j]"+r"(src1_j), [win_j]"+r"(win_j), [dst_i]"+r"(dst_i), + [dst_j]"+r"(dst_j), [s0] "=&f"(s0), [s01]"=&f"(s01), [s1] "=&f"(s1), + [s11]"=&f"(s11), [wi] "=&f"(wi), [wj] "=&f"(wj), [wi2]"=&f"(wi2), + [wj2]"=&f"(wj2), [wi3]"=&f"(wi3), [wj3]"=&f"(wj3), [wi1]"=&f"(wi1), + [wj1]"=&f"(wj1) + : [lp_end]"r"(lp_end) + : "memory" + ); +} + +static void butterflies_float_mips(float *av_restrict v1, float *av_restrict v2, + int len) +{ + float temp0, temp1, temp2, temp3, temp4; + float temp5, temp6, temp7, temp8, temp9; + float temp10, temp11, temp12, temp13, temp14, temp15; + int pom; + pom = (len >> 2)-1; + + /* loop unrolled 4 times */ + __asm__ volatile ( + "lwc1 %[temp0], 0(%[v1]) \n\t" + "lwc1 %[temp1], 4(%[v1]) \n\t" + "lwc1 %[temp2], 8(%[v1]) \n\t" + "lwc1 %[temp3], 12(%[v1]) \n\t" + "lwc1 %[temp4], 0(%[v2]) \n\t" + "lwc1 %[temp5], 4(%[v2]) \n\t" + "lwc1 %[temp6], 8(%[v2]) \n\t" + "lwc1 %[temp7], 12(%[v2]) \n\t" + "beq %[pom], $zero, 2f \n\t" + "1: \n\t" + "sub.s %[temp8], %[temp0], %[temp4] \n\t" + "add.s %[temp9], %[temp0], %[temp4] \n\t" + "sub.s %[temp10], %[temp1], %[temp5] \n\t" + "add.s %[temp11], %[temp1], %[temp5] \n\t" + "sub.s %[temp12], %[temp2], %[temp6] \n\t" + "add.s %[temp13], %[temp2], %[temp6] \n\t" + "sub.s %[temp14], %[temp3], %[temp7] \n\t" + "add.s %[temp15], %[temp3], %[temp7] \n\t" + PTR_ADDIU "%[v1], %[v1], 16 \n\t" + PTR_ADDIU "%[v2], %[v2], 16 \n\t" + "addiu %[pom], %[pom], -1 \n\t" + "lwc1 %[temp0], 0(%[v1]) \n\t" + "lwc1 %[temp1], 4(%[v1]) \n\t" + "lwc1 %[temp2], 8(%[v1]) \n\t" + "lwc1 %[temp3], 12(%[v1]) \n\t" + "lwc1 %[temp4], 0(%[v2]) \n\t" + "lwc1 %[temp5], 4(%[v2]) \n\t" + "lwc1 %[temp6], 8(%[v2]) \n\t" + "lwc1 %[temp7], 12(%[v2]) \n\t" + "swc1 %[temp9], -16(%[v1]) \n\t" + "swc1 %[temp8], -16(%[v2]) \n\t" + "swc1 %[temp11], -12(%[v1]) \n\t" + "swc1 %[temp10], -12(%[v2]) \n\t" + "swc1 %[temp13], -8(%[v1]) \n\t" + "swc1 %[temp12], -8(%[v2]) \n\t" + "swc1 %[temp15], -4(%[v1]) \n\t" + "swc1 %[temp14], -4(%[v2]) \n\t" + "bgtz %[pom], 1b \n\t" + "2: \n\t" + "sub.s %[temp8], %[temp0], %[temp4] \n\t" + "add.s %[temp9], %[temp0], %[temp4] \n\t" + "sub.s %[temp10], %[temp1], %[temp5] \n\t" + "add.s %[temp11], %[temp1], %[temp5] \n\t" + "sub.s %[temp12], %[temp2], %[temp6] \n\t" + "add.s %[temp13], %[temp2], %[temp6] \n\t" + "sub.s %[temp14], %[temp3], %[temp7] \n\t" + "add.s %[temp15], %[temp3], %[temp7] \n\t" + "swc1 %[temp9], 0(%[v1]) \n\t" + "swc1 %[temp8], 0(%[v2]) \n\t" + "swc1 %[temp11], 4(%[v1]) \n\t" + "swc1 %[temp10], 4(%[v2]) \n\t" + "swc1 %[temp13], 8(%[v1]) \n\t" + "swc1 %[temp12], 8(%[v2]) \n\t" + "swc1 %[temp15], 12(%[v1]) \n\t" + "swc1 %[temp14], 12(%[v2]) \n\t" + + : [v1]"+r"(v1), [v2]"+r"(v2), [pom]"+r"(pom), [temp0] "=&f" (temp0), + [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), [temp3]"=&f"(temp3), + [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), [temp6]"=&f"(temp6), + [temp7]"=&f"(temp7), [temp8]"=&f"(temp8), [temp9]"=&f"(temp9), + [temp10]"=&f"(temp10), [temp11]"=&f"(temp11), [temp12]"=&f"(temp12), + [temp13]"=&f"(temp13), [temp14]"=&f"(temp14), [temp15]"=&f"(temp15) + : + : "memory" + ); +} + +static void vector_fmul_reverse_mips(float *dst, const float *src0, const float *src1, int len){ + int i; + float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; + src1 += len-1; + + for(i=0; i<(len>>2); i++) + { + /* loop unrolled 4 times */ + __asm__ volatile( + "lwc1 %[temp0], 0(%[src0]) \n\t" + "lwc1 %[temp1], 0(%[src1]) \n\t" + "lwc1 %[temp2], 4(%[src0]) \n\t" + "lwc1 %[temp3], -4(%[src1]) \n\t" + "lwc1 %[temp4], 8(%[src0]) \n\t" + "lwc1 %[temp5], -8(%[src1]) \n\t" + "lwc1 %[temp6], 12(%[src0]) \n\t" + "lwc1 %[temp7], -12(%[src1]) \n\t" + "mul.s %[temp0], %[temp1], %[temp0] \n\t" + "mul.s %[temp2], %[temp3], %[temp2] \n\t" + "mul.s %[temp4], %[temp5], %[temp4] \n\t" + "mul.s %[temp6], %[temp7], %[temp6] \n\t" + PTR_ADDIU "%[src0], %[src0], 16 \n\t" + PTR_ADDIU "%[src1], %[src1], -16 \n\t" + PTR_ADDIU "%[dst], %[dst], 16 \n\t" + "swc1 %[temp0], -16(%[dst]) \n\t" + "swc1 %[temp2], -12(%[dst]) \n\t" + "swc1 %[temp4], -8(%[dst]) \n\t" + "swc1 %[temp6], -4(%[dst]) \n\t" + + : [dst]"+r"(dst), [src0]"+r"(src0), [src1]"+r"(src1), + [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),[temp2]"=&f"(temp2), + [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5), + [temp6]"=&f"(temp6), [temp7]"=&f"(temp7) + : + : "memory" + ); + } +} +#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */ +#endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */ + +void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp) { +#if HAVE_INLINE_ASM && HAVE_MIPSFPU +#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6 + fdsp->vector_fmul = vector_fmul_mips; + fdsp->vector_fmul_scalar = vector_fmul_scalar_mips; + fdsp->vector_fmul_window = vector_fmul_window_mips; + fdsp->butterflies_float = butterflies_float_mips; + fdsp->vector_fmul_reverse = vector_fmul_reverse_mips; +#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */ +#endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */ +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/generic_macros_msa.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/generic_macros_msa.h new file mode 100644 index 00000000..1486f729 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/generic_macros_msa.h @@ -0,0 +1,2821 @@ +/* + * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MIPS_GENERIC_MACROS_MSA_H +#define AVUTIL_MIPS_GENERIC_MACROS_MSA_H + +#include +#include +#include + +#define ALIGNMENT 16 +#define ALLOC_ALIGNED(align) __attribute__ ((aligned((align) << 1))) + +#define LD_V(RTYPE, psrc) *((RTYPE *)(psrc)) +#define LD_UB(...) LD_V(v16u8, __VA_ARGS__) +#define LD_SB(...) LD_V(v16i8, __VA_ARGS__) +#define LD_UH(...) LD_V(v8u16, __VA_ARGS__) +#define LD_SH(...) LD_V(v8i16, __VA_ARGS__) +#define LD_UW(...) LD_V(v4u32, __VA_ARGS__) +#define LD_SW(...) LD_V(v4i32, __VA_ARGS__) + +#define ST_V(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in) +#define ST_UB(...) ST_V(v16u8, __VA_ARGS__) +#define ST_SB(...) ST_V(v16i8, __VA_ARGS__) +#define ST_UH(...) ST_V(v8u16, __VA_ARGS__) +#define ST_SH(...) ST_V(v8i16, __VA_ARGS__) +#define ST_UW(...) ST_V(v4u32, __VA_ARGS__) +#define ST_SW(...) ST_V(v4i32, __VA_ARGS__) + +#if (__mips_isa_rev >= 6) + #define LH(psrc) \ + ( { \ + uint16_t val_lh_m = *(uint16_t *)(psrc); \ + val_lh_m; \ + } ) + + #define LW(psrc) \ + ( { \ + uint32_t val_lw_m = *(uint32_t *)(psrc); \ + val_lw_m; \ + } ) + + #if (__mips == 64) + #define LD(psrc) \ + ( { \ + uint64_t val_ld_m = *(uint64_t *)(psrc); \ + val_ld_m; \ + } ) + #else // !(__mips == 64) + #define LD(psrc) \ + ( { \ + uint8_t *psrc_ld_m = (uint8_t *) (psrc); \ + uint32_t val0_ld_m, val1_ld_m; \ + uint64_t val_ld_m = 0; \ + \ + val0_ld_m = LW(psrc_ld_m); \ + val1_ld_m = LW(psrc_ld_m + 4); \ + \ + val_ld_m = (uint64_t) (val1_ld_m); \ + val_ld_m = (uint64_t) ((val_ld_m << 32) & 0xFFFFFFFF00000000); \ + val_ld_m = (uint64_t) (val_ld_m | (uint64_t) val0_ld_m); \ + \ + val_ld_m; \ + } ) + #endif // (__mips == 64) + + #define SH(val, pdst) *(uint16_t *)(pdst) = (val); + #define SW(val, pdst) *(uint32_t *)(pdst) = (val); + #define SD(val, pdst) *(uint64_t *)(pdst) = (val); + +#else // !(__mips_isa_rev >= 6) + #define LH(psrc) \ + ( { \ + uint8_t *psrc_lh_m = (uint8_t *) (psrc); \ + uint16_t val_lh_m; \ + \ + __asm__ volatile ( \ + "ulh %[val_lh_m], %[psrc_lh_m] \n\t" \ + \ + : [val_lh_m] "=r" (val_lh_m) \ + : [psrc_lh_m] "m" (*psrc_lh_m) \ + ); \ + \ + val_lh_m; \ + } ) + + #define LW(psrc) \ + ( { \ + uint8_t *psrc_lw_m = (uint8_t *) (psrc); \ + uint32_t val_lw_m; \ + \ + __asm__ volatile ( \ + "lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \ + "lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \ + \ + : [val_lw_m] "=&r"(val_lw_m) \ + : [psrc_lw_m] "r"(psrc_lw_m) \ + ); \ + \ + val_lw_m; \ + } ) + + #if (__mips == 64) + #define LD(psrc) \ + ( { \ + uint8_t *psrc_ld_m = (uint8_t *) (psrc); \ + uint64_t val_ld_m = 0; \ + \ + __asm__ volatile ( \ + "ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \ + "ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \ + \ + : [val_ld_m] "=&r" (val_ld_m) \ + : [psrc_ld_m] "r" (psrc_ld_m) \ + ); \ + \ + val_ld_m; \ + } ) + #else // !(__mips == 64) + #define LD(psrc) \ + ( { \ + uint8_t *psrc_ld_m = (uint8_t *) (psrc); \ + uint32_t val0_ld_m, val1_ld_m; \ + uint64_t val_ld_m = 0; \ + \ + val0_ld_m = LW(psrc_ld_m); \ + val1_ld_m = LW(psrc_ld_m + 4); \ + \ + val_ld_m = (uint64_t) (val1_ld_m); \ + val_ld_m = (uint64_t) ((val_ld_m << 32) & 0xFFFFFFFF00000000); \ + val_ld_m = (uint64_t) (val_ld_m | (uint64_t) val0_ld_m); \ + \ + val_ld_m; \ + } ) + #endif // (__mips == 64) + + #define SH(val, pdst) \ + { \ + uint8_t *pdst_sh_m = (uint8_t *) (pdst); \ + uint16_t val_sh_m = (val); \ + \ + __asm__ volatile ( \ + "ush %[val_sh_m], %[pdst_sh_m] \n\t" \ + \ + : [pdst_sh_m] "=m" (*pdst_sh_m) \ + : [val_sh_m] "r" (val_sh_m) \ + ); \ + } + + #define SW(val, pdst) \ + { \ + uint8_t *pdst_sw_m = (uint8_t *) (pdst); \ + uint32_t val_sw_m = (val); \ + \ + __asm__ volatile ( \ + "usw %[val_sw_m], %[pdst_sw_m] \n\t" \ + \ + : [pdst_sw_m] "=m" (*pdst_sw_m) \ + : [val_sw_m] "r" (val_sw_m) \ + ); \ + } + + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint32_t val0_sd_m, val1_sd_m; \ + \ + val0_sd_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \ + val1_sd_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \ + \ + SW(val0_sd_m, pdst_sd_m); \ + SW(val1_sd_m, pdst_sd_m + 4); \ + } +#endif // (__mips_isa_rev >= 6) + +/* Description : Load 4 words with stride + Arguments : Inputs - psrc (source pointer to load from) + - stride + Outputs - out0, out1, out2, out3 + Details : Loads word in 'out0' from (psrc) + Loads word in 'out1' from (psrc + stride) + Loads word in 'out2' from (psrc + 2 * stride) + Loads word in 'out3' from (psrc + 3 * stride) +*/ +#define LW4(psrc, stride, out0, out1, out2, out3) \ +{ \ + out0 = LW((psrc)); \ + out1 = LW((psrc) + stride); \ + out2 = LW((psrc) + 2 * stride); \ + out3 = LW((psrc) + 3 * stride); \ +} + +#define LW2(psrc, stride, out0, out1) \ +{ \ + out0 = LW((psrc)); \ + out1 = LW((psrc) + stride); \ +} + +/* Description : Load double words with stride + Arguments : Inputs - psrc (source pointer to load from) + - stride + Outputs - out0, out1 + Details : Loads double word in 'out0' from (psrc) + Loads double word in 'out1' from (psrc + stride) +*/ +#define LD2(psrc, stride, out0, out1) \ +{ \ + out0 = LD((psrc)); \ + out1 = LD((psrc) + stride); \ +} +#define LD4(psrc, stride, out0, out1, out2, out3) \ +{ \ + LD2((psrc), stride, out0, out1); \ + LD2((psrc) + 2 * stride, stride, out2, out3); \ +} + +/* Description : Store 4 words with stride + Arguments : Inputs - in0, in1, in2, in3, pdst, stride + Details : Stores word from 'in0' to (pdst) + Stores word from 'in1' to (pdst + stride) + Stores word from 'in2' to (pdst + 2 * stride) + Stores word from 'in3' to (pdst + 3 * stride) +*/ +#define SW4(in0, in1, in2, in3, pdst, stride) \ +{ \ + SW(in0, (pdst)) \ + SW(in1, (pdst) + stride); \ + SW(in2, (pdst) + 2 * stride); \ + SW(in3, (pdst) + 3 * stride); \ +} + +/* Description : Store 4 double words with stride + Arguments : Inputs - in0, in1, in2, in3, pdst, stride + Details : Stores double word from 'in0' to (pdst) + Stores double word from 'in1' to (pdst + stride) + Stores double word from 'in2' to (pdst + 2 * stride) + Stores double word from 'in3' to (pdst + 3 * stride) +*/ +#define SD4(in0, in1, in2, in3, pdst, stride) \ +{ \ + SD(in0, (pdst)) \ + SD(in1, (pdst) + stride); \ + SD(in2, (pdst) + 2 * stride); \ + SD(in3, (pdst) + 3 * stride); \ +} + +/* Description : Load vector elements with stride + Arguments : Inputs - psrc (source pointer to load from) + - stride + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Loads elements in 'out0' from (psrc) + Loads elements in 'out1' from (psrc + stride) +*/ +#define LD_V2(RTYPE, psrc, stride, out0, out1) \ +{ \ + out0 = LD_V(RTYPE, (psrc)); \ + out1 = LD_V(RTYPE, (psrc) + stride); \ +} +#define LD_UB2(...) LD_V2(v16u8, __VA_ARGS__) +#define LD_SB2(...) LD_V2(v16i8, __VA_ARGS__) +#define LD_UH2(...) LD_V2(v8u16, __VA_ARGS__) +#define LD_SH2(...) LD_V2(v8i16, __VA_ARGS__) +#define LD_SW2(...) LD_V2(v4i32, __VA_ARGS__) + +#define LD_V3(RTYPE, psrc, stride, out0, out1, out2) \ +{ \ + LD_V2(RTYPE, (psrc), stride, out0, out1); \ + out2 = LD_V(RTYPE, (psrc) + 2 * stride); \ +} +#define LD_UB3(...) LD_V3(v16u8, __VA_ARGS__) +#define LD_SB3(...) LD_V3(v16i8, __VA_ARGS__) + +#define LD_V4(RTYPE, psrc, stride, out0, out1, out2, out3) \ +{ \ + LD_V2(RTYPE, (psrc), stride, out0, out1); \ + LD_V2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \ +} +#define LD_UB4(...) LD_V4(v16u8, __VA_ARGS__) +#define LD_SB4(...) LD_V4(v16i8, __VA_ARGS__) +#define LD_UH4(...) LD_V4(v8u16, __VA_ARGS__) +#define LD_SH4(...) LD_V4(v8i16, __VA_ARGS__) +#define LD_SW4(...) LD_V4(v4i32, __VA_ARGS__) + +#define LD_V5(RTYPE, psrc, stride, out0, out1, out2, out3, out4) \ +{ \ + LD_V4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ + out4 = LD_V(RTYPE, (psrc) + 4 * stride); \ +} +#define LD_UB5(...) LD_V5(v16u8, __VA_ARGS__) +#define LD_SB5(...) LD_V5(v16i8, __VA_ARGS__) + +#define LD_V6(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5) \ +{ \ + LD_V4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ + LD_V2(RTYPE, (psrc) + 4 * stride, stride, out4, out5); \ +} +#define LD_UB6(...) LD_V6(v16u8, __VA_ARGS__) +#define LD_SB6(...) LD_V6(v16i8, __VA_ARGS__) +#define LD_UH6(...) LD_V6(v8u16, __VA_ARGS__) +#define LD_SH6(...) LD_V6(v8i16, __VA_ARGS__) + +#define LD_V7(RTYPE, psrc, stride, \ + out0, out1, out2, out3, out4, out5, out6) \ +{ \ + LD_V5(RTYPE, (psrc), stride, out0, out1, out2, out3, out4); \ + LD_V2(RTYPE, (psrc) + 5 * stride, stride, out5, out6); \ +} +#define LD_UB7(...) LD_V7(v16u8, __VA_ARGS__) +#define LD_SB7(...) LD_V7(v16i8, __VA_ARGS__) + +#define LD_V8(RTYPE, psrc, stride, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + LD_V4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ + LD_V4(RTYPE, (psrc) + 4 * stride, stride, out4, out5, out6, out7); \ +} +#define LD_UB8(...) LD_V8(v16u8, __VA_ARGS__) +#define LD_SB8(...) LD_V8(v16i8, __VA_ARGS__) +#define LD_UH8(...) LD_V8(v8u16, __VA_ARGS__) +#define LD_SH8(...) LD_V8(v8i16, __VA_ARGS__) +#define LD_SW8(...) LD_V8(v4i32, __VA_ARGS__) + +#define LD_V16(RTYPE, psrc, stride, \ + out0, out1, out2, out3, out4, out5, out6, out7, \ + out8, out9, out10, out11, out12, out13, out14, out15) \ +{ \ + LD_V8(RTYPE, (psrc), stride, \ + out0, out1, out2, out3, out4, out5, out6, out7); \ + LD_V8(RTYPE, (psrc) + 8 * stride, stride, \ + out8, out9, out10, out11, out12, out13, out14, out15); \ +} +#define LD_SH16(...) LD_V16(v8i16, __VA_ARGS__) + +/* Description : Store vectors with stride + Arguments : Inputs - in0, in1, stride + Outputs - pdst (destination pointer to store to) + Details : Stores elements from 'in0' to (pdst) + Stores elements from 'in1' to (pdst + stride) +*/ +#define ST_V2(RTYPE, in0, in1, pdst, stride) \ +{ \ + ST_V(RTYPE, in0, (pdst)); \ + ST_V(RTYPE, in1, (pdst) + stride); \ +} +#define ST_UB2(...) ST_V2(v16u8, __VA_ARGS__) +#define ST_SB2(...) ST_V2(v16i8, __VA_ARGS__) +#define ST_UH2(...) ST_V2(v8u16, __VA_ARGS__) +#define ST_SH2(...) ST_V2(v8i16, __VA_ARGS__) +#define ST_SW2(...) ST_V2(v4i32, __VA_ARGS__) + +#define ST_V4(RTYPE, in0, in1, in2, in3, pdst, stride) \ +{ \ + ST_V2(RTYPE, in0, in1, (pdst), stride); \ + ST_V2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \ +} +#define ST_UB4(...) ST_V4(v16u8, __VA_ARGS__) +#define ST_SB4(...) ST_V4(v16i8, __VA_ARGS__) +#define ST_SH4(...) ST_V4(v8i16, __VA_ARGS__) +#define ST_SW4(...) ST_V4(v4i32, __VA_ARGS__) + +#define ST_V6(RTYPE, in0, in1, in2, in3, in4, in5, pdst, stride) \ +{ \ + ST_V4(RTYPE, in0, in1, in2, in3, (pdst), stride); \ + ST_V2(RTYPE, in4, in5, (pdst) + 4 * stride, stride); \ +} +#define ST_SH6(...) ST_V6(v8i16, __VA_ARGS__) + +#define ST_V8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + ST_V4(RTYPE, in0, in1, in2, in3, (pdst), stride); \ + ST_V4(RTYPE, in4, in5, in6, in7, (pdst) + 4 * stride, stride); \ +} +#define ST_UB8(...) ST_V8(v16u8, __VA_ARGS__) +#define ST_SH8(...) ST_V8(v8i16, __VA_ARGS__) +#define ST_SW8(...) ST_V8(v4i32, __VA_ARGS__) + +/* Description : Store half word elements of vector with stride + * Arguments : Inputs - in source vector + * - pdst (destination pointer to store to) + * - stride + * Details : Stores half word 'idx0' from 'in' to (pdst) + * Stores half word 'idx1' from 'in' to (pdst + stride) + * Similar for other elements + */ +#define ST_H1(in, idx, pdst) \ +{ \ + uint16_t out0_m; \ + out0_m = __msa_copy_u_h((v8i16) in, idx); \ + SH(out0_m, (pdst)); \ +} +#define ST_H2(in, idx0, idx1, pdst, stride) \ +{ \ + uint16_t out0_m, out1_m; \ + out0_m = __msa_copy_u_h((v8i16) in, idx0); \ + out1_m = __msa_copy_u_h((v8i16) in, idx1); \ + SH(out0_m, (pdst)); \ + SH(out1_m, (pdst) + stride); \ +} +#define ST_H4(in, idx0, idx1, idx2, idx3, pdst, stride) \ +{ \ + uint16_t out0_m, out1_m, out2_m, out3_m; \ + out0_m = __msa_copy_u_h((v8i16) in, idx0); \ + out1_m = __msa_copy_u_h((v8i16) in, idx1); \ + out2_m = __msa_copy_u_h((v8i16) in, idx2); \ + out3_m = __msa_copy_u_h((v8i16) in, idx3); \ + SH(out0_m, (pdst)); \ + SH(out1_m, (pdst) + stride); \ + SH(out2_m, (pdst) + 2 * stride); \ + SH(out3_m, (pdst) + 3 * stride); \ +} +#define ST_H8(in, idx0, idx1, idx2, idx3, idx4, idx5, \ + idx6, idx7, pdst, stride) \ +{ \ + ST_H4(in, idx0, idx1, idx2, idx3, pdst, stride) \ + ST_H4(in, idx4, idx5, idx6, idx7, (pdst) + 4*stride, stride) \ +} + +/* Description : Store word elements of vector with stride + * Arguments : Inputs - in source vector + * - pdst (destination pointer to store to) + * - stride + * Details : Stores word 'idx0' from 'in' to (pdst) + * Stores word 'idx1' from 'in' to (pdst + stride) + * Similar for other elements + */ +#define ST_W1(in, idx, pdst) \ +{ \ + uint32_t out0_m; \ + out0_m = __msa_copy_u_w((v4i32) in, idx); \ + SW(out0_m, (pdst)); \ +} +#define ST_W2(in, idx0, idx1, pdst, stride) \ +{ \ + uint32_t out0_m, out1_m; \ + out0_m = __msa_copy_u_w((v4i32) in, idx0); \ + out1_m = __msa_copy_u_w((v4i32) in, idx1); \ + SW(out0_m, (pdst)); \ + SW(out1_m, (pdst) + stride); \ +} +#define ST_W4(in, idx0, idx1, idx2, idx3, pdst, stride) \ +{ \ + uint32_t out0_m, out1_m, out2_m, out3_m; \ + out0_m = __msa_copy_u_w((v4i32) in, idx0); \ + out1_m = __msa_copy_u_w((v4i32) in, idx1); \ + out2_m = __msa_copy_u_w((v4i32) in, idx2); \ + out3_m = __msa_copy_u_w((v4i32) in, idx3); \ + SW(out0_m, (pdst)); \ + SW(out1_m, (pdst) + stride); \ + SW(out2_m, (pdst) + 2*stride); \ + SW(out3_m, (pdst) + 3*stride); \ +} +#define ST_W8(in0, in1, idx0, idx1, idx2, idx3, \ + idx4, idx5, idx6, idx7, pdst, stride) \ +{ \ + ST_W4(in0, idx0, idx1, idx2, idx3, pdst, stride) \ + ST_W4(in1, idx4, idx5, idx6, idx7, pdst + 4*stride, stride) \ +} + +/* Description : Store double word elements of vector with stride + * Arguments : Inputs - in source vector + * - pdst (destination pointer to store to) + * - stride + * Details : Stores double word 'idx0' from 'in' to (pdst) + * Stores double word 'idx1' from 'in' to (pdst + stride) + * Similar for other elements + */ +#define ST_D1(in, idx, pdst) \ +{ \ + uint64_t out0_m; \ + out0_m = __msa_copy_u_d((v2i64) in, idx); \ + SD(out0_m, (pdst)); \ +} +#define ST_D2(in, idx0, idx1, pdst, stride) \ +{ \ + uint64_t out0_m, out1_m; \ + out0_m = __msa_copy_u_d((v2i64) in, idx0); \ + out1_m = __msa_copy_u_d((v2i64) in, idx1); \ + SD(out0_m, (pdst)); \ + SD(out1_m, (pdst) + stride); \ +} +#define ST_D4(in0, in1, idx0, idx1, idx2, idx3, pdst, stride) \ +{ \ + uint64_t out0_m, out1_m, out2_m, out3_m; \ + out0_m = __msa_copy_u_d((v2i64) in0, idx0); \ + out1_m = __msa_copy_u_d((v2i64) in0, idx1); \ + out2_m = __msa_copy_u_d((v2i64) in1, idx2); \ + out3_m = __msa_copy_u_d((v2i64) in1, idx3); \ + SD(out0_m, (pdst)); \ + SD(out1_m, (pdst) + stride); \ + SD(out2_m, (pdst) + 2 * stride); \ + SD(out3_m, (pdst) + 3 * stride); \ +} +#define ST_D8(in0, in1, in2, in3, idx0, idx1, idx2, idx3, \ + idx4, idx5, idx6, idx7, pdst, stride) \ +{ \ + ST_D4(in0, in1, idx0, idx1, idx2, idx3, pdst, stride) \ + ST_D4(in2, in3, idx4, idx5, idx6, idx7, pdst + 4 * stride, stride) \ +} + +/* Description : Store as 12x8 byte block to destination memory from + input vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Index 0 double word element from input vector 'in0' is copied + and stored to destination memory at (pblk_12x8_m) followed by + index 2 word element from same input vector 'in0' at + (pblk_12x8_m + 8) + Similar to remaining lines +*/ +#define ST12x8_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + uint64_t out0_m, out1_m, out2_m, out3_m; \ + uint64_t out4_m, out5_m, out6_m, out7_m; \ + uint32_t out8_m, out9_m, out10_m, out11_m; \ + uint32_t out12_m, out13_m, out14_m, out15_m; \ + uint8_t *pblk_12x8_m = (uint8_t *) (pdst); \ + \ + out0_m = __msa_copy_u_d((v2i64) in0, 0); \ + out1_m = __msa_copy_u_d((v2i64) in1, 0); \ + out2_m = __msa_copy_u_d((v2i64) in2, 0); \ + out3_m = __msa_copy_u_d((v2i64) in3, 0); \ + out4_m = __msa_copy_u_d((v2i64) in4, 0); \ + out5_m = __msa_copy_u_d((v2i64) in5, 0); \ + out6_m = __msa_copy_u_d((v2i64) in6, 0); \ + out7_m = __msa_copy_u_d((v2i64) in7, 0); \ + \ + out8_m = __msa_copy_u_w((v4i32) in0, 2); \ + out9_m = __msa_copy_u_w((v4i32) in1, 2); \ + out10_m = __msa_copy_u_w((v4i32) in2, 2); \ + out11_m = __msa_copy_u_w((v4i32) in3, 2); \ + out12_m = __msa_copy_u_w((v4i32) in4, 2); \ + out13_m = __msa_copy_u_w((v4i32) in5, 2); \ + out14_m = __msa_copy_u_w((v4i32) in6, 2); \ + out15_m = __msa_copy_u_w((v4i32) in7, 2); \ + \ + SD(out0_m, pblk_12x8_m); \ + SW(out8_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out1_m, pblk_12x8_m); \ + SW(out9_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out2_m, pblk_12x8_m); \ + SW(out10_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out3_m, pblk_12x8_m); \ + SW(out11_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out4_m, pblk_12x8_m); \ + SW(out12_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out5_m, pblk_12x8_m); \ + SW(out13_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out6_m, pblk_12x8_m); \ + SW(out14_m, pblk_12x8_m + 8); \ + pblk_12x8_m += stride; \ + SD(out7_m, pblk_12x8_m); \ + SW(out15_m, pblk_12x8_m + 8); \ +} + +/* Description : average with rounding (in0 + in1 + 1) / 2. + Arguments : Inputs - in0, in1, in2, in3, + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Each byte element from 'in0' vector is added with each byte + element from 'in1' vector. The addition of the elements plus 1 + (for rounding) is done unsigned with full precision, + i.e. the result has one extra bit. Unsigned division by 2 + (or logical shift right by one bit) is performed before writing + the result to vector 'out0' + Similar for the pair of 'in2' and 'in3' +*/ +#define AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_aver_u_b((v16u8) in0, (v16u8) in1); \ + out1 = (RTYPE) __msa_aver_u_b((v16u8) in2, (v16u8) in3); \ +} +#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__) + +#define AVER_UB4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1) \ + AVER_UB2(RTYPE, in4, in5, in6, in7, out2, out3) \ +} +#define AVER_UB4_UB(...) AVER_UB4(v16u8, __VA_ARGS__) + +/* Description : Immediate number of columns to slide + Arguments : Inputs - s, d, slide_val + Outputs - out + Return Type - as per RTYPE + Details : Byte elements from 'd' vector are slide into 's' by + number of elements specified by 'slide_val' +*/ +#define SLDI_B(RTYPE, d, s, slide_val, out) \ +{ \ + out = (RTYPE) __msa_sldi_b((v16i8) d, (v16i8) s, slide_val); \ +} + +#define SLDI_B2(RTYPE, d0, s0, d1, s1, slide_val, out0, out1) \ +{ \ + SLDI_B(RTYPE, d0, s0, slide_val, out0) \ + SLDI_B(RTYPE, d1, s1, slide_val, out1) \ +} +#define SLDI_B2_UB(...) SLDI_B2(v16u8, __VA_ARGS__) +#define SLDI_B2_SB(...) SLDI_B2(v16i8, __VA_ARGS__) +#define SLDI_B2_SH(...) SLDI_B2(v8i16, __VA_ARGS__) +#define SLDI_B2_SW(...) SLDI_B2(v4i32, __VA_ARGS__) + +#define SLDI_B3(RTYPE, d0, s0, d1, s1, d2, s2, slide_val, \ + out0, out1, out2) \ +{ \ + SLDI_B2(RTYPE, d0, s0, d1, s1, slide_val, out0, out1) \ + SLDI_B(RTYPE, d2, s2, slide_val, out2) \ +} +#define SLDI_B3_UB(...) SLDI_B3(v16u8, __VA_ARGS__) +#define SLDI_B3_SB(...) SLDI_B3(v16i8, __VA_ARGS__) +#define SLDI_B3_UH(...) SLDI_B3(v8u16, __VA_ARGS__) + +#define SLDI_B4(RTYPE, d0, s0, d1, s1, d2, s2, d3, s3, \ + slide_val, out0, out1, out2, out3) \ +{ \ + SLDI_B2(RTYPE, d0, s0, d1, s1, slide_val, out0, out1) \ + SLDI_B2(RTYPE, d2, s2, d3, s3, slide_val, out2, out3) \ +} +#define SLDI_B4_UB(...) SLDI_B4(v16u8, __VA_ARGS__) +#define SLDI_B4_SB(...) SLDI_B4(v16i8, __VA_ARGS__) +#define SLDI_B4_SH(...) SLDI_B4(v8i16, __VA_ARGS__) + +/* Description : Shuffle byte vector elements as per mask vector + Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Selective byte elements from in0 & in1 are copied to out0 as + per control vector mask0 + Selective byte elements from in2 & in3 are copied to out1 as + per control vector mask1 +*/ +#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \ + out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \ +} +#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__) +#define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__) +#define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__) +#define VSHF_B2_SH(...) VSHF_B2(v8i16, __VA_ARGS__) + +#define VSHF_B3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2, \ + out0, out1, out2) \ +{ \ + VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1); \ + out2 = (RTYPE) __msa_vshf_b((v16i8) mask2, (v16i8) in5, (v16i8) in4); \ +} +#define VSHF_B3_SB(...) VSHF_B3(v16i8, __VA_ARGS__) + +#define VSHF_B4(RTYPE, in0, in1, mask0, mask1, mask2, mask3, \ + out0, out1, out2, out3) \ +{ \ + VSHF_B2(RTYPE, in0, in1, in0, in1, mask0, mask1, out0, out1); \ + VSHF_B2(RTYPE, in0, in1, in0, in1, mask2, mask3, out2, out3); \ +} +#define VSHF_B4_SB(...) VSHF_B4(v16i8, __VA_ARGS__) +#define VSHF_B4_SH(...) VSHF_B4(v8i16, __VA_ARGS__) + +/* Description : Shuffle halfword vector elements as per mask vector + Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Selective halfword elements from in0 & in1 are copied to out0 + as per control vector mask0 + Selective halfword elements from in2 & in3 are copied to out1 + as per control vector mask1 +*/ +#define VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_vshf_h((v8i16) mask0, (v8i16) in1, (v8i16) in0); \ + out1 = (RTYPE) __msa_vshf_h((v8i16) mask1, (v8i16) in3, (v8i16) in2); \ +} +#define VSHF_H2_SH(...) VSHF_H2(v8i16, __VA_ARGS__) + +#define VSHF_H3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2, \ + out0, out1, out2) \ +{ \ + VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1); \ + out2 = (RTYPE) __msa_vshf_h((v8i16) mask2, (v8i16) in5, (v8i16) in4); \ +} +#define VSHF_H3_SH(...) VSHF_H3(v8i16, __VA_ARGS__) + +/* Description : Shuffle byte vector elements as per mask vector + Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Selective byte elements from in0 & in1 are copied to out0 as + per control vector mask0 + Selective byte elements from in2 & in3 are copied to out1 as + per control vector mask1 +*/ +#define VSHF_W2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_vshf_w((v4i32) mask0, (v4i32) in1, (v4i32) in0); \ + out1 = (RTYPE) __msa_vshf_w((v4i32) mask1, (v4i32) in3, (v4i32) in2); \ +} +#define VSHF_W2_SB(...) VSHF_W2(v16i8, __VA_ARGS__) + +/* Description : Dot product of byte vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Unsigned byte elements from mult0 are multiplied with + unsigned byte elements from cnst0 producing a result + twice the size of input i.e. unsigned halfword. + Then this multiplication results of adjacent odd-even elements + are added together and stored to the out vector + (2 unsigned halfword results) +*/ +#define DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dotp_u_h((v16u8) mult0, (v16u8) cnst0); \ + out1 = (RTYPE) __msa_dotp_u_h((v16u8) mult1, (v16u8) cnst1); \ +} +#define DOTP_UB2_UH(...) DOTP_UB2(v8u16, __VA_ARGS__) + +#define DOTP_UB4(RTYPE, mult0, mult1, mult2, mult3, \ + cnst0, cnst1, cnst2, cnst3, \ + out0, out1, out2, out3) \ +{ \ + DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + DOTP_UB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ +} +#define DOTP_UB4_UH(...) DOTP_UB4(v8u16, __VA_ARGS__) + +/* Description : Dot product of byte vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Signed byte elements from mult0 are multiplied with + signed byte elements from cnst0 producing a result + twice the size of input i.e. signed halfword. + Then this multiplication results of adjacent odd-even elements + are added together and stored to the out vector + (2 signed halfword results) +*/ +#define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dotp_s_h((v16i8) mult0, (v16i8) cnst0); \ + out1 = (RTYPE) __msa_dotp_s_h((v16i8) mult1, (v16i8) cnst1); \ +} +#define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__) + +#define DOTP_SB3(RTYPE, mult0, mult1, mult2, cnst0, cnst1, cnst2, \ + out0, out1, out2) \ +{ \ + DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + out2 = (RTYPE) __msa_dotp_s_h((v16i8) mult2, (v16i8) cnst2); \ +} +#define DOTP_SB3_SH(...) DOTP_SB3(v8i16, __VA_ARGS__) + +#define DOTP_SB4(RTYPE, mult0, mult1, mult2, mult3, \ + cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3) \ +{ \ + DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + DOTP_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ +} +#define DOTP_SB4_SH(...) DOTP_SB4(v8i16, __VA_ARGS__) + +/* Description : Dot product of halfword vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Signed halfword elements from mult0 are multiplied with + signed halfword elements from cnst0 producing a result + twice the size of input i.e. signed word. + Then this multiplication results of adjacent odd-even elements + are added together and stored to the out vector + (2 signed word results) +*/ +#define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dotp_s_w((v8i16) mult0, (v8i16) cnst0); \ + out1 = (RTYPE) __msa_dotp_s_w((v8i16) mult1, (v8i16) cnst1); \ +} +#define DOTP_SH2_SW(...) DOTP_SH2(v4i32, __VA_ARGS__) + +#define DOTP_SH4(RTYPE, mult0, mult1, mult2, mult3, \ + cnst0, cnst1, cnst2, cnst3, \ + out0, out1, out2, out3) \ +{ \ + DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + DOTP_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ +} +#define DOTP_SH4_SW(...) DOTP_SH4(v4i32, __VA_ARGS__) + +/* Description : Dot product & addition of byte vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Signed byte elements from mult0 are multiplied with + signed byte elements from cnst0 producing a result + twice the size of input i.e. signed halfword. + Then this multiplication results of adjacent odd-even elements + are added to the out vector + (2 signed halfword results) +*/ +#define DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dpadd_s_h((v8i16) out0, \ + (v16i8) mult0, (v16i8) cnst0); \ + out1 = (RTYPE) __msa_dpadd_s_h((v8i16) out1, \ + (v16i8) mult1, (v16i8) cnst1); \ +} +#define DPADD_SB2_SH(...) DPADD_SB2(v8i16, __VA_ARGS__) + +#define DPADD_SB4(RTYPE, mult0, mult1, mult2, mult3, \ + cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3) \ +{ \ + DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + DPADD_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ +} +#define DPADD_SB4_SH(...) DPADD_SB4(v8i16, __VA_ARGS__) + +/* Description : Dot product & addition of byte vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Unsigned byte elements from mult0 are multiplied with + unsigned byte elements from cnst0 producing a result + twice the size of input i.e. unsigned halfword. + Then this multiplication results of adjacent odd-even elements + are added to the out vector + (2 unsigned halfword results) +*/ +#define DPADD_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dpadd_u_h((v8u16) out0, \ + (v16u8) mult0, (v16u8) cnst0); \ + out1 = (RTYPE) __msa_dpadd_u_h((v8u16) out1, \ + (v16u8) mult1, (v16u8) cnst1); \ +} +#define DPADD_UB2_UH(...) DPADD_UB2(v8u16, __VA_ARGS__) + +/* Description : Dot product & addition of halfword vector elements + Arguments : Inputs - mult0, mult1 + cnst0, cnst1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Signed halfword elements from mult0 are multiplied with + signed halfword elements from cnst0 producing a result + twice the size of input i.e. signed word. + Then this multiplication results of adjacent odd-even elements + are added to the out vector + (2 signed word results) +*/ +#define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_dpadd_s_w((v4i32) out0, \ + (v8i16) mult0, (v8i16) cnst0); \ + out1 = (RTYPE) __msa_dpadd_s_w((v4i32) out1, \ + (v8i16) mult1, (v8i16) cnst1); \ +} +#define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__) + +#define DPADD_SH4(RTYPE, mult0, mult1, mult2, mult3, \ + cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3) \ +{ \ + DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ + DPADD_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ +} +#define DPADD_SH4_SW(...) DPADD_SH4(v4i32, __VA_ARGS__) + +/* Description : Minimum values between unsigned elements of + either vector are copied to the output vector + Arguments : Inputs - in0, in1, min_vec + Outputs - in0, in1, (in place) + Return Type - as per RTYPE + Details : Minimum of unsigned halfword element values from 'in0' and + 'min_value' are written to output vector 'in0' +*/ +#define MIN_UH2(RTYPE, in0, in1, min_vec) \ +{ \ + in0 = (RTYPE) __msa_min_u_h((v8u16) in0, min_vec); \ + in1 = (RTYPE) __msa_min_u_h((v8u16) in1, min_vec); \ +} +#define MIN_UH2_UH(...) MIN_UH2(v8u16, __VA_ARGS__) + +#define MIN_UH4(RTYPE, in0, in1, in2, in3, min_vec) \ +{ \ + MIN_UH2(RTYPE, in0, in1, min_vec); \ + MIN_UH2(RTYPE, in2, in3, min_vec); \ +} +#define MIN_UH4_UH(...) MIN_UH4(v8u16, __VA_ARGS__) + +/* Description : Clips all halfword elements of input vector between min & max + out = ((in) < (min)) ? (min) : (((in) > (max)) ? (max) : (in)) + Arguments : Inputs - in (input vector) + - min (min threshold) + - max (max threshold) + Outputs - in (output vector with clipped elements) + Return Type - signed halfword +*/ +#define CLIP_SH(in, min, max) \ +{ \ + in = __msa_max_s_h((v8i16) min, (v8i16) in); \ + in = __msa_min_s_h((v8i16) max, (v8i16) in); \ +} + +/* Description : Clips all signed halfword elements of input vector + between 0 & 255 + Arguments : Inputs - in (input vector) + Outputs - in (output vector with clipped elements) + Return Type - signed halfwords +*/ +#define CLIP_SH_0_255(in) \ +{ \ + in = __msa_maxi_s_h((v8i16) in, 0); \ + in = (v8i16) __msa_sat_u_h((v8u16) in, 7); \ +} + +#define CLIP_SH2_0_255(in0, in1) \ +{ \ + CLIP_SH_0_255(in0); \ + CLIP_SH_0_255(in1); \ +} + +#define CLIP_SH4_0_255(in0, in1, in2, in3) \ +{ \ + CLIP_SH2_0_255(in0, in1); \ + CLIP_SH2_0_255(in2, in3); \ +} + +#define CLIP_SH8_0_255(in0, in1, in2, in3, \ + in4, in5, in6, in7) \ +{ \ + CLIP_SH4_0_255(in0, in1, in2, in3); \ + CLIP_SH4_0_255(in4, in5, in6, in7); \ +} + +/* Description : Clips all signed word elements of input vector + between 0 & 255 + Arguments : Inputs - in (input vector) + Outputs - in (output vector with clipped elements) + Return Type - signed word +*/ +#define CLIP_SW_0_255(in) \ +{ \ + in = __msa_maxi_s_w((v4i32) in, 0); \ + in = (v4i32) __msa_sat_u_w((v4u32) in, 7); \ +} + +#define CLIP_SW2_0_255(in0, in1) \ +{ \ + CLIP_SW_0_255(in0); \ + CLIP_SW_0_255(in1); \ +} + +#define CLIP_SW4_0_255(in0, in1, in2, in3) \ +{ \ + CLIP_SW2_0_255(in0, in1); \ + CLIP_SW2_0_255(in2, in3); \ +} + +#define CLIP_SW8_0_255(in0, in1, in2, in3, \ + in4, in5, in6, in7) \ +{ \ + CLIP_SW4_0_255(in0, in1, in2, in3); \ + CLIP_SW4_0_255(in4, in5, in6, in7); \ +} + +/* Description : Addition of 4 signed word elements + 4 signed word elements of input vector are added together and + resulted integer sum is returned + Arguments : Inputs - in (signed word vector) + Outputs - sum_m (i32 sum) + Return Type - signed word +*/ +#define HADD_SW_S32(in) \ +( { \ + v2i64 res0_m, res1_m; \ + int32_t sum_m; \ + \ + res0_m = __msa_hadd_s_d((v4i32) in, (v4i32) in); \ + res1_m = __msa_splati_d(res0_m, 1); \ + res0_m += res1_m; \ + sum_m = __msa_copy_s_w((v4i32) res0_m, 0); \ + sum_m; \ +} ) + +/* Description : Addition of 8 unsigned halfword elements + 8 unsigned halfword elements of input vector are added + together and resulted integer sum is returned + Arguments : Inputs - in (unsigned halfword vector) + Outputs - sum_m (u32 sum) + Return Type - unsigned word +*/ +#define HADD_UH_U32(in) \ +( { \ + v4u32 res_m; \ + v2u64 res0_m, res1_m; \ + uint32_t sum_m; \ + \ + res_m = __msa_hadd_u_w((v8u16) in, (v8u16) in); \ + res0_m = __msa_hadd_u_d(res_m, res_m); \ + res1_m = (v2u64) __msa_splati_d((v2i64) res0_m, 1); \ + res0_m += res1_m; \ + sum_m = __msa_copy_u_w((v4i32) res0_m, 0); \ + sum_m; \ +} ) + +/* Description : Horizontal addition of signed byte vector elements + Arguments : Inputs - in0, in1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Each signed odd byte element from 'in0' is added to + even signed byte element from 'in0' (pairwise) and the + halfword result is stored in 'out0' +*/ +#define HADD_SB2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_hadd_s_h((v16i8) in0, (v16i8) in0); \ + out1 = (RTYPE) __msa_hadd_s_h((v16i8) in1, (v16i8) in1); \ +} +#define HADD_SB2_SH(...) HADD_SB2(v8i16, __VA_ARGS__) + +#define HADD_SB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + HADD_SB2(RTYPE, in0, in1, out0, out1); \ + HADD_SB2(RTYPE, in2, in3, out2, out3); \ +} +#define HADD_SB4_UH(...) HADD_SB4(v8u16, __VA_ARGS__) +#define HADD_SB4_SH(...) HADD_SB4(v8i16, __VA_ARGS__) + +/* Description : Horizontal addition of unsigned byte vector elements + Arguments : Inputs - in0, in1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Each unsigned odd byte element from 'in0' is added to + even unsigned byte element from 'in0' (pairwise) and the + halfword result is stored in 'out0' +*/ +#define HADD_UB2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_hadd_u_h((v16u8) in0, (v16u8) in0); \ + out1 = (RTYPE) __msa_hadd_u_h((v16u8) in1, (v16u8) in1); \ +} +#define HADD_UB2_UH(...) HADD_UB2(v8u16, __VA_ARGS__) + +#define HADD_UB3(RTYPE, in0, in1, in2, out0, out1, out2) \ +{ \ + HADD_UB2(RTYPE, in0, in1, out0, out1); \ + out2 = (RTYPE) __msa_hadd_u_h((v16u8) in2, (v16u8) in2); \ +} +#define HADD_UB3_UH(...) HADD_UB3(v8u16, __VA_ARGS__) + +#define HADD_UB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + HADD_UB2(RTYPE, in0, in1, out0, out1); \ + HADD_UB2(RTYPE, in2, in3, out2, out3); \ +} +#define HADD_UB4_UB(...) HADD_UB4(v16u8, __VA_ARGS__) +#define HADD_UB4_UH(...) HADD_UB4(v8u16, __VA_ARGS__) +#define HADD_UB4_SH(...) HADD_UB4(v8i16, __VA_ARGS__) + +/* Description : Horizontal subtraction of unsigned byte vector elements + Arguments : Inputs - in0, in1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Each unsigned odd byte element from 'in0' is subtracted from + even unsigned byte element from 'in0' (pairwise) and the + halfword result is stored in 'out0' +*/ +#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0); \ + out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1); \ +} +#define HSUB_UB2_UH(...) HSUB_UB2(v8u16, __VA_ARGS__) +#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__) + +#define HSUB_UB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + HSUB_UB2(RTYPE, in0, in1, out0, out1); \ + HSUB_UB2(RTYPE, in2, in3, out2, out3); \ +} +#define HSUB_UB4_UH(...) HSUB_UB4(v8u16, __VA_ARGS__) +#define HSUB_UB4_SH(...) HSUB_UB4(v8i16, __VA_ARGS__) + +/* Description : SAD (Sum of Absolute Difference) + Arguments : Inputs - in0, in1, ref0, ref1 (unsigned byte src & ref) + Outputs - sad_m (halfword vector with sad) + Return Type - unsigned halfword + Details : Absolute difference of all the byte elements from 'in0' with + 'ref0' is calculated and preserved in 'diff0'. From the 16 + unsigned absolute diff values, even-odd pairs are added + together to generate 8 halfword results. +*/ +#define SAD_UB2_UH(in0, in1, ref0, ref1) \ +( { \ + v16u8 diff0_m, diff1_m; \ + v8u16 sad_m = { 0 }; \ + \ + diff0_m = __msa_asub_u_b((v16u8) in0, (v16u8) ref0); \ + diff1_m = __msa_asub_u_b((v16u8) in1, (v16u8) ref1); \ + \ + sad_m += __msa_hadd_u_h((v16u8) diff0_m, (v16u8) diff0_m); \ + sad_m += __msa_hadd_u_h((v16u8) diff1_m, (v16u8) diff1_m); \ + \ + sad_m; \ +} ) + +/* Description : Insert specified word elements from input vectors to 1 + destination vector + Arguments : Inputs - in0, in1, in2, in3 (4 input vectors) + Outputs - out (output vector) + Return Type - as per RTYPE +*/ +#define INSERT_W2(RTYPE, in0, in1, out) \ +{ \ + out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0); \ + out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1); \ +} +#define INSERT_W2_UB(...) INSERT_W2(v16u8, __VA_ARGS__) +#define INSERT_W2_SB(...) INSERT_W2(v16i8, __VA_ARGS__) + +#define INSERT_W4(RTYPE, in0, in1, in2, in3, out) \ +{ \ + out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0); \ + out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1); \ + out = (RTYPE) __msa_insert_w((v4i32) out, 2, in2); \ + out = (RTYPE) __msa_insert_w((v4i32) out, 3, in3); \ +} +#define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__) +#define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__) +#define INSERT_W4_SH(...) INSERT_W4(v8i16, __VA_ARGS__) +#define INSERT_W4_SW(...) INSERT_W4(v4i32, __VA_ARGS__) + +/* Description : Insert specified double word elements from input vectors to 1 + destination vector + Arguments : Inputs - in0, in1 (2 input vectors) + Outputs - out (output vector) + Return Type - as per RTYPE +*/ +#define INSERT_D2(RTYPE, in0, in1, out) \ +{ \ + out = (RTYPE) __msa_insert_d((v2i64) out, 0, in0); \ + out = (RTYPE) __msa_insert_d((v2i64) out, 1, in1); \ +} +#define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__) +#define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__) +#define INSERT_D2_SH(...) INSERT_D2(v8i16, __VA_ARGS__) +#define INSERT_D2_SD(...) INSERT_D2(v2i64, __VA_ARGS__) + +/* Description : Interleave even byte elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even byte elements of 'in0' and even byte + elements of 'in1' are interleaved and copied to 'out0' + Even byte elements of 'in2' and even byte + elements of 'in3' are interleaved and copied to 'out1' +*/ +#define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvev_b((v16i8) in1, (v16i8) in0); \ + out1 = (RTYPE) __msa_ilvev_b((v16i8) in3, (v16i8) in2); \ +} +#define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__) +#define ILVEV_B2_SB(...) ILVEV_B2(v16i8, __VA_ARGS__) +#define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__) +#define ILVEV_B2_SD(...) ILVEV_B2(v2i64, __VA_ARGS__) + +/* Description : Interleave even halfword elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even halfword elements of 'in0' and even halfword + elements of 'in1' are interleaved and copied to 'out0' + Even halfword elements of 'in2' and even halfword + elements of 'in3' are interleaved and copied to 'out1' +*/ +#define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvev_h((v8i16) in1, (v8i16) in0); \ + out1 = (RTYPE) __msa_ilvev_h((v8i16) in3, (v8i16) in2); \ +} +#define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__) +#define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__) +#define ILVEV_H2_SW(...) ILVEV_H2(v4i32, __VA_ARGS__) + +/* Description : Interleave even word elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even word elements of 'in0' and even word + elements of 'in1' are interleaved and copied to 'out0' + Even word elements of 'in2' and even word + elements of 'in3' are interleaved and copied to 'out1' +*/ +#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0); \ + out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2); \ +} +#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__) +#define ILVEV_W2_SB(...) ILVEV_W2(v16i8, __VA_ARGS__) +#define ILVEV_W2_UH(...) ILVEV_W2(v8u16, __VA_ARGS__) +#define ILVEV_W2_SD(...) ILVEV_W2(v2i64, __VA_ARGS__) + +/* Description : Interleave even double word elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even double word elements of 'in0' and even double word + elements of 'in1' are interleaved and copied to 'out0' + Even double word elements of 'in2' and even double word + elements of 'in3' are interleaved and copied to 'out1' +*/ +#define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvev_d((v2i64) in1, (v2i64) in0); \ + out1 = (RTYPE) __msa_ilvev_d((v2i64) in3, (v2i64) in2); \ +} +#define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__) +#define ILVEV_D2_SB(...) ILVEV_D2(v16i8, __VA_ARGS__) +#define ILVEV_D2_SW(...) ILVEV_D2(v4i32, __VA_ARGS__) + +/* Description : Interleave left half of byte elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Left half of byte elements of in0 and left half of byte + elements of in1 are interleaved and copied to out0. + Left half of byte elements of in2 and left half of byte + elements of in3 are interleaved and copied to out1. +*/ +#define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1); \ + out1 = (RTYPE) __msa_ilvl_b((v16i8) in2, (v16i8) in3); \ +} +#define ILVL_B2_UB(...) ILVL_B2(v16u8, __VA_ARGS__) +#define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__) +#define ILVL_B2_UH(...) ILVL_B2(v8u16, __VA_ARGS__) +#define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__) + +#define ILVL_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVL_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVL_B4_UB(...) ILVL_B4(v16u8, __VA_ARGS__) +#define ILVL_B4_SB(...) ILVL_B4(v16i8, __VA_ARGS__) +#define ILVL_B4_UH(...) ILVL_B4(v8u16, __VA_ARGS__) +#define ILVL_B4_SH(...) ILVL_B4(v8i16, __VA_ARGS__) + +/* Description : Interleave left half of halfword elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Left half of halfword elements of in0 and left half of halfword + elements of in1 are interleaved and copied to out0. + Left half of halfword elements of in2 and left half of halfword + elements of in3 are interleaved and copied to out1. +*/ +#define ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1); \ + out1 = (RTYPE) __msa_ilvl_h((v8i16) in2, (v8i16) in3); \ +} +#define ILVL_H2_SH(...) ILVL_H2(v8i16, __VA_ARGS__) +#define ILVL_H2_SW(...) ILVL_H2(v4i32, __VA_ARGS__) + +#define ILVL_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVL_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVL_H4_SH(...) ILVL_H4(v8i16, __VA_ARGS__) +#define ILVL_H4_SW(...) ILVL_H4(v4i32, __VA_ARGS__) + +/* Description : Interleave left half of word elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Left half of word elements of in0 and left half of word + elements of in1 are interleaved and copied to out0. + Left half of word elements of in2 and left half of word + elements of in3 are interleaved and copied to out1. +*/ +#define ILVL_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1); \ + out1 = (RTYPE) __msa_ilvl_w((v4i32) in2, (v4i32) in3); \ +} +#define ILVL_W2_UB(...) ILVL_W2(v16u8, __VA_ARGS__) +#define ILVL_W2_SB(...) ILVL_W2(v16i8, __VA_ARGS__) +#define ILVL_W2_SH(...) ILVL_W2(v8i16, __VA_ARGS__) + +/* Description : Interleave right half of byte elements from vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + Outputs - out0, out1, out2, out3 + Return Type - as per RTYPE + Details : Right half of byte elements of in0 and right half of byte + elements of in1 are interleaved and copied to out0. + Right half of byte elements of in2 and right half of byte + elements of in3 are interleaved and copied to out1. + Similar for other pairs +*/ +#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1); \ + out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3); \ +} +#define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__) +#define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__) +#define ILVR_B2_UH(...) ILVR_B2(v8u16, __VA_ARGS__) +#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__) +#define ILVR_B2_SW(...) ILVR_B2(v4i32, __VA_ARGS__) + +#define ILVR_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2) \ +{ \ + ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ + out2 = (RTYPE) __msa_ilvr_b((v16i8) in4, (v16i8) in5); \ +} +#define ILVR_B3_UB(...) ILVR_B3(v16u8, __VA_ARGS__) +#define ILVR_B3_SB(...) ILVR_B3(v16i8, __VA_ARGS__) +#define ILVR_B3_UH(...) ILVR_B3(v8u16, __VA_ARGS__) +#define ILVR_B3_SH(...) ILVR_B3(v8i16, __VA_ARGS__) + +#define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__) +#define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__) +#define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__) +#define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__) +#define ILVR_B4_SW(...) ILVR_B4(v4i32, __VA_ARGS__) + +#define ILVR_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + in8, in9, in10, in11, in12, in13, in14, in15, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3); \ + ILVR_B4(RTYPE, in8, in9, in10, in11, in12, in13, in14, in15, \ + out4, out5, out6, out7); \ +} +#define ILVR_B8_UH(...) ILVR_B8(v8u16, __VA_ARGS__) +#define ILVR_B8_SW(...) ILVR_B8(v4i32, __VA_ARGS__) + +/* Description : Interleave right half of halfword elements from vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + Outputs - out0, out1, out2, out3 + Return Type - as per RTYPE + Details : Right half of halfword elements of in0 and right half of + halfword elements of in1 are interleaved and copied to out0. + Right half of halfword elements of in2 and right half of + halfword elements of in3 are interleaved and copied to out1. + Similar for other pairs +*/ +#define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1); \ + out1 = (RTYPE) __msa_ilvr_h((v8i16) in2, (v8i16) in3); \ +} +#define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__) +#define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__) + +#define ILVR_H3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2) \ +{ \ + ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ + out2 = (RTYPE) __msa_ilvr_h((v8i16) in4, (v8i16) in5); \ +} +#define ILVR_H3_SH(...) ILVR_H3(v8i16, __VA_ARGS__) + +#define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__) +#define ILVR_H4_SW(...) ILVR_H4(v4i32, __VA_ARGS__) + +#define ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1); \ + out1 = (RTYPE) __msa_ilvr_w((v4i32) in2, (v4i32) in3); \ +} +#define ILVR_W2_UB(...) ILVR_W2(v16u8, __VA_ARGS__) +#define ILVR_W2_SB(...) ILVR_W2(v16i8, __VA_ARGS__) +#define ILVR_W2_SH(...) ILVR_W2(v8i16, __VA_ARGS__) + +#define ILVR_W4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVR_W2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVR_W4_SB(...) ILVR_W4(v16i8, __VA_ARGS__) +#define ILVR_W4_UB(...) ILVR_W4(v16u8, __VA_ARGS__) + +/* Description : Interleave right half of double word elements from vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + Outputs - out0, out1, out2, out3 + Return Type - as per RTYPE + Details : Right half of double word elements of in0 and right half of + double word elements of in1 are interleaved and copied to out0. + Right half of double word elements of in2 and right half of + double word elements of in3 are interleaved and copied to out1. +*/ +#define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_d((v2i64) in0, (v2i64) in1); \ + out1 = (RTYPE) __msa_ilvr_d((v2i64) in2, (v2i64) in3); \ +} +#define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__) +#define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__) +#define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__) + +#define ILVR_D3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2) \ +{ \ + ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ + out2 = (RTYPE) __msa_ilvr_d((v2i64) in4, (v2i64) in5); \ +} +#define ILVR_D3_SB(...) ILVR_D3(v16i8, __VA_ARGS__) + +#define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__) +#define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__) + +/* Description : Interleave left half of double word elements from vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Left half of double word elements of in0 and left half of + double word elements of in1 are interleaved and copied to out0. + Left half of double word elements of in2 and left half of + double word elements of in3 are interleaved and copied to out1. +*/ +#define ILVL_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvl_d((v2i64) in0, (v2i64) in1); \ + out1 = (RTYPE) __msa_ilvl_d((v2i64) in2, (v2i64) in3); \ +} +#define ILVL_D2_UB(...) ILVL_D2(v16u8, __VA_ARGS__) +#define ILVL_D2_SB(...) ILVL_D2(v16i8, __VA_ARGS__) +#define ILVL_D2_SH(...) ILVL_D2(v8i16, __VA_ARGS__) + +/* Description : Interleave both left and right half of input vectors + Arguments : Inputs - in0, in1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Right half of byte elements from 'in0' and 'in1' are + interleaved and stored to 'out0' + Left half of byte elements from 'in0' and 'in1' are + interleaved and stored to 'out1' +*/ +#define ILVRL_B2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1); \ + out1 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1); \ +} +#define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__) +#define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__) +#define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__) +#define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__) +#define ILVRL_B2_SW(...) ILVRL_B2(v4i32, __VA_ARGS__) + +#define ILVRL_H2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1); \ + out1 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1); \ +} +#define ILVRL_H2_UB(...) ILVRL_H2(v16u8, __VA_ARGS__) +#define ILVRL_H2_SB(...) ILVRL_H2(v16i8, __VA_ARGS__) +#define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__) +#define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__) + +#define ILVRL_W2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1); \ + out1 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1); \ +} +#define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__) +#define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__) +#define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__) + +/* Description : Maximum values between signed elements of vector and + 5-bit signed immediate value are copied to the output vector + Arguments : Inputs - in0, in1, in2, in3, max_val + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Maximum of signed halfword element values from 'in0' and + 'max_val' are written to output vector 'in0' +*/ +#define MAXI_SH2(RTYPE, in0, in1, max_val) \ +{ \ + in0 = (RTYPE) __msa_maxi_s_h((v8i16) in0, max_val); \ + in1 = (RTYPE) __msa_maxi_s_h((v8i16) in1, max_val); \ +} +#define MAXI_SH2_UH(...) MAXI_SH2(v8u16, __VA_ARGS__) +#define MAXI_SH2_SH(...) MAXI_SH2(v8i16, __VA_ARGS__) + +#define MAXI_SH4(RTYPE, in0, in1, in2, in3, max_val) \ +{ \ + MAXI_SH2(RTYPE, in0, in1, max_val); \ + MAXI_SH2(RTYPE, in2, in3, max_val); \ +} +#define MAXI_SH4_UH(...) MAXI_SH4(v8u16, __VA_ARGS__) +#define MAXI_SH4_SH(...) MAXI_SH4(v8i16, __VA_ARGS__) + +#define MAXI_SH8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, max_val) \ +{ \ + MAXI_SH4(RTYPE, in0, in1, in2, in3, max_val); \ + MAXI_SH4(RTYPE, in4, in5, in6, in7, max_val); \ +} +#define MAXI_SH8_UH(...) MAXI_SH8(v8u16, __VA_ARGS__) +#define MAXI_SH8_SH(...) MAXI_SH8(v8i16, __VA_ARGS__) + +/* Description : Saturate the halfword element values to the max + unsigned value of (sat_val+1 bits) + The element data width remains unchanged + Arguments : Inputs - in0, in1, in2, in3, sat_val + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Each unsigned halfword element from 'in0' is saturated to the + value generated with (sat_val+1) bit range + Results are in placed to original vectors +*/ +#define SAT_UH2(RTYPE, in0, in1, sat_val) \ +{ \ + in0 = (RTYPE) __msa_sat_u_h((v8u16) in0, sat_val); \ + in1 = (RTYPE) __msa_sat_u_h((v8u16) in1, sat_val); \ +} +#define SAT_UH2_UH(...) SAT_UH2(v8u16, __VA_ARGS__) +#define SAT_UH2_SH(...) SAT_UH2(v8i16, __VA_ARGS__) + +#define SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val) \ +{ \ + SAT_UH2(RTYPE, in0, in1, sat_val); \ + SAT_UH2(RTYPE, in2, in3, sat_val); \ +} +#define SAT_UH4_UH(...) SAT_UH4(v8u16, __VA_ARGS__) +#define SAT_UH4_SH(...) SAT_UH4(v8i16, __VA_ARGS__) + +#define SAT_UH8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, sat_val) \ +{ \ + SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val); \ + SAT_UH4(RTYPE, in4, in5, in6, in7, sat_val); \ +} +#define SAT_UH8_UH(...) SAT_UH8(v8u16, __VA_ARGS__) +#define SAT_UH8_SH(...) SAT_UH8(v8i16, __VA_ARGS__) + +/* Description : Saturate the halfword element values to the max + unsigned value of (sat_val+1 bits) + The element data width remains unchanged + Arguments : Inputs - in0, in1, in2, in3, sat_val + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Each unsigned halfword element from 'in0' is saturated to the + value generated with (sat_val+1) bit range + Results are in placed to original vectors +*/ +#define SAT_SH2(RTYPE, in0, in1, sat_val) \ +{ \ + in0 = (RTYPE) __msa_sat_s_h((v8i16) in0, sat_val); \ + in1 = (RTYPE) __msa_sat_s_h((v8i16) in1, sat_val); \ +} +#define SAT_SH2_SH(...) SAT_SH2(v8i16, __VA_ARGS__) + +#define SAT_SH3(RTYPE, in0, in1, in2, sat_val) \ +{ \ + SAT_SH2(RTYPE, in0, in1, sat_val); \ + in2 = (RTYPE) __msa_sat_s_h((v8i16) in2, sat_val); \ +} +#define SAT_SH3_SH(...) SAT_SH3(v8i16, __VA_ARGS__) + +#define SAT_SH4(RTYPE, in0, in1, in2, in3, sat_val) \ +{ \ + SAT_SH2(RTYPE, in0, in1, sat_val); \ + SAT_SH2(RTYPE, in2, in3, sat_val); \ +} +#define SAT_SH4_SH(...) SAT_SH4(v8i16, __VA_ARGS__) + +/* Description : Saturate the word element values to the max + unsigned value of (sat_val+1 bits) + The element data width remains unchanged + Arguments : Inputs - in0, in1, in2, in3, sat_val + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Each unsigned word element from 'in0' is saturated to the + value generated with (sat_val+1) bit range + Results are in placed to original vectors +*/ +#define SAT_SW2(RTYPE, in0, in1, sat_val) \ +{ \ + in0 = (RTYPE) __msa_sat_s_w((v4i32) in0, sat_val); \ + in1 = (RTYPE) __msa_sat_s_w((v4i32) in1, sat_val); \ +} +#define SAT_SW2_SW(...) SAT_SW2(v4i32, __VA_ARGS__) + +#define SAT_SW4(RTYPE, in0, in1, in2, in3, sat_val) \ +{ \ + SAT_SW2(RTYPE, in0, in1, sat_val); \ + SAT_SW2(RTYPE, in2, in3, sat_val); \ +} +#define SAT_SW4_SW(...) SAT_SW4(v4i32, __VA_ARGS__) + +/* Description : Indexed halfword element values are replicated to all + elements in output vector + Arguments : Inputs - in, idx0, idx1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : 'idx0' element value from 'in' vector is replicated to all + elements in 'out0' vector + Valid index range for halfword operation is 0-7 +*/ +#define SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_splati_h((v8i16) in, idx0); \ + out1 = (RTYPE) __msa_splati_h((v8i16) in, idx1); \ +} +#define SPLATI_H2_SB(...) SPLATI_H2(v16i8, __VA_ARGS__) +#define SPLATI_H2_SH(...) SPLATI_H2(v8i16, __VA_ARGS__) + +#define SPLATI_H3(RTYPE, in, idx0, idx1, idx2, \ + out0, out1, out2) \ +{ \ + SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1); \ + out2 = (RTYPE) __msa_splati_h((v8i16) in, idx2); \ +} +#define SPLATI_H3_SB(...) SPLATI_H3(v16i8, __VA_ARGS__) +#define SPLATI_H3_SH(...) SPLATI_H3(v8i16, __VA_ARGS__) + +#define SPLATI_H4(RTYPE, in, idx0, idx1, idx2, idx3, \ + out0, out1, out2, out3) \ +{ \ + SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1); \ + SPLATI_H2(RTYPE, in, idx2, idx3, out2, out3); \ +} +#define SPLATI_H4_SB(...) SPLATI_H4(v16i8, __VA_ARGS__) +#define SPLATI_H4_SH(...) SPLATI_H4(v8i16, __VA_ARGS__) + +/* Description : Indexed word element values are replicated to all + elements in output vector + Arguments : Inputs - in, stidx + Outputs - out0, out1 + Return Type - as per RTYPE + Details : 'stidx' element value from 'in' vector is replicated to all + elements in 'out0' vector + 'stidx + 1' element value from 'in' vector is replicated to all + elements in 'out1' vector + Valid index range for halfword operation is 0-3 +*/ +#define SPLATI_W2(RTYPE, in, stidx, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_splati_w((v4i32) in, stidx); \ + out1 = (RTYPE) __msa_splati_w((v4i32) in, (stidx+1)); \ +} +#define SPLATI_W2_SH(...) SPLATI_W2(v8i16, __VA_ARGS__) +#define SPLATI_W2_SW(...) SPLATI_W2(v4i32, __VA_ARGS__) + +#define SPLATI_W4(RTYPE, in, out0, out1, out2, out3) \ +{ \ + SPLATI_W2(RTYPE, in, 0, out0, out1); \ + SPLATI_W2(RTYPE, in, 2, out2, out3); \ +} +#define SPLATI_W4_SH(...) SPLATI_W4(v8i16, __VA_ARGS__) +#define SPLATI_W4_SW(...) SPLATI_W4(v4i32, __VA_ARGS__) + +/* Description : Pack even byte elements of vector pairs + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even byte elements of in0 are copied to the left half of + out0 & even byte elements of in1 are copied to the right + half of out0. + Even byte elements of in2 are copied to the left half of + out1 & even byte elements of in3 are copied to the right + half of out1. +*/ +#define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_pckev_b((v16i8) in0, (v16i8) in1); \ + out1 = (RTYPE) __msa_pckev_b((v16i8) in2, (v16i8) in3); \ +} +#define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__) +#define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__) +#define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__) +#define PCKEV_B2_SW(...) PCKEV_B2(v4i32, __VA_ARGS__) + +#define PCKEV_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2) \ +{ \ + PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ + out2 = (RTYPE) __msa_pckev_b((v16i8) in4, (v16i8) in5); \ +} +#define PCKEV_B3_UB(...) PCKEV_B3(v16u8, __VA_ARGS__) +#define PCKEV_B3_SB(...) PCKEV_B3(v16i8, __VA_ARGS__) + +#define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ + PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__) +#define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__) +#define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__) +#define PCKEV_B4_SW(...) PCKEV_B4(v4i32, __VA_ARGS__) + +/* Description : Pack even halfword elements of vector pairs + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even halfword elements of in0 are copied to the left half of + out0 & even halfword elements of in1 are copied to the right + half of out0. + Even halfword elements of in2 are copied to the left half of + out1 & even halfword elements of in3 are copied to the right + half of out1. +*/ +#define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_pckev_h((v8i16) in0, (v8i16) in1); \ + out1 = (RTYPE) __msa_pckev_h((v8i16) in2, (v8i16) in3); \ +} +#define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__) +#define PCKEV_H2_SW(...) PCKEV_H2(v4i32, __VA_ARGS__) + +#define PCKEV_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ + PCKEV_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define PCKEV_H4_SH(...) PCKEV_H4(v8i16, __VA_ARGS__) +#define PCKEV_H4_SW(...) PCKEV_H4(v4i32, __VA_ARGS__) + +/* Description : Pack even double word elements of vector pairs + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Even double elements of in0 are copied to the left half of + out0 & even double elements of in1 are copied to the right + half of out0. + Even double elements of in2 are copied to the left half of + out1 & even double elements of in3 are copied to the right + half of out1. +*/ +#define PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_pckev_d((v2i64) in0, (v2i64) in1); \ + out1 = (RTYPE) __msa_pckev_d((v2i64) in2, (v2i64) in3); \ +} +#define PCKEV_D2_UB(...) PCKEV_D2(v16u8, __VA_ARGS__) +#define PCKEV_D2_SB(...) PCKEV_D2(v16i8, __VA_ARGS__) +#define PCKEV_D2_SH(...) PCKEV_D2(v8i16, __VA_ARGS__) + +#define PCKEV_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ + PCKEV_D2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define PCKEV_D4_UB(...) PCKEV_D4(v16u8, __VA_ARGS__) + +/* Description : Pack odd double word elements of vector pairs + Arguments : Inputs - in0, in1 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : As operation is on same input 'in0' vector, index 1 double word + element is overwritten to index 0 and result is written to out0 + As operation is on same input 'in1' vector, index 1 double word + element is overwritten to index 0 and result is written to out1 +*/ +#define PCKOD_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_pckod_d((v2i64) in0, (v2i64) in1); \ + out1 = (RTYPE) __msa_pckod_d((v2i64) in2, (v2i64) in3); \ +} +#define PCKOD_D2_UB(...) PCKOD_D2(v16u8, __VA_ARGS__) +#define PCKOD_D2_SH(...) PCKOD_D2(v8i16, __VA_ARGS__) +#define PCKOD_D2_SD(...) PCKOD_D2(v2i64, __VA_ARGS__) + +/* Description : Each byte element is logically xor'ed with immediate 128 + Arguments : Inputs - in0, in1 + Outputs - in0, in1 (in-place) + Return Type - as per RTYPE + Details : Each unsigned byte element from input vector 'in0' is + logically xor'ed with 128 and result is in-place stored in + 'in0' vector + Each unsigned byte element from input vector 'in1' is + logically xor'ed with 128 and result is in-place stored in + 'in1' vector + Similar for other pairs +*/ +#define XORI_B2_128(RTYPE, in0, in1) \ +{ \ + in0 = (RTYPE) __msa_xori_b((v16u8) in0, 128); \ + in1 = (RTYPE) __msa_xori_b((v16u8) in1, 128); \ +} +#define XORI_B2_128_UB(...) XORI_B2_128(v16u8, __VA_ARGS__) +#define XORI_B2_128_SB(...) XORI_B2_128(v16i8, __VA_ARGS__) +#define XORI_B2_128_SH(...) XORI_B2_128(v8i16, __VA_ARGS__) + +#define XORI_B3_128(RTYPE, in0, in1, in2) \ +{ \ + XORI_B2_128(RTYPE, in0, in1); \ + in2 = (RTYPE) __msa_xori_b((v16u8) in2, 128); \ +} +#define XORI_B3_128_SB(...) XORI_B3_128(v16i8, __VA_ARGS__) + +#define XORI_B4_128(RTYPE, in0, in1, in2, in3) \ +{ \ + XORI_B2_128(RTYPE, in0, in1); \ + XORI_B2_128(RTYPE, in2, in3); \ +} +#define XORI_B4_128_UB(...) XORI_B4_128(v16u8, __VA_ARGS__) +#define XORI_B4_128_SB(...) XORI_B4_128(v16i8, __VA_ARGS__) +#define XORI_B4_128_SH(...) XORI_B4_128(v8i16, __VA_ARGS__) + +#define XORI_B5_128(RTYPE, in0, in1, in2, in3, in4) \ +{ \ + XORI_B3_128(RTYPE, in0, in1, in2); \ + XORI_B2_128(RTYPE, in3, in4); \ +} +#define XORI_B5_128_SB(...) XORI_B5_128(v16i8, __VA_ARGS__) + +#define XORI_B6_128(RTYPE, in0, in1, in2, in3, in4, in5) \ +{ \ + XORI_B4_128(RTYPE, in0, in1, in2, in3); \ + XORI_B2_128(RTYPE, in4, in5); \ +} +#define XORI_B6_128_SB(...) XORI_B6_128(v16i8, __VA_ARGS__) + +#define XORI_B7_128(RTYPE, in0, in1, in2, in3, in4, in5, in6) \ +{ \ + XORI_B4_128(RTYPE, in0, in1, in2, in3); \ + XORI_B3_128(RTYPE, in4, in5, in6); \ +} +#define XORI_B7_128_SB(...) XORI_B7_128(v16i8, __VA_ARGS__) + +#define XORI_B8_128(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7) \ +{ \ + XORI_B4_128(RTYPE, in0, in1, in2, in3); \ + XORI_B4_128(RTYPE, in4, in5, in6, in7); \ +} +#define XORI_B8_128_SB(...) XORI_B8_128(v16i8, __VA_ARGS__) +#define XORI_B8_128_UB(...) XORI_B8_128(v16u8, __VA_ARGS__) + +/* Description : Addition of signed halfword elements and signed saturation + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Return Type - as per RTYPE + Details : Signed halfword elements from 'in0' are added to signed + halfword elements of 'in1'. The result is then signed saturated + between -32768 to +32767 (as per halfword data type) + Similar for other pairs +*/ +#define ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_adds_s_h((v8i16) in0, (v8i16) in1); \ + out1 = (RTYPE) __msa_adds_s_h((v8i16) in2, (v8i16) in3); \ +} +#define ADDS_SH2_SH(...) ADDS_SH2(v8i16, __VA_ARGS__) + +#define ADDS_SH4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1); \ + ADDS_SH2(RTYPE, in4, in5, in6, in7, out2, out3); \ +} +#define ADDS_SH4_UH(...) ADDS_SH4(v8u16, __VA_ARGS__) +#define ADDS_SH4_SH(...) ADDS_SH4(v8i16, __VA_ARGS__) + +/* Description : Shift left all elements of vector (generic for all data types) + Arguments : Inputs - in0, in1, in2, in3, shift + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per input vector RTYPE + Details : Each element of vector 'in0' is left shifted by 'shift' and + result is in place written to 'in0' + Similar for other pairs +*/ +#define SLLI_2V(in0, in1, shift) \ +{ \ + in0 = in0 << shift; \ + in1 = in1 << shift; \ +} +#define SLLI_4V(in0, in1, in2, in3, shift) \ +{ \ + in0 = in0 << shift; \ + in1 = in1 << shift; \ + in2 = in2 << shift; \ + in3 = in3 << shift; \ +} + +/* Description : Arithmetic shift right all elements of vector + (generic for all data types) + Arguments : Inputs - in0, in1, in2, in3, shift + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per input vector RTYPE + Details : Each element of vector 'in0' is right shifted by 'shift' and + result is in place written to 'in0' + Here, 'shift' is GP variable passed in + Similar for other pairs +*/ +#define SRA_4V(in0, in1, in2, in3, shift) \ +{ \ + in0 = in0 >> shift; \ + in1 = in1 >> shift; \ + in2 = in2 >> shift; \ + in3 = in3 >> shift; \ +} + +/* Description : Shift right logical all halfword elements of vector + Arguments : Inputs - in0, in1, in2, in3, shift + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Each element of vector 'in0' is shifted right logical by + number of bits respective element holds in vector 'shift' and + result is in place written to 'in0' + Here, 'shift' is a vector passed in + Similar for other pairs +*/ +#define SRL_H4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + in0 = (RTYPE) __msa_srl_h((v8i16) in0, (v8i16) shift); \ + in1 = (RTYPE) __msa_srl_h((v8i16) in1, (v8i16) shift); \ + in2 = (RTYPE) __msa_srl_h((v8i16) in2, (v8i16) shift); \ + in3 = (RTYPE) __msa_srl_h((v8i16) in3, (v8i16) shift); \ +} +#define SRL_H4_UH(...) SRL_H4(v8u16, __VA_ARGS__) + +#define SRLR_H4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + in0 = (RTYPE) __msa_srlr_h((v8i16) in0, (v8i16) shift); \ + in1 = (RTYPE) __msa_srlr_h((v8i16) in1, (v8i16) shift); \ + in2 = (RTYPE) __msa_srlr_h((v8i16) in2, (v8i16) shift); \ + in3 = (RTYPE) __msa_srlr_h((v8i16) in3, (v8i16) shift); \ +} +#define SRLR_H4_UH(...) SRLR_H4(v8u16, __VA_ARGS__) +#define SRLR_H4_SH(...) SRLR_H4(v8i16, __VA_ARGS__) + +#define SRLR_H8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, shift) \ +{ \ + SRLR_H4(RTYPE, in0, in1, in2, in3, shift); \ + SRLR_H4(RTYPE, in4, in5, in6, in7, shift); \ +} +#define SRLR_H8_UH(...) SRLR_H8(v8u16, __VA_ARGS__) +#define SRLR_H8_SH(...) SRLR_H8(v8i16, __VA_ARGS__) + +/* Description : Shift right arithmetic rounded halfwords + Arguments : Inputs - in0, in1, shift + Outputs - in0, in1, (in place) + Return Type - as per RTYPE + Details : Each element of vector 'in0' is shifted right arithmetic by + number of bits respective element holds in vector 'shift'. + The last discarded bit is added to shifted value for rounding + and the result is in place written to 'in0' + Here, 'shift' is a vector passed in + Similar for other pairs +*/ +#define SRAR_H2(RTYPE, in0, in1, shift) \ +{ \ + in0 = (RTYPE) __msa_srar_h((v8i16) in0, (v8i16) shift); \ + in1 = (RTYPE) __msa_srar_h((v8i16) in1, (v8i16) shift); \ +} +#define SRAR_H2_UH(...) SRAR_H2(v8u16, __VA_ARGS__) +#define SRAR_H2_SH(...) SRAR_H2(v8i16, __VA_ARGS__) + +#define SRAR_H3(RTYPE, in0, in1, in2, shift) \ +{ \ + SRAR_H2(RTYPE, in0, in1, shift) \ + in2 = (RTYPE) __msa_srar_h((v8i16) in2, (v8i16) shift); \ +} +#define SRAR_H3_SH(...) SRAR_H3(v8i16, __VA_ARGS__) + +#define SRAR_H4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + SRAR_H2(RTYPE, in0, in1, shift) \ + SRAR_H2(RTYPE, in2, in3, shift) \ +} +#define SRAR_H4_UH(...) SRAR_H4(v8u16, __VA_ARGS__) +#define SRAR_H4_SH(...) SRAR_H4(v8i16, __VA_ARGS__) + +/* Description : Shift right arithmetic rounded words + Arguments : Inputs - in0, in1, shift + Outputs - in0, in1, (in place) + Return Type - as per RTYPE + Details : Each element of vector 'in0' is shifted right arithmetic by + number of bits respective element holds in vector 'shift'. + The last discarded bit is added to shifted value for rounding + and the result is in place written to 'in0' + Here, 'shift' is a vector passed in + Similar for other pairs +*/ +#define SRAR_W2(RTYPE, in0, in1, shift) \ +{ \ + in0 = (RTYPE) __msa_srar_w((v4i32) in0, (v4i32) shift); \ + in1 = (RTYPE) __msa_srar_w((v4i32) in1, (v4i32) shift); \ +} +#define SRAR_W2_SW(...) SRAR_W2(v4i32, __VA_ARGS__) + +#define SRAR_W4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + SRAR_W2(RTYPE, in0, in1, shift) \ + SRAR_W2(RTYPE, in2, in3, shift) \ +} +#define SRAR_W4_SW(...) SRAR_W4(v4i32, __VA_ARGS__) + +/* Description : Shift right arithmetic rounded (immediate) + Arguments : Inputs - in0, in1, in2, in3, shift + Outputs - in0, in1, in2, in3 (in place) + Return Type - as per RTYPE + Details : Each element of vector 'in0' is shifted right arithmetic by + value in 'shift'. + The last discarded bit is added to shifted value for rounding + and the result is in place written to 'in0' + Similar for other pairs +*/ +#define SRARI_H2(RTYPE, in0, in1, shift) \ +{ \ + in0 = (RTYPE) __msa_srari_h((v8i16) in0, shift); \ + in1 = (RTYPE) __msa_srari_h((v8i16) in1, shift); \ +} +#define SRARI_H2_UH(...) SRARI_H2(v8u16, __VA_ARGS__) +#define SRARI_H2_SH(...) SRARI_H2(v8i16, __VA_ARGS__) + +#define SRARI_H4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + SRARI_H2(RTYPE, in0, in1, shift); \ + SRARI_H2(RTYPE, in2, in3, shift); \ +} +#define SRARI_H4_UH(...) SRARI_H4(v8u16, __VA_ARGS__) +#define SRARI_H4_SH(...) SRARI_H4(v8i16, __VA_ARGS__) + +/* Description : Shift right arithmetic rounded (immediate) + Arguments : Inputs - in0, in1, shift + Outputs - in0, in1 (in place) + Return Type - as per RTYPE + Details : Each element of vector 'in0' is shifted right arithmetic by + value in 'shift'. + The last discarded bit is added to shifted value for rounding + and the result is in place written to 'in0' + Similar for other pairs +*/ +#define SRARI_W2(RTYPE, in0, in1, shift) \ +{ \ + in0 = (RTYPE) __msa_srari_w((v4i32) in0, shift); \ + in1 = (RTYPE) __msa_srari_w((v4i32) in1, shift); \ +} +#define SRARI_W2_SW(...) SRARI_W2(v4i32, __VA_ARGS__) + +#define SRARI_W4(RTYPE, in0, in1, in2, in3, shift) \ +{ \ + SRARI_W2(RTYPE, in0, in1, shift); \ + SRARI_W2(RTYPE, in2, in3, shift); \ +} +#define SRARI_W4_SH(...) SRARI_W4(v8i16, __VA_ARGS__) +#define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__) + +/* Description : Multiplication of pairs of vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Details : Each element from 'in0' is multiplied with elements from 'in1' + and result is written to 'out0' + Similar for other pairs +*/ +#define MUL2(in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = in0 * in1; \ + out1 = in2 * in3; \ +} +#define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ +{ \ + MUL2(in0, in1, in2, in3, out0, out1); \ + MUL2(in4, in5, in6, in7, out2, out3); \ +} + +/* Description : Addition of 2 pairs of vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Details : Each element from 2 pairs vectors is added and 2 results are + produced +*/ +#define ADD2(in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = in0 + in1; \ + out1 = in2 + in3; \ +} +#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ +{ \ + ADD2(in0, in1, in2, in3, out0, out1); \ + ADD2(in4, in5, in6, in7, out2, out3); \ +} + +/* Description : Subtraction of 2 pairs of vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1 + Details : Each element from 2 pairs vectors is subtracted and 2 results + are produced +*/ +#define SUB2(in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = in0 - in1; \ + out1 = in2 - in3; \ +} +#define SUB4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ +{ \ + out0 = in0 - in1; \ + out1 = in2 - in3; \ + out2 = in4 - in5; \ + out3 = in6 - in7; \ +} + +/* Description : Sign extend byte elements from right half of the vector + Arguments : Input - in (byte vector) + Output - out (sign extended halfword vector) + Return Type - signed halfword + Details : Sign bit of byte elements from input vector 'in' is + extracted and interleaved with same vector 'in' to generate + 8 halfword elements keeping sign intact +*/ +#define UNPCK_R_SB_SH(in, out) \ +{ \ + v16i8 sign_m; \ + \ + sign_m = __msa_clti_s_b((v16i8) in, 0); \ + out = (v8i16) __msa_ilvr_b(sign_m, (v16i8) in); \ +} + +/* Description : Sign extend halfword elements from right half of the vector + Arguments : Inputs - in (input halfword vector) + Outputs - out (sign extended word vectors) + Return Type - signed word + Details : Sign bit of halfword elements from input vector 'in' is + extracted and interleaved with same vector 'in0' to generate + 4 word elements keeping sign intact +*/ +#define UNPCK_R_SH_SW(in, out) \ +{ \ + v8i16 sign_m; \ + \ + sign_m = __msa_clti_s_h((v8i16) in, 0); \ + out = (v4i32) __msa_ilvr_h(sign_m, (v8i16) in); \ +} + +/* Description : Sign extend byte elements from input vector and return + halfword results in pair of vectors + Arguments : Inputs - in (1 input byte vector) + Outputs - out0, out1 (sign extended 2 halfword vectors) + Return Type - signed halfword + Details : Sign bit of byte elements from input vector 'in' is + extracted and interleaved right with same vector 'in0' to + generate 8 signed halfword elements in 'out0' + Then interleaved left with same vector 'in0' to + generate 8 signed halfword elements in 'out1' +*/ +#define UNPCK_SB_SH(in, out0, out1) \ +{ \ + v16i8 tmp_m; \ + \ + tmp_m = __msa_clti_s_b((v16i8) in, 0); \ + ILVRL_B2_SH(tmp_m, in, out0, out1); \ +} + +/* Description : Zero extend unsigned byte elements to halfword elements + Arguments : Inputs - in (1 input unsigned byte vector) + Outputs - out0, out1 (unsigned 2 halfword vectors) + Return Type - signed halfword + Details : Zero extended right half of vector is returned in 'out0' + Zero extended left half of vector is returned in 'out1' +*/ +#define UNPCK_UB_SH(in, out0, out1) \ +{ \ + v16i8 zero_m = { 0 }; \ + \ + ILVRL_B2_SH(zero_m, in, out0, out1); \ +} + +/* Description : Sign extend halfword elements from input vector and return + result in pair of vectors + Arguments : Inputs - in (1 input halfword vector) + Outputs - out0, out1 (sign extended 2 word vectors) + Return Type - signed word + Details : Sign bit of halfword elements from input vector 'in' is + extracted and interleaved right with same vector 'in0' to + generate 4 signed word elements in 'out0' + Then interleaved left with same vector 'in0' to + generate 4 signed word elements in 'out1' +*/ +#define UNPCK_SH_SW(in, out0, out1) \ +{ \ + v8i16 tmp_m; \ + \ + tmp_m = __msa_clti_s_h((v8i16) in, 0); \ + ILVRL_H2_SW(tmp_m, in, out0, out1); \ +} + +/* Description : Swap two variables + Arguments : Inputs - in0, in1 + Outputs - in0, in1 (in-place) + Details : Swapping of two input variables using xor +*/ +#define SWAP(in0, in1) \ +{ \ + in0 = in0 ^ in1; \ + in1 = in0 ^ in1; \ + in0 = in0 ^ in1; \ +} + +/* Description : Butterfly of 4 input vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1, out2, out3 + Details : Butterfly operation +*/ +#define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + out0 = in0 + in3; \ + out1 = in1 + in2; \ + \ + out2 = in1 - in2; \ + out3 = in0 - in3; \ +} + +/* Description : Butterfly of 8 input vectors + Arguments : Inputs - in0 ... in7 + Outputs - out0 .. out7 + Details : Butterfly operation +*/ +#define BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + out0 = in0 + in7; \ + out1 = in1 + in6; \ + out2 = in2 + in5; \ + out3 = in3 + in4; \ + \ + out4 = in3 - in4; \ + out5 = in2 - in5; \ + out6 = in1 - in6; \ + out7 = in0 - in7; \ +} + +/* Description : Butterfly of 16 input vectors + Arguments : Inputs - in0 ... in15 + Outputs - out0 .. out15 + Details : Butterfly operation +*/ +#define BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, \ + in8, in9, in10, in11, in12, in13, in14, in15, \ + out0, out1, out2, out3, out4, out5, out6, out7, \ + out8, out9, out10, out11, out12, out13, out14, out15) \ +{ \ + out0 = in0 + in15; \ + out1 = in1 + in14; \ + out2 = in2 + in13; \ + out3 = in3 + in12; \ + out4 = in4 + in11; \ + out5 = in5 + in10; \ + out6 = in6 + in9; \ + out7 = in7 + in8; \ + \ + out8 = in7 - in8; \ + out9 = in6 - in9; \ + out10 = in5 - in10; \ + out11 = in4 - in11; \ + out12 = in3 - in12; \ + out13 = in2 - in13; \ + out14 = in1 - in14; \ + out15 = in0 - in15; \ +} + +/* Description : Transposes input 4x4 byte block + Arguments : Inputs - in0, in1, in2, in3 (input 4x4 byte block) + Outputs - out0, out1, out2, out3 (output 4x4 byte block) + Return Type - unsigned byte + Details : +*/ +#define TRANSPOSE4x4_UB_UB(in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + v16i8 zero_m = { 0 }; \ + v16i8 s0_m, s1_m, s2_m, s3_m; \ + \ + ILVR_D2_SB(in1, in0, in3, in2, s0_m, s1_m); \ + ILVRL_B2_SB(s1_m, s0_m, s2_m, s3_m); \ + \ + out0 = (v16u8) __msa_ilvr_b(s3_m, s2_m); \ + out1 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out0, 4); \ + out2 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out1, 4); \ + out3 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out2, 4); \ +} + +/* Description : Transposes input 8x4 byte block into 4x8 + Arguments : Inputs - in0, in1, in2, in3 (input 8x4 byte block) + Outputs - out0, out1, out2, out3 (output 4x8 byte block) + Return Type - as per RTYPE + Details : +*/ +#define TRANSPOSE8x4_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + \ + ILVEV_W2_SB(in0, in4, in1, in5, tmp0_m, tmp1_m); \ + tmp2_m = __msa_ilvr_b(tmp1_m, tmp0_m); \ + ILVEV_W2_SB(in2, in6, in3, in7, tmp0_m, tmp1_m); \ + \ + tmp3_m = __msa_ilvr_b(tmp1_m, tmp0_m); \ + ILVRL_H2_SB(tmp3_m, tmp2_m, tmp0_m, tmp1_m); \ + \ + ILVRL_W2(RTYPE, tmp1_m, tmp0_m, out0, out2); \ + out1 = (RTYPE) __msa_ilvl_d((v2i64) out2, (v2i64) out0); \ + out3 = (RTYPE) __msa_ilvl_d((v2i64) out0, (v2i64) out2); \ +} +#define TRANSPOSE8x4_UB_UB(...) TRANSPOSE8x4_UB(v16u8, __VA_ARGS__) +#define TRANSPOSE8x4_UB_UH(...) TRANSPOSE8x4_UB(v8u16, __VA_ARGS__) + +/* Description : Transposes input 8x8 byte block + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + (input 8x8 byte block) + Outputs - out0, out1, out2, out3, out4, out5, out6, out7 + (output 8x8 byte block) + Return Type - as per RTYPE + Details : +*/ +#define TRANSPOSE8x8_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + v16i8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ + v16i8 zeros = { 0 }; \ + \ + ILVR_B4_SB(in2, in0, in3, in1, in6, in4, in7, in5, \ + tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ + ILVRL_B2_SB(tmp1_m, tmp0_m, tmp4_m, tmp5_m); \ + ILVRL_B2_SB(tmp3_m, tmp2_m, tmp6_m, tmp7_m); \ + ILVRL_W2(RTYPE, tmp6_m, tmp4_m, out0, out2); \ + ILVRL_W2(RTYPE, tmp7_m, tmp5_m, out4, out6); \ + SLDI_B4(RTYPE, zeros, out0, zeros, out2, zeros, out4, zeros, out6, \ + 8, out1, out3, out5, out7); \ +} +#define TRANSPOSE8x8_UB_UB(...) TRANSPOSE8x8_UB(v16u8, __VA_ARGS__) +#define TRANSPOSE8x8_UB_UH(...) TRANSPOSE8x8_UB(v8u16, __VA_ARGS__) + +/* Description : Transposes 16x4 block into 4x16 with byte elements in vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, + in8, in9, in10, in11, in12, in13, in14, in15 + Outputs - out0, out1, out2, out3 + Return Type - unsigned byte + Details : +*/ +#define TRANSPOSE16x4_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + in8, in9, in10, in11, in12, in13, in14, in15, \ + out0, out1, out2, out3) \ +{ \ + v2i64 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + \ + ILVEV_W2_SD(in0, in4, in8, in12, tmp0_m, tmp1_m); \ + out1 = (v16u8) __msa_ilvev_d(tmp1_m, tmp0_m); \ + \ + ILVEV_W2_SD(in1, in5, in9, in13, tmp0_m, tmp1_m); \ + out3 = (v16u8) __msa_ilvev_d(tmp1_m, tmp0_m); \ + \ + ILVEV_W2_SD(in2, in6, in10, in14, tmp0_m, tmp1_m); \ + \ + tmp2_m = __msa_ilvev_d(tmp1_m, tmp0_m); \ + ILVEV_W2_SD(in3, in7, in11, in15, tmp0_m, tmp1_m); \ + \ + tmp3_m = __msa_ilvev_d(tmp1_m, tmp0_m); \ + ILVEV_B2_SD(out1, out3, tmp2_m, tmp3_m, tmp0_m, tmp1_m); \ + out0 = (v16u8) __msa_ilvev_h((v8i16) tmp1_m, (v8i16) tmp0_m); \ + out2 = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m); \ + \ + tmp0_m = (v2i64) __msa_ilvod_b((v16i8) out3, (v16i8) out1); \ + tmp1_m = (v2i64) __msa_ilvod_b((v16i8) tmp3_m, (v16i8) tmp2_m); \ + out1 = (v16u8) __msa_ilvev_h((v8i16) tmp1_m, (v8i16) tmp0_m); \ + out3 = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m); \ +} + +/* Description : Transposes 16x8 block into 8x16 with byte elements in vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, + in8, in9, in10, in11, in12, in13, in14, in15 + Outputs - out0, out1, out2, out3, out4, out5, out6, out7 + Return Type - unsigned byte + Details : +*/ +#define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + in8, in9, in10, in11, in12, in13, in14, in15, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + v16u8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ + \ + ILVEV_D2_UB(in0, in8, in1, in9, out7, out6); \ + ILVEV_D2_UB(in2, in10, in3, in11, out5, out4); \ + ILVEV_D2_UB(in4, in12, in5, in13, out3, out2); \ + ILVEV_D2_UB(in6, in14, in7, in15, out1, out0); \ + \ + tmp0_m = (v16u8) __msa_ilvev_b((v16i8) out6, (v16i8) out7); \ + tmp4_m = (v16u8) __msa_ilvod_b((v16i8) out6, (v16i8) out7); \ + tmp1_m = (v16u8) __msa_ilvev_b((v16i8) out4, (v16i8) out5); \ + tmp5_m = (v16u8) __msa_ilvod_b((v16i8) out4, (v16i8) out5); \ + out5 = (v16u8) __msa_ilvev_b((v16i8) out2, (v16i8) out3); \ + tmp6_m = (v16u8) __msa_ilvod_b((v16i8) out2, (v16i8) out3); \ + out7 = (v16u8) __msa_ilvev_b((v16i8) out0, (v16i8) out1); \ + tmp7_m = (v16u8) __msa_ilvod_b((v16i8) out0, (v16i8) out1); \ + \ + ILVEV_H2_UB(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m); \ + out0 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + out4 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + \ + tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m); \ + tmp3_m = (v16u8) __msa_ilvod_h((v8i16) out7, (v8i16) out5); \ + out2 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + out6 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + \ + ILVEV_H2_UB(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m); \ + out1 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + out5 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + \ + tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp5_m, (v8i16) tmp4_m); \ + tmp3_m = (v16u8) __msa_ilvod_h((v8i16) tmp7_m, (v8i16) tmp6_m); \ + out3 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ + out7 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m); \ +} + +/* Description : Transposes 4x4 block with half word elements in vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1, out2, out3 + Return Type - signed halfword + Details : +*/ +#define TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + v8i16 s0_m, s1_m; \ + \ + ILVR_H2_SH(in1, in0, in3, in2, s0_m, s1_m); \ + ILVRL_W2_SH(s1_m, s0_m, out0, out2); \ + out1 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out0); \ + out3 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out2); \ +} + +/* Description : Transposes 8x8 block with half word elements in vectors + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 + Outputs - out0, out1, out2, out3, out4, out5, out6, out7 + Return Type - as per RTYPE + Details : +*/ +#define TRANSPOSE8x8_H(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3, out4, out5, out6, out7) \ +{ \ + v8i16 s0_m, s1_m; \ + v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + v8i16 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ + \ + ILVR_H2_SH(in6, in4, in7, in5, s0_m, s1_m); \ + ILVRL_H2_SH(s1_m, s0_m, tmp0_m, tmp1_m); \ + ILVL_H2_SH(in6, in4, in7, in5, s0_m, s1_m); \ + ILVRL_H2_SH(s1_m, s0_m, tmp2_m, tmp3_m); \ + ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ + ILVRL_H2_SH(s1_m, s0_m, tmp4_m, tmp5_m); \ + ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ + ILVRL_H2_SH(s1_m, s0_m, tmp6_m, tmp7_m); \ + PCKEV_D4(RTYPE, tmp0_m, tmp4_m, tmp1_m, tmp5_m, tmp2_m, tmp6_m, \ + tmp3_m, tmp7_m, out0, out2, out4, out6); \ + out1 = (RTYPE) __msa_pckod_d((v2i64) tmp0_m, (v2i64) tmp4_m); \ + out3 = (RTYPE) __msa_pckod_d((v2i64) tmp1_m, (v2i64) tmp5_m); \ + out5 = (RTYPE) __msa_pckod_d((v2i64) tmp2_m, (v2i64) tmp6_m); \ + out7 = (RTYPE) __msa_pckod_d((v2i64) tmp3_m, (v2i64) tmp7_m); \ +} +#define TRANSPOSE8x8_UH_UH(...) TRANSPOSE8x8_H(v8u16, __VA_ARGS__) +#define TRANSPOSE8x8_SH_SH(...) TRANSPOSE8x8_H(v8i16, __VA_ARGS__) + +/* Description : Transposes 4x4 block with word elements in vectors + Arguments : Inputs - in0, in1, in2, in3 + Outputs - out0, out1, out2, out3 + Return Type - signed word + Details : +*/ +#define TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, out0, out1, out2, out3) \ +{ \ + v4i32 s0_m, s1_m, s2_m, s3_m; \ + \ + ILVRL_W2_SW(in1, in0, s0_m, s1_m); \ + ILVRL_W2_SW(in3, in2, s2_m, s3_m); \ + \ + out0 = (v4i32) __msa_ilvr_d((v2i64) s2_m, (v2i64) s0_m); \ + out1 = (v4i32) __msa_ilvl_d((v2i64) s2_m, (v2i64) s0_m); \ + out2 = (v4i32) __msa_ilvr_d((v2i64) s3_m, (v2i64) s1_m); \ + out3 = (v4i32) __msa_ilvl_d((v2i64) s3_m, (v2i64) s1_m); \ +} + +/* Description : Average byte elements from pair of vectors and store 8x4 byte + block in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + averaged (a + b)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + averaged (a + b)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + averaged (a + b)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + averaged (a + b)/2 and stored in 'tmp3_m' + The half vector results from all 4 vectors are stored in + destination memory as 8x4 byte block +*/ +#define AVE_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + uint64_t out0_m, out1_m, out2_m, out3_m; \ + v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + \ + tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1); \ + tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3); \ + tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5); \ + tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7); \ + \ + out0_m = __msa_copy_u_d((v2i64) tmp0_m, 0); \ + out1_m = __msa_copy_u_d((v2i64) tmp1_m, 0); \ + out2_m = __msa_copy_u_d((v2i64) tmp2_m, 0); \ + out3_m = __msa_copy_u_d((v2i64) tmp3_m, 0); \ + SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride); \ +} + +/* Description : Average byte elements from pair of vectors and store 16x4 byte + block in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + averaged (a + b)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + averaged (a + b)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + averaged (a + b)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + averaged (a + b)/2 and stored in 'tmp3_m' + The results from all 4 vectors are stored in destination + memory as 16x4 byte block +*/ +#define AVE_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + \ + tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1); \ + tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3); \ + tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5); \ + tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7); \ + \ + ST_UB4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, pdst, stride); \ +} + +/* Description : Average rounded byte elements from pair of vectors and store + 8x4 byte block in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + average rounded (a + b + 1)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + average rounded (a + b + 1)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + average rounded (a + b + 1)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + average rounded (a + b + 1)/2 and stored in 'tmp3_m' + The half vector results from all 4 vectors are stored in + destination memory as 8x4 byte block +*/ +#define AVER_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + uint64_t out0_m, out1_m, out2_m, out3_m; \ + v16u8 tp0_m, tp1_m, tp2_m, tp3_m; \ + \ + AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + tp0_m, tp1_m, tp2_m, tp3_m); \ + \ + out0_m = __msa_copy_u_d((v2i64) tp0_m, 0); \ + out1_m = __msa_copy_u_d((v2i64) tp1_m, 0); \ + out2_m = __msa_copy_u_d((v2i64) tp2_m, 0); \ + out3_m = __msa_copy_u_d((v2i64) tp3_m, 0); \ + SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride); \ +} + +/* Description : Average rounded byte elements from pair of vectors and store + 16x4 byte block in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + average rounded (a + b + 1)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + average rounded (a + b + 1)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + average rounded (a + b + 1)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + average rounded (a + b + 1)/2 and stored in 'tmp3_m' + The vector results from all 4 vectors are stored in + destination memory as 16x4 byte block +*/ +#define AVER_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ +{ \ + v16u8 t0_m, t1_m, t2_m, t3_m; \ + \ + AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + t0_m, t1_m, t2_m, t3_m); \ + ST_UB4(t0_m, t1_m, t2_m, t3_m, pdst, stride); \ +} + +/* Description : Average rounded byte elements from pair of vectors, + average rounded with destination and store 8x4 byte block + in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + average rounded (a + b + 1)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + average rounded (a + b + 1)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + average rounded (a + b + 1)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + average rounded (a + b + 1)/2 and stored in 'tmp3_m' + The half vector results from all 4 vectors are stored in + destination memory as 8x4 byte block +*/ +#define AVER_DST_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + v16u8 dst0_m, dst1_m, dst2_m, dst3_m; \ + \ + LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m); \ + AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ + AVER_ST8x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m, \ + dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride); \ +} + +/* Description : Average rounded byte elements from pair of vectors, + average rounded with destination and store 16x4 byte block + in destination memory + Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride + Details : Each byte element from input vector pair 'in0' and 'in1' are + average rounded (a + b + 1)/2 and stored in 'tmp0_m' + Each byte element from input vector pair 'in2' and 'in3' are + average rounded (a + b + 1)/2 and stored in 'tmp1_m' + Each byte element from input vector pair 'in4' and 'in5' are + average rounded (a + b + 1)/2 and stored in 'tmp2_m' + Each byte element from input vector pair 'in6' and 'in7' are + average rounded (a + b + 1)/2 and stored in 'tmp3_m' + The vector results from all 4 vectors are stored in + destination memory as 16x4 byte block +*/ +#define AVER_DST_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ + v16u8 dst0_m, dst1_m, dst2_m, dst3_m; \ + \ + LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m); \ + AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7, \ + tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ + AVER_ST16x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m, \ + dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride); \ +} + +/* Description : Add block 4x4 + Arguments : Inputs - in0, in1, in2, in3, pdst, stride + Details : Least significant 4 bytes from each input vector are added to + the destination bytes, clipped between 0-255 and then stored. +*/ +#define ADDBLK_ST4x4_UB(in0, in1, in2, in3, pdst, stride) \ +{ \ + uint32_t src0_m, src1_m, src2_m, src3_m; \ + uint32_t out0_m, out1_m, out2_m, out3_m; \ + v8i16 inp0_m, inp1_m, res0_m, res1_m; \ + v16i8 dst0_m = { 0 }; \ + v16i8 dst1_m = { 0 }; \ + v16i8 zero_m = { 0 }; \ + \ + ILVR_D2_SH(in1, in0, in3, in2, inp0_m, inp1_m) \ + LW4(pdst, stride, src0_m, src1_m, src2_m, src3_m); \ + INSERT_W2_SB(src0_m, src1_m, dst0_m); \ + INSERT_W2_SB(src2_m, src3_m, dst1_m); \ + ILVR_B2_SH(zero_m, dst0_m, zero_m, dst1_m, res0_m, res1_m); \ + ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m); \ + CLIP_SH2_0_255(res0_m, res1_m); \ + PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m); \ + \ + out0_m = __msa_copy_u_w((v4i32) dst0_m, 0); \ + out1_m = __msa_copy_u_w((v4i32) dst0_m, 1); \ + out2_m = __msa_copy_u_w((v4i32) dst1_m, 0); \ + out3_m = __msa_copy_u_w((v4i32) dst1_m, 1); \ + SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride); \ +} + +/* Description : Dot product and addition of 3 signed halfword input vectors + Arguments : Inputs - in0, in1, in2, coeff0, coeff1, coeff2 + Outputs - out0_m + Return Type - signed halfword + Details : Dot product of 'in0' with 'coeff0' + Dot product of 'in1' with 'coeff1' + Dot product of 'in2' with 'coeff2' + Addition of all the 3 vector results + + out0_m = (in0 * coeff0) + (in1 * coeff1) + (in2 * coeff2) +*/ +#define DPADD_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2) \ +( { \ + v8i16 out0_m; \ + \ + out0_m = __msa_dotp_s_h((v16i8) in0, (v16i8) coeff0); \ + out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in1, (v16i8) coeff1); \ + out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in2, (v16i8) coeff2); \ + \ + out0_m; \ +} ) + +/* Description : Pack even elements of input vectors & xor with 128 + Arguments : Inputs - in0, in1 + Outputs - out_m + Return Type - unsigned byte + Details : Signed byte even elements from 'in0' and 'in1' are packed + together in one vector and the resulted vector is xor'ed with + 128 to shift the range from signed to unsigned byte +*/ +#define PCKEV_XORI128_UB(in0, in1) \ +( { \ + v16u8 out_m; \ + out_m = (v16u8) __msa_pckev_b((v16i8) in1, (v16i8) in0); \ + out_m = (v16u8) __msa_xori_b((v16u8) out_m, 128); \ + out_m; \ +} ) + +/* Description : Converts inputs to unsigned bytes, interleave, average & store + as 8x4 unsigned byte block + Arguments : Inputs - in0, in1, in2, in3, dst0, dst1, pdst, stride +*/ +#define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3, \ + dst0, dst1, pdst, stride) \ +{ \ + v16u8 tmp0_m, tmp1_m; \ + uint8_t *pdst_m = (uint8_t *) (pdst); \ + \ + tmp0_m = PCKEV_XORI128_UB(in0, in1); \ + tmp1_m = PCKEV_XORI128_UB(in2, in3); \ + AVER_UB2_UB(tmp0_m, dst0, tmp1_m, dst1, tmp0_m, tmp1_m); \ + ST_D4(tmp0_m, tmp1_m, 0, 1, 0, 1, pdst_m, stride); \ +} + +/* Description : Pack even byte elements, extract 0 & 2 index words from pair + of results and store 4 words in destination memory as per + stride + Arguments : Inputs - in0, in1, in2, in3, pdst, stride +*/ +#define PCKEV_ST4x4_UB(in0, in1, in2, in3, pdst, stride) \ +{ \ + uint32_t out0_m, out1_m, out2_m, out3_m; \ + v16i8 tmp0_m, tmp1_m; \ + \ + PCKEV_B2_SB(in1, in0, in3, in2, tmp0_m, tmp1_m); \ + \ + out0_m = __msa_copy_u_w((v4i32) tmp0_m, 0); \ + out1_m = __msa_copy_u_w((v4i32) tmp0_m, 2); \ + out2_m = __msa_copy_u_w((v4i32) tmp1_m, 0); \ + out3_m = __msa_copy_u_w((v4i32) tmp1_m, 2); \ + \ + SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride); \ +} + +/* Description : Pack even byte elements and store byte vector in destination + memory + Arguments : Inputs - in0, in1, pdst +*/ +#define PCKEV_ST_SB(in0, in1, pdst) \ +{ \ + v16i8 tmp_m; \ + tmp_m = __msa_pckev_b((v16i8) in1, (v16i8) in0); \ + ST_SB(tmp_m, (pdst)); \ +} + +/* Description : Horizontal 2 tap filter kernel code + Arguments : Inputs - in0, in1, mask, coeff, shift +*/ +#define HORIZ_2TAP_FILT_UH(in0, in1, mask, coeff, shift) \ +( { \ + v16i8 tmp0_m; \ + v8u16 tmp1_m; \ + \ + tmp0_m = __msa_vshf_b((v16i8) mask, (v16i8) in1, (v16i8) in0); \ + tmp1_m = __msa_dotp_u_h((v16u8) tmp0_m, (v16u8) coeff); \ + tmp1_m = (v8u16) __msa_srari_h((v8i16) tmp1_m, shift); \ + tmp1_m = __msa_sat_u_h(tmp1_m, shift); \ + \ + tmp1_m; \ +} ) +#endif /* AVUTIL_MIPS_GENERIC_MACROS_MSA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/intreadwrite.h new file mode 100644 index 00000000..32084f68 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/intreadwrite.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MIPS_INTREADWRITE_H +#define AVUTIL_MIPS_INTREADWRITE_H + +#include +#include "config.h" + +#if ARCH_MIPS64 && HAVE_INLINE_ASM && !HAVE_MIPS64R6 + +#define AV_RN32 AV_RN32 +static av_always_inline uint32_t AV_RN32(const void *p) +{ + struct __attribute__((packed)) u32 { uint32_t v; }; + const uint8_t *q = p; + const struct u32 *pl = (const struct u32 *)(q + 3 * !HAVE_BIGENDIAN); + const struct u32 *pr = (const struct u32 *)(q + 3 * HAVE_BIGENDIAN); + uint32_t v; + __asm__ ("lwl %0, %1 \n\t" + "lwr %0, %2 \n\t" + : "=&r"(v) + : "m"(*pl), "m"(*pr)); + return v; +} + +#endif /* ARCH_MIPS64 && HAVE_INLINE_ASM && !HAVE_MIPS64R6 */ + +#endif /* AVUTIL_MIPS_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/libm_mips.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/libm_mips.h new file mode 100644 index 00000000..fbf7cf41 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/libm_mips.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * 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. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MIPS optimization for some libm functions + */ + +#ifndef AVUTIL_MIPS_LIBM_MIPS_H +#define AVUTIL_MIPS_LIBM_MIPS_H + +#include "libavutil/attributes.h" + +static av_always_inline av_const long int lrintf_mips(float x) +{ + register int ret_int; + + __asm__ volatile ( + "cvt.w.s %[x], %[x] \n\t" + "mfc1 %[ret_int], %[x] \n\t" + + :[x]"+f"(x), [ret_int]"=r"(ret_int) + ); + return ret_int; +} + +#undef lrintf +#define lrintf(x) lrintf_mips(x) + +#define HAVE_LRINTF 1 +#endif /* AVUTIL_MIPS_LIBM_MIPS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/mips/mmiutils.h b/arm/raspi/third_party/ffmpeg/libavutil/mips/mmiutils.h new file mode 100644 index 00000000..7991e14e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/mips/mmiutils.h @@ -0,0 +1,392 @@ +/* + * Loongson SIMD utils + * + * Copyright (c) 2016 Loongson Technology Corporation Limited + * Copyright (c) 2016 Zhou Xiaoyong + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MIPS_MMIUTILS_H +#define AVUTIL_MIPS_MMIUTILS_H + +#include "config.h" + +#include "libavutil/mem_internal.h" +#include "libavutil/mips/asmdefs.h" + +/* + * These were used to define temporary registers for MMI marcos + * however now we're using $at. They're theoretically unnecessary + * but just leave them here to avoid mess. + */ +#define DECLARE_VAR_LOW32 +#define RESTRICT_ASM_LOW32 +#define DECLARE_VAR_ALL64 +#define RESTRICT_ASM_ALL64 +#define DECLARE_VAR_ADDRT +#define RESTRICT_ASM_ADDRT + +#if HAVE_LOONGSON2 + +#define MMI_LWX(reg, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + "lw "#reg", "#bias"($at) \n\t" \ + ".set at \n\t" + +#define MMI_SWX(reg, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + "sw "#reg", "#bias"($at) \n\t" \ + ".set at \n\t" + +#define MMI_LDX(reg, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + "ld "#reg", "#bias"($at) \n\t" \ + ".set at \n\t" + +#define MMI_SDX(reg, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + "sd "#reg", "#bias"($at) \n\t" \ + ".set at \n\t" + +#define MMI_LWC1(fp, addr, bias) \ + "lwc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_ULWC1(fp, addr, bias) \ + ".set noat \n\t" \ + "ulw $at, "#bias"("#addr") \n\t" \ + "mtc1 $at, "#fp" \n\t" \ + ".set at \n\t" + +#define MMI_LWXC1(fp, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + MMI_LWC1(fp, $at, bias) \ + ".set at \n\t" + +#define MMI_SWC1(fp, addr, bias) \ + "swc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_USWC1(fp, addr, bias) \ + ".set noat \n\t" \ + "mfc1 $at, "#fp" \n\t" \ + "usw $at, "#bias"("#addr") \n\t" \ + ".set at \n\t" + +#define MMI_SWXC1(fp, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + MMI_SWC1(fp, $at, bias) \ + ".set at \n\t" + +#define MMI_LDC1(fp, addr, bias) \ + "ldc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_ULDC1(fp, addr, bias) \ + ".set noat \n\t" \ + "uld $at, "#bias"("#addr") \n\t" \ + "dmtc1 $at, "#fp" \n\t" \ + ".set at \n\t" + +#define MMI_LDXC1(fp, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + MMI_LDC1(fp, $at, bias) \ + ".set at \n\t" + +#define MMI_SDC1(fp, addr, bias) \ + "sdc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_USDC1(fp, addr, bias) \ + ".set noat \n\t" \ + "dmfc1 $at, "#fp" \n\t" \ + "usd $at, "#bias"("#addr") \n\t" \ + ".set at \n\t" + +#define MMI_SDXC1(fp, addr, stride, bias) \ + ".set noat \n\t" \ + PTR_ADDU "$at, "#addr", "#stride" \n\t" \ + MMI_SDC1(fp, $at, bias) \ + ".set at \n\t" + +#define MMI_LQ(reg1, reg2, addr, bias) \ + "ld "#reg1", "#bias"("#addr") \n\t" \ + "ld "#reg2", 8+"#bias"("#addr") \n\t" + +#define MMI_SQ(reg1, reg2, addr, bias) \ + "sd "#reg1", "#bias"("#addr") \n\t" \ + "sd "#reg2", 8+"#bias"("#addr") \n\t" + +#define MMI_LQC1(fp1, fp2, addr, bias) \ + "ldc1 "#fp1", "#bias"("#addr") \n\t" \ + "ldc1 "#fp2", 8+"#bias"("#addr") \n\t" + +#define MMI_SQC1(fp1, fp2, addr, bias) \ + "sdc1 "#fp1", "#bias"("#addr") \n\t" \ + "sdc1 "#fp2", 8+"#bias"("#addr") \n\t" + +#elif HAVE_LOONGSON3 /* !HAVE_LOONGSON2 */ + +#define MMI_LWX(reg, addr, stride, bias) \ + "gslwx "#reg", "#bias"("#addr", "#stride") \n\t" + +#define MMI_SWX(reg, addr, stride, bias) \ + "gsswx "#reg", "#bias"("#addr", "#stride") \n\t" + +#define MMI_LDX(reg, addr, stride, bias) \ + "gsldx "#reg", "#bias"("#addr", "#stride") \n\t" + +#define MMI_SDX(reg, addr, stride, bias) \ + "gssdx "#reg", "#bias"("#addr", "#stride") \n\t" + +#define MMI_LWC1(fp, addr, bias) \ + "lwc1 "#fp", "#bias"("#addr") \n\t" + +#if _MIPS_SIM == _ABIO32 /* workaround for 3A2000 gslwlc1 bug */ + +#define MMI_LWLRC1(fp, addr, bias, off) \ + ".set noat \n\t" \ + "lwl $at, "#bias"+"#off"("#addr") \n\t" \ + "lwr $at, "#bias"("#addr") \n\t" \ + "mtc1 $at, "#fp" \n\t" \ + ".set at \n\t" + +#else /* _MIPS_SIM != _ABIO32 */ + +#define DECLARE_VAR_LOW32 +#define RESTRICT_ASM_LOW32 + +#define MMI_ULWC1(fp, addr, bias) \ + "gslwlc1 "#fp", 3+"#bias"("#addr") \n\t" \ + "gslwrc1 "#fp", "#bias"("#addr") \n\t" + +#endif /* _MIPS_SIM != _ABIO32 */ + +#define MMI_LWXC1(fp, addr, stride, bias) \ + "gslwxc1 "#fp", "#bias"("#addr", "#stride") \n\t" + +#define MMI_SWC1(fp, addr, bias) \ + "swc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_USWC1(fp, addr, bias) \ + "gsswlc1 "#fp", 3+"#bias"("#addr") \n\t" \ + "gsswrc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_SWXC1(fp, addr, stride, bias) \ + "gsswxc1 "#fp", "#bias"("#addr", "#stride") \n\t" + +#define MMI_LDC1(fp, addr, bias) \ + "ldc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_ULDC1(fp, addr, bias) \ + "gsldlc1 "#fp", 7+"#bias"("#addr") \n\t" \ + "gsldrc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_LDXC1(fp, addr, stride, bias) \ + "gsldxc1 "#fp", "#bias"("#addr", "#stride") \n\t" + +#define MMI_SDC1(fp, addr, bias) \ + "sdc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_USDC1(fp, addr, bias) \ + "gssdlc1 "#fp", 7+"#bias"("#addr") \n\t" \ + "gssdrc1 "#fp", "#bias"("#addr") \n\t" + +#define MMI_SDXC1(fp, addr, stride, bias) \ + "gssdxc1 "#fp", "#bias"("#addr", "#stride") \n\t" + +#define MMI_LQ(reg1, reg2, addr, bias) \ + "gslq "#reg1", "#reg2", "#bias"("#addr") \n\t" + +#define MMI_SQ(reg1, reg2, addr, bias) \ + "gssq "#reg1", "#reg2", "#bias"("#addr") \n\t" + +#define MMI_LQC1(fp1, fp2, addr, bias) \ + "gslqc1 "#fp1", "#fp2", "#bias"("#addr") \n\t" + +#define MMI_SQC1(fp1, fp2, addr, bias) \ + "gssqc1 "#fp1", "#fp2", "#bias"("#addr") \n\t" + +#endif /* HAVE_LOONGSON2 */ + +/** + * Backup saved registers + * We're not using compiler's clobber list as it's not smart enough + * to take advantage of quad word load/store. + */ +#define BACKUP_REG \ + LOCAL_ALIGNED_16(double, temp_backup_reg, [8]); \ + if (_MIPS_SIM == _ABI64) \ + __asm__ volatile ( \ + MMI_SQC1($f25, $f24, %[temp], 0x00) \ + MMI_SQC1($f27, $f26, %[temp], 0x10) \ + MMI_SQC1($f29, $f28, %[temp], 0x20) \ + MMI_SQC1($f31, $f30, %[temp], 0x30) \ + : \ + : [temp]"r"(temp_backup_reg) \ + : "memory" \ + ); \ + else \ + __asm__ volatile ( \ + MMI_SQC1($f22, $f20, %[temp], 0x10) \ + MMI_SQC1($f26, $f24, %[temp], 0x10) \ + MMI_SQC1($f30, $f28, %[temp], 0x20) \ + : \ + : [temp]"r"(temp_backup_reg) \ + : "memory" \ + ); + +/** + * recover register + */ +#define RECOVER_REG \ + if (_MIPS_SIM == _ABI64) \ + __asm__ volatile ( \ + MMI_LQC1($f25, $f24, %[temp], 0x00) \ + MMI_LQC1($f27, $f26, %[temp], 0x10) \ + MMI_LQC1($f29, $f28, %[temp], 0x20) \ + MMI_LQC1($f31, $f30, %[temp], 0x30) \ + : \ + : [temp]"r"(temp_backup_reg) \ + : "memory" \ + ); \ + else \ + __asm__ volatile ( \ + MMI_LQC1($f22, $f20, %[temp], 0x10) \ + MMI_LQC1($f26, $f24, %[temp], 0x10) \ + MMI_LQC1($f30, $f28, %[temp], 0x20) \ + : \ + : [temp]"r"(temp_backup_reg) \ + : "memory" \ + ); + +/** + * brief: Transpose 2X2 word packaged data. + * fr_i0, fr_i1: src + * fr_o0, fr_o1: dst + */ +#define TRANSPOSE_2W(fr_i0, fr_i1, fr_o0, fr_o1) \ + "punpcklwd "#fr_o0", "#fr_i0", "#fr_i1" \n\t" \ + "punpckhwd "#fr_o1", "#fr_i0", "#fr_i1" \n\t" + +/** + * brief: Transpose 4X4 half word packaged data. + * fr_i0, fr_i1, fr_i2, fr_i3: src & dst + * fr_t0, fr_t1, fr_t2, fr_t3: temporary register + */ +#define TRANSPOSE_4H(fr_i0, fr_i1, fr_i2, fr_i3, \ + fr_t0, fr_t1, fr_t2, fr_t3) \ + "punpcklhw "#fr_t0", "#fr_i0", "#fr_i1" \n\t" \ + "punpckhhw "#fr_t1", "#fr_i0", "#fr_i1" \n\t" \ + "punpcklhw "#fr_t2", "#fr_i2", "#fr_i3" \n\t" \ + "punpckhhw "#fr_t3", "#fr_i2", "#fr_i3" \n\t" \ + "punpcklwd "#fr_i0", "#fr_t0", "#fr_t2" \n\t" \ + "punpckhwd "#fr_i1", "#fr_t0", "#fr_t2" \n\t" \ + "punpcklwd "#fr_i2", "#fr_t1", "#fr_t3" \n\t" \ + "punpckhwd "#fr_i3", "#fr_t1", "#fr_t3" \n\t" + +/** + * brief: Transpose 8x8 byte packaged data. + * fr_i0~i7: src & dst + * fr_t0~t3: temporary register + */ +#define TRANSPOSE_8B(fr_i0, fr_i1, fr_i2, fr_i3, fr_i4, fr_i5, \ + fr_i6, fr_i7, fr_t0, fr_t1, fr_t2, fr_t3) \ + "punpcklbh "#fr_t0", "#fr_i0", "#fr_i1" \n\t" \ + "punpckhbh "#fr_t1", "#fr_i0", "#fr_i1" \n\t" \ + "punpcklbh "#fr_t2", "#fr_i2", "#fr_i3" \n\t" \ + "punpckhbh "#fr_t3", "#fr_i2", "#fr_i3" \n\t" \ + "punpcklbh "#fr_i0", "#fr_i4", "#fr_i5" \n\t" \ + "punpckhbh "#fr_i1", "#fr_i4", "#fr_i5" \n\t" \ + "punpcklbh "#fr_i2", "#fr_i6", "#fr_i7" \n\t" \ + "punpckhbh "#fr_i3", "#fr_i6", "#fr_i7" \n\t" \ + "punpcklhw "#fr_i4", "#fr_t0", "#fr_t2" \n\t" \ + "punpckhhw "#fr_i5", "#fr_t0", "#fr_t2" \n\t" \ + "punpcklhw "#fr_i6", "#fr_t1", "#fr_t3" \n\t" \ + "punpckhhw "#fr_i7", "#fr_t1", "#fr_t3" \n\t" \ + "punpcklhw "#fr_t0", "#fr_i0", "#fr_i2" \n\t" \ + "punpckhhw "#fr_t1", "#fr_i0", "#fr_i2" \n\t" \ + "punpcklhw "#fr_t2", "#fr_i1", "#fr_i3" \n\t" \ + "punpckhhw "#fr_t3", "#fr_i1", "#fr_i3" \n\t" \ + "punpcklwd "#fr_i0", "#fr_i4", "#fr_t0" \n\t" \ + "punpckhwd "#fr_i1", "#fr_i4", "#fr_t0" \n\t" \ + "punpcklwd "#fr_i2", "#fr_i5", "#fr_t1" \n\t" \ + "punpckhwd "#fr_i3", "#fr_i5", "#fr_t1" \n\t" \ + "punpcklwd "#fr_i4", "#fr_i6", "#fr_t2" \n\t" \ + "punpckhwd "#fr_i5", "#fr_i6", "#fr_t2" \n\t" \ + "punpcklwd "#fr_i6", "#fr_i7", "#fr_t3" \n\t" \ + "punpckhwd "#fr_i7", "#fr_i7", "#fr_t3" \n\t" + +/** + * brief: Parallel SRA for 8 byte packaged data. + * fr_i0: src + * fr_i1: SRA number(SRAB number + 8) + * fr_t0, fr_t1: temporary register + * fr_d0: dst + */ +#define PSRAB_MMI(fr_i0, fr_i1, fr_t0, fr_t1, fr_d0) \ + "punpcklbh "#fr_t0", "#fr_t0", "#fr_i0" \n\t" \ + "punpckhbh "#fr_t1", "#fr_t1", "#fr_i0" \n\t" \ + "psrah "#fr_t0", "#fr_t0", "#fr_i1" \n\t" \ + "psrah "#fr_t1", "#fr_t1", "#fr_i1" \n\t" \ + "packsshb "#fr_d0", "#fr_t0", "#fr_t1" \n\t" + +/** + * brief: Parallel SRL for 8 byte packaged data. + * fr_i0: src + * fr_i1: SRL number(SRLB number + 8) + * fr_t0, fr_t1: temporary register + * fr_d0: dst + */ +#define PSRLB_MMI(fr_i0, fr_i1, fr_t0, fr_t1, fr_d0) \ + "punpcklbh "#fr_t0", "#fr_t0", "#fr_i0" \n\t" \ + "punpckhbh "#fr_t1", "#fr_t1", "#fr_i0" \n\t" \ + "psrlh "#fr_t0", "#fr_t0", "#fr_i1" \n\t" \ + "psrlh "#fr_t1", "#fr_t1", "#fr_i1" \n\t" \ + "packsshb "#fr_d0", "#fr_t0", "#fr_t1" \n\t" + +#define PSRAH_4_MMI(fp1, fp2, fp3, fp4, shift) \ + "psrah "#fp1", "#fp1", "#shift" \n\t" \ + "psrah "#fp2", "#fp2", "#shift" \n\t" \ + "psrah "#fp3", "#fp3", "#shift" \n\t" \ + "psrah "#fp4", "#fp4", "#shift" \n\t" + +#define PSRAH_8_MMI(fp1, fp2, fp3, fp4, fp5, fp6, fp7, fp8, shift) \ + PSRAH_4_MMI(fp1, fp2, fp3, fp4, shift) \ + PSRAH_4_MMI(fp5, fp6, fp7, fp8, shift) + +/** + * brief: (((value) + (1 << ((n) - 1))) >> (n)) + * fr_i0: src & dst + * fr_i1: Operand number + * fr_t0, fr_t1: temporary FPR + * gr_t0: temporary GPR + */ +#define ROUND_POWER_OF_TWO_MMI(fr_i0, fr_i1, fr_t0, fr_t1, gr_t0) \ + "li "#gr_t0", 0x01 \n\t" \ + "dmtc1 "#gr_t0", "#fr_t0" \n\t" \ + "punpcklwd "#fr_t0", "#fr_t0", "#fr_t0" \n\t" \ + "psubw "#fr_t1", "#fr_i1", "#fr_t0" \n\t" \ + "psllw "#fr_t1", "#fr_t0", "#fr_t1" \n\t" \ + "paddw "#fr_i0", "#fr_i0", "#fr_t1" \n\t" \ + "psraw "#fr_i0", "#fr_i0", "#fr_i1" \n\t" + +#endif /* AVUTILS_MIPS_MMIUTILS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/motion_vector.h b/arm/raspi/third_party/ffmpeg/libavutil/motion_vector.h new file mode 100644 index 00000000..ec295563 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/motion_vector.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MOTION_VECTOR_H +#define AVUTIL_MOTION_VECTOR_H + +#include + +typedef struct AVMotionVector { + /** + * Where the current macroblock comes from; negative value when it comes + * from the past, positive value when it comes from the future. + * XXX: set exact relative ref frame reference instead of a +/- 1 "direction". + */ + int32_t source; + /** + * Width and height of the block. + */ + uint8_t w, h; + /** + * Absolute source position. Can be outside the frame area. + */ + int16_t src_x, src_y; + /** + * Absolute destination position. Can be outside the frame area. + */ + int16_t dst_x, dst_y; + /** + * Extra flag information. + * Currently unused. + */ + uint64_t flags; + /** + * Motion vector + * src_x = dst_x + motion_x / motion_scale + * src_y = dst_y + motion_y / motion_scale + */ + int32_t motion_x, motion_y; + uint16_t motion_scale; +} AVMotionVector; + +#endif /* AVUTIL_MOTION_VECTOR_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/murmur3.c b/arm/raspi/third_party/ffmpeg/libavutil/murmur3.c new file mode 100644 index 00000000..f2e2a9ea --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/murmur3.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "mem.h" +#include "intreadwrite.h" +#include "murmur3.h" + +typedef struct AVMurMur3 { + uint64_t h1, h2; + uint8_t state[16]; + int state_pos; + uint64_t len; +} AVMurMur3; + +AVMurMur3 *av_murmur3_alloc(void) +{ + return av_mallocz(sizeof(AVMurMur3)); +} + +void av_murmur3_init_seeded(AVMurMur3 *c, uint64_t seed) +{ + memset(c, 0, sizeof(*c)); + c->h1 = c->h2 = seed; +} + +void av_murmur3_init(AVMurMur3 *c) +{ + // arbitrary random number as seed + av_murmur3_init_seeded(c, 0x725acc55daddca55); +} + +static const uint64_t c1 = UINT64_C(0x87c37b91114253d5); +static const uint64_t c2 = UINT64_C(0x4cf5ad432745937f); + +#define ROT(a, b) (((a) << (b)) | ((a) >> (64 - (b)))) + +static uint64_t inline get_k1(const uint8_t *src) +{ + uint64_t k = AV_RL64(src); + k *= c1; + k = ROT(k, 31); + k *= c2; + return k; +} + +static inline uint64_t get_k2(const uint8_t *src) +{ + uint64_t k = AV_RL64(src + 8); + k *= c2; + k = ROT(k, 33); + k *= c1; + return k; +} + +static inline uint64_t update_h1(uint64_t k, uint64_t h1, uint64_t h2) +{ + k ^= h1; + k = ROT(k, 27); + k += h2; + k *= 5; + k += 0x52dce729; + return k; +} + +static inline uint64_t update_h2(uint64_t k, uint64_t h1, uint64_t h2) +{ + k ^= h2; + k = ROT(k, 31); + k += h1; + k *= 5; + k += 0x38495ab5; + return k; +} + +void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, size_t len) +{ + const uint8_t *end; + uint64_t h1 = c->h1, h2 = c->h2; + uint64_t k1, k2; + if (len <= 0) return; + c->len += len; + if (c->state_pos > 0) { + while (c->state_pos < 16) { + c->state[c->state_pos++] = *src++; + if (--len <= 0) return; + } + c->state_pos = 0; + k1 = get_k1(c->state); + k2 = get_k2(c->state); + h1 = update_h1(k1, h1, h2); + h2 = update_h2(k2, h1, h2); + } + + end = src + (len & ~15); + while (src < end) { + // These could be done sequentially instead + // of interleaved, but like this is over 10% faster + k1 = get_k1(src); + k2 = get_k2(src); + h1 = update_h1(k1, h1, h2); + h2 = update_h2(k2, h1, h2); + src += 16; + } + c->h1 = h1; + c->h2 = h2; + + len &= 15; + if (len > 0) { + memcpy(c->state, src, len); + c->state_pos = len; + } +} + +static inline uint64_t fmix(uint64_t k) +{ + k ^= k >> 33; + k *= UINT64_C(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= UINT64_C(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + return k; +} + +void av_murmur3_final(AVMurMur3 *c, uint8_t dst[16]) +{ + uint64_t h1 = c->h1, h2 = c->h2; + memset(c->state + c->state_pos, 0, sizeof(c->state) - c->state_pos); + h1 ^= get_k1(c->state) ^ c->len; + h2 ^= get_k2(c->state) ^ c->len; + h1 += h2; + h2 += h1; + h1 = fmix(h1); + h2 = fmix(h2); + h1 += h2; + h2 += h1; + AV_WL64(dst, h1); + AV_WL64(dst + 8, h2); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/murmur3.h b/arm/raspi/third_party/ffmpeg/libavutil/murmur3.h new file mode 100644 index 00000000..d90bc2fc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/murmur3.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_murmur3 + * Public header for MurmurHash3 hash function implementation. + */ + +#ifndef AVUTIL_MURMUR3_H +#define AVUTIL_MURMUR3_H + +#include +#include + +/** + * @defgroup lavu_murmur3 Murmur3 + * @ingroup lavu_hash + * MurmurHash3 hash function implementation. + * + * MurmurHash3 is a non-cryptographic hash function, of which three + * incompatible versions were created by its inventor Austin Appleby: + * + * - 32-bit output + * - 128-bit output for 32-bit platforms + * - 128-bit output for 64-bit platforms + * + * FFmpeg only implements the last variant: 128-bit output designed for 64-bit + * platforms. Even though the hash function was designed for 64-bit platforms, + * the function in reality works on 32-bit systems too, only with reduced + * performance. + * + * @anchor lavu_murmur3_seedinfo + * By design, MurmurHash3 requires a seed to operate. In response to this, + * libavutil provides two functions for hash initiation, one that requires a + * seed (av_murmur3_init_seeded()) and one that uses a fixed arbitrary integer + * as the seed, and therefore does not (av_murmur3_init()). + * + * To make hashes comparable, you should provide the same seed for all calls to + * this hash function -- if you are supplying one yourself, that is. + * + * @{ + */ + +/** + * Allocate an AVMurMur3 hash context. + * + * @return Uninitialized hash context or `NULL` in case of error + */ +struct AVMurMur3 *av_murmur3_alloc(void); + +/** + * Initialize or reinitialize an AVMurMur3 hash context with a seed. + * + * @param[out] c Hash context + * @param[in] seed Random seed + * + * @see av_murmur3_init() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init_seeded(struct AVMurMur3 *c, uint64_t seed); + +/** + * Initialize or reinitialize an AVMurMur3 hash context. + * + * Equivalent to av_murmur3_init_seeded() with a built-in seed. + * + * @param[out] c Hash context + * + * @see av_murmur3_init_seeded() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init(struct AVMurMur3 *c); + +/** + * Update hash context with new data. + * + * @param[out] c Hash context + * @param[in] src Input data to update hash with + * @param[in] len Number of bytes to read from `src` + */ +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, size_t len); + +/** + * Finish hashing and output digest value. + * + * @param[in,out] c Hash context + * @param[out] dst Buffer where output digest value is stored + */ +void av_murmur3_final(struct AVMurMur3 *c, uint8_t dst[16]); + +/** + * @} + */ + +#endif /* AVUTIL_MURMUR3_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/objc.h b/arm/raspi/third_party/ffmpeg/libavutil/objc.h new file mode 100644 index 00000000..0db993f7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/objc.h @@ -0,0 +1,32 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_OBJC_H +#define AVUTIL_OBJC_H + +#include + +static inline void ff_objc_release(NSObject **obj) +{ + if (*obj) { + [*obj release]; + *obj = nil; + } +} + +#endif /* AVUTIL_OBJC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/opt.c b/arm/raspi/third_party/ffmpeg/libavutil/opt.c new file mode 100644 index 00000000..09087517 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/opt.c @@ -0,0 +1,2241 @@ +/* + * AVOptions + * Copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AVOptions + * @author Michael Niedermayer + */ + +#include "avutil.h" +#include "avassert.h" +#include "avstring.h" +#include "channel_layout.h" +#include "common.h" +#include "dict.h" +#include "eval.h" +#include "log.h" +#include "parseutils.h" +#include "pixdesc.h" +#include "mathematics.h" +#include "opt.h" +#include "samplefmt.h" +#include "bprint.h" +#include "version.h" + +#include + +const AVOption *av_opt_next(const void *obj, const AVOption *last) +{ + const AVClass *class; + if (!obj) + return NULL; + class = *(const AVClass**)obj; + if (!last && class && class->option && class->option[0].name) + return class->option; + if (last && last[1].name) + return ++last; + return NULL; +} + +static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum) +{ + switch (o->type) { + case AV_OPT_TYPE_FLAGS: + *intnum = *(unsigned int*)dst; + return 0; + case AV_OPT_TYPE_PIXEL_FMT: + *intnum = *(enum AVPixelFormat *)dst; + return 0; + case AV_OPT_TYPE_SAMPLE_FMT: + *intnum = *(enum AVSampleFormat *)dst; + return 0; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + *intnum = *(int *)dst; + return 0; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + *intnum = *(int64_t *)dst; + return 0; + case AV_OPT_TYPE_FLOAT: + *num = *(float *)dst; + return 0; + case AV_OPT_TYPE_DOUBLE: + *num = *(double *)dst; + return 0; + case AV_OPT_TYPE_RATIONAL: + *intnum = ((AVRational *)dst)->num; + *den = ((AVRational *)dst)->den; + return 0; + case AV_OPT_TYPE_CONST: + *num = o->default_val.dbl; + return 0; + } + return AVERROR(EINVAL); +} + +static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) +{ + if (o->type != AV_OPT_TYPE_FLAGS && + (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { + num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); + av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", + num, o->name, o->min, o->max); + return AVERROR(ERANGE); + } + if (o->type == AV_OPT_TYPE_FLAGS) { + double d = num*intnum/den; + if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { + av_log(obj, AV_LOG_ERROR, + "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", + num*intnum/den, o->name); + return AVERROR(ERANGE); + } + } + + switch (o->type) { + case AV_OPT_TYPE_PIXEL_FMT: + *(enum AVPixelFormat *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_SAMPLE_FMT: + *(enum AVSampleFormat *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + *(int *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_INT64:{ + double d = num / den; + if (intnum == 1 && d == (double)INT64_MAX) { + *(int64_t *)dst = INT64_MAX; + } else + *(int64_t *)dst = llrint(d) * intnum; + break;} + case AV_OPT_TYPE_UINT64:{ + double d = num / den; + // We must special case uint64_t here as llrint() does not support values + // outside the int64_t range and there is no portable function which does + // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double + // while INT64_MAX is not + if (intnum == 1 && d == (double)UINT64_MAX) { + *(uint64_t *)dst = UINT64_MAX; + } else if (d > INT64_MAX + 1ULL) { + *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum; + } else { + *(uint64_t *)dst = llrint(d) * intnum; + } + break;} + case AV_OPT_TYPE_FLOAT: + *(float *)dst = num * intnum / den; + break; + case AV_OPT_TYPE_DOUBLE: + *(double *)dst = num * intnum / den; + break; + case AV_OPT_TYPE_RATIONAL: + case AV_OPT_TYPE_VIDEO_RATE: + if ((int) num == num) + *(AVRational *)dst = (AVRational) { num *intnum, den }; + else + *(AVRational *)dst = av_d2q(num * intnum / den, 1 << 24); + break; + default: + return AVERROR(EINVAL); + } + return 0; +} + +static int hexchar2int(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + int *lendst = (int *)(dst + 1); + uint8_t *bin, *ptr; + int len; + + av_freep(dst); + *lendst = 0; + + if (!val || !(len = strlen(val))) + return 0; + + if (len & 1) + return AVERROR(EINVAL); + len /= 2; + + ptr = bin = av_malloc(len); + if (!ptr) + return AVERROR(ENOMEM); + while (*val) { + int a = hexchar2int(*val++); + int b = hexchar2int(*val++); + if (a < 0 || b < 0) { + av_free(bin); + return AVERROR(EINVAL); + } + *ptr++ = (a << 4) | b; + } + *dst = bin; + *lendst = len; + + return 0; +} + +static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + av_freep(dst); + *dst = av_strdup(val); + return *dst ? 0 : AVERROR(ENOMEM); +} + +#define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \ + opt->type == AV_OPT_TYPE_UINT64 || \ + opt->type == AV_OPT_TYPE_CONST || \ + opt->type == AV_OPT_TYPE_FLAGS || \ + opt->type == AV_OPT_TYPE_INT) \ + ? opt->default_val.i64 \ + : opt->default_val.dbl) + +static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) +{ + int ret = 0; + + if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) { + int num, den; + char c; + if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { + if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) + return ret; + ret = 0; + } + } + + for (;;) { + int i = 0; + char buf[256]; + int cmd = 0; + double d; + int64_t intnum = 1; + + if (o->type == AV_OPT_TYPE_FLAGS) { + if (*val == '+' || *val == '-') + cmd = *(val++); + for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) + buf[i] = val[i]; + buf[i] = 0; + } + + { + int res; + int ci = 0; + double const_values[64]; + const char * const_names[64]; + int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0; + const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags); + if (o_named && o_named->type == AV_OPT_TYPE_CONST) { + d = DEFAULT_NUMVAL(o_named); + if (o_named->flags & AV_OPT_FLAG_DEPRECATED) + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", + o_named->name, o_named->help); + } else { + if (o->unit) { + for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { + if (o_named->type == AV_OPT_TYPE_CONST && + o_named->unit && + !strcmp(o_named->unit, o->unit)) { + if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { + av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); + return AVERROR_PATCHWELCOME; + } + const_names [ci ] = o_named->name; + const_values[ci++] = DEFAULT_NUMVAL(o_named); + } + } + } + const_names [ci ] = "default"; + const_values[ci++] = DEFAULT_NUMVAL(o); + const_names [ci ] = "max"; + const_values[ci++] = o->max; + const_names [ci ] = "min"; + const_values[ci++] = o->min; + const_names [ci ] = "none"; + const_values[ci++] = 0; + const_names [ci ] = "all"; + const_values[ci++] = ~0; + const_names [ci] = NULL; + const_values[ci] = 0; + + res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, + const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); + if (res < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); + return res; + } + } + } + if (o->type == AV_OPT_TYPE_FLAGS) { + read_number(o, dst, NULL, NULL, &intnum); + if (cmd == '+') + d = intnum | (int64_t)d; + else if (cmd == '-') + d = intnum &~(int64_t)d; + } + + if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) + return ret; + val += i; + if (!i || !*val) + return 0; + } +} + +static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) +{ + int ret; + + if (!val || !strcmp(val, "none")) { + dst[0] = + dst[1] = 0; + return 0; + } + ret = av_parse_video_size(dst, dst + 1, val); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); + return ret; +} + +static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) +{ + int ret = av_parse_video_rate(dst, val); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); + return ret; +} + +static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + int ret; + + if (!val) { + return 0; + } else { + ret = av_parse_color(dst, val, -1, obj); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); + return ret; + } + return 0; +} + +static const char *get_bool_name(int val) +{ + if (val < 0) + return "auto"; + return val ? "true" : "false"; +} + +static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst) +{ + int n; + + if (!val) + return 0; + + if (!strcmp(val, "auto")) { + n = -1; + } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) { + n = 1; + } else if (av_match_name(val, "false,n,no,disable,disabled,off")) { + n = 0; + } else { + char *end = NULL; + n = strtol(val, &end, 10); + if (val + strlen(val) != end) + goto fail; + } + + if (n < o->min || n > o->max) + goto fail; + + *dst = n; + return 0; + +fail: + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val); + return AVERROR(EINVAL); +} + +static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, + int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) +{ + int fmt, min, max; + + if (!val || !strcmp(val, "none")) { + fmt = -1; + } else { + fmt = get_fmt(val); + if (fmt == -1) { + char *tail; + fmt = strtol(val, &tail, 0); + if (*tail || (unsigned)fmt >= fmt_nb) { + av_log(obj, AV_LOG_ERROR, + "Unable to parse option value \"%s\" as %s\n", val, desc); + return AVERROR(EINVAL); + } + } + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, fmt_nb-1); + + // hack for compatibility with old ffmpeg + if(min == 0 && max == 0) { + min = -1; + max = fmt_nb-1; + } + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, o->name, desc, min, max); + return AVERROR(ERANGE); + } + + *(int *)dst = fmt; + return 0; +} + +static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); +} + +static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); +} + +static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + AVDictionary *options = NULL; + + if (val) { + int ret = av_dict_parse_string(&options, val, "=", ":", 0); + if (ret < 0) { + av_dict_free(&options); + return ret; + } + } + + av_dict_free((AVDictionary **)dst); + *dst = (uint8_t *)options; + + return 0; +} + +static int set_string_channel_layout(void *obj, const AVOption *o, + const char *val, void *dst) +{ + AVChannelLayout *channel_layout = dst; + av_channel_layout_uninit(channel_layout); + if (!val) + return 0; + return av_channel_layout_from_string(channel_layout, val); +} + +int av_opt_set(void *obj, const char *name, const char *val, int search_flags) +{ + int ret = 0; + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; +FF_DISABLE_DEPRECATION_WARNINGS + if (!val && (o->type != AV_OPT_TYPE_STRING && + o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT && + o->type != AV_OPT_TYPE_IMAGE_SIZE && + o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && +#if FF_API_OLD_CHANNEL_LAYOUT + o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && +#endif + o->type != AV_OPT_TYPE_BOOL)) + return AVERROR(EINVAL); +FF_ENABLE_DEPRECATION_WARNINGS + + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + if (o->flags & AV_OPT_FLAG_DEPRECATED) + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); + + dst = ((uint8_t *)target_obj) + o->offset; + switch (o->type) { + case AV_OPT_TYPE_BOOL: + return set_string_bool(obj, o, val, dst); + case AV_OPT_TYPE_STRING: + return set_string(obj, o, val, dst); + case AV_OPT_TYPE_BINARY: + return set_string_binary(obj, o, val, dst); + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_RATIONAL: + return set_string_number(obj, target_obj, o, val, dst); + case AV_OPT_TYPE_IMAGE_SIZE: + return set_string_image_size(obj, o, val, dst); + case AV_OPT_TYPE_VIDEO_RATE: { + AVRational tmp; + ret = set_string_video_rate(obj, o, val, &tmp); + if (ret < 0) + return ret; + return write_number(obj, o, dst, 1, tmp.den, tmp.num); + } + case AV_OPT_TYPE_PIXEL_FMT: + return set_string_pixel_fmt(obj, o, val, dst); + case AV_OPT_TYPE_SAMPLE_FMT: + return set_string_sample_fmt(obj, o, val, dst); + case AV_OPT_TYPE_DURATION: + { + int64_t usecs = 0; + if (val) { + if ((ret = av_parse_time(&usecs, val, 1)) < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); + return ret; + } + } + if (usecs < o->min || usecs > o->max) { + av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", + usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0); + return AVERROR(ERANGE); + } + *(int64_t *)dst = usecs; + return 0; + } + case AV_OPT_TYPE_COLOR: + return set_string_color(obj, o, val, dst); +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: + if (!val || !strcmp(val, "none")) { + *(int64_t *)dst = 0; + } else { + int64_t cl = av_get_channel_layout(val); + if (!cl) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + *(int64_t *)dst = cl; + return ret; + } + break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_CHLAYOUT: + ret = set_string_channel_layout(obj, o, val, dst); + if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + return ret; + case AV_OPT_TYPE_DICT: + return set_string_dict(obj, o, val, dst); + } + + av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); + return AVERROR(EINVAL); +} + +#define OPT_EVAL_NUMBER(name, opttype, vartype) \ +int av_opt_eval_ ## name(void *obj, const AVOption *o, \ + const char *val, vartype *name ## _out) \ +{ \ + if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \ + return AVERROR(EINVAL); \ + return set_string_number(obj, obj, o, val, name ## _out); \ +} + +OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int) +OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int) +OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t) +OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float) +OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double) +OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational) + +static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, + int search_flags) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + dst = ((uint8_t *)target_obj) + o->offset; + return write_number(obj, o, dst, num, den, intnum); +} + +int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) +{ + return set_number(obj, name, 1, 1, val, search_flags); +} + +int av_opt_set_double(void *obj, const char *name, double val, int search_flags) +{ + return set_number(obj, name, val, 1, 1, search_flags); +} + +int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) +{ + return set_number(obj, name, val.num, val.den, 1, search_flags); +} + +int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + uint8_t *ptr; + uint8_t **dst; + int *lendst; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + ptr = len ? av_malloc(len) : NULL; + if (len && !ptr) + return AVERROR(ENOMEM); + + dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset); + lendst = (int *)(dst + 1); + + av_free(*dst); + *dst = ptr; + *lendst = len; + if (len) + memcpy(ptr, val, len); + + return 0; +} + +int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not an image size.\n", o->name); + return AVERROR(EINVAL); + } + if (w<0 || h<0) { + av_log(obj, AV_LOG_ERROR, + "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name); + return AVERROR(EINVAL); + } + *(int *)(((uint8_t *)target_obj) + o->offset) = w; + *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h; + return 0; +} + +int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_VIDEO_RATE) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a video rate.\n", o->name); + return AVERROR(EINVAL); + } + if (val.num <= 0 || val.den <= 0) + return AVERROR(EINVAL); + return set_number(obj, name, val.num, val.den, 1, search_flags); +} + +static int set_format(void *obj, const char *name, int fmt, int search_flags, + enum AVOptionType type, const char *desc, int nb_fmts) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, + search_flags, &target_obj); + int min, max; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != type) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a %s format", name, desc); + return AVERROR(EINVAL); + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, nb_fmts-1); + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, name, desc, min, max); + return AVERROR(ERANGE); + } + *(int *)(((uint8_t *)target_obj) + o->offset) = fmt; + return 0; +} + +int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) +{ + return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB); +} + +int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) +{ + return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); +} + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS +int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a channel layout.\n", o->name); + return AVERROR(EINVAL); + } + *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; + return 0; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, + int search_flags) +{ + void *target_obj; + AVDictionary **dst; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset); + av_dict_free(dst); + av_dict_copy(dst, val, 0); + + return 0; +} + +int av_opt_set_chlayout(void *obj, const char *name, + const AVChannelLayout *channel_layout, + int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + AVChannelLayout *dst; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + dst = (AVChannelLayout*)((uint8_t*)target_obj + o->offset); + + return av_channel_layout_copy(dst, channel_layout); +} + +static void format_duration(char *buf, size_t size, int64_t d) +{ + char *e; + + av_assert0(size >= 25); + if (d < 0 && d != INT64_MIN) { + *(buf++) = '-'; + size--; + d = -d; + } + if (d == INT64_MAX) + snprintf(buf, size, "INT64_MAX"); + else if (d == INT64_MIN) + snprintf(buf, size, "INT64_MIN"); + else if (d > (int64_t)3600*1000000) + snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000, + (int)((d / 60000000) % 60), + (int)((d / 1000000) % 60), + (int)(d % 1000000)); + else if (d > 60*1000000) + snprintf(buf, size, "%d:%02d.%06d", + (int)(d / 60000000), + (int)((d / 1000000) % 60), + (int)(d % 1000000)); + else + snprintf(buf, size, "%d.%06d", + (int)(d / 1000000), + (int)(d % 1000000)); + e = buf + strlen(buf); + while (e > buf && e[-1] == '0') + *(--e) = 0; + if (e > buf && e[-1] == '.') + *(--e) = 0; +} + +int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + uint8_t *bin, buf[128]; + int len, i, ret; + int64_t i64; + + if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) + return AVERROR_OPTION_NOT_FOUND; + + if (o->flags & AV_OPT_FLAG_DEPRECATED) + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); + + dst = (uint8_t *)target_obj + o->offset; + + buf[0] = 0; + switch (o->type) { + case AV_OPT_TYPE_BOOL: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid")); + break; + case AV_OPT_TYPE_FLAGS: + ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst); + break; + case AV_OPT_TYPE_INT: + ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst); + break; + case AV_OPT_TYPE_INT64: + ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst); + break; + case AV_OPT_TYPE_UINT64: + ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst); + break; + case AV_OPT_TYPE_FLOAT: + ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst); + break; + case AV_OPT_TYPE_DOUBLE: + ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst); + break; + case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_RATIONAL: + ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den); + break; + case AV_OPT_TYPE_CONST: + ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl); + break; + case AV_OPT_TYPE_STRING: + if (*(uint8_t **)dst) { + *out_val = av_strdup(*(uint8_t **)dst); + } else if (search_flags & AV_OPT_ALLOW_NULL) { + *out_val = NULL; + return 0; + } else { + *out_val = av_strdup(""); + } + return *out_val ? 0 : AVERROR(ENOMEM); + case AV_OPT_TYPE_BINARY: + if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { + *out_val = NULL; + return 0; + } + len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *)); + if ((uint64_t)len * 2 + 1 > INT_MAX) + return AVERROR(EINVAL); + if (!(*out_val = av_malloc(len * 2 + 1))) + return AVERROR(ENOMEM); + if (!len) { + *out_val[0] = '\0'; + return 0; + } + bin = *(uint8_t **)dst; + for (i = 0; i < len; i++) + snprintf(*out_val + i * 2, 3, "%02X", bin[i]); + return 0; + case AV_OPT_TYPE_IMAGE_SIZE: + ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); + break; + case AV_OPT_TYPE_PIXEL_FMT: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); + break; + case AV_OPT_TYPE_DURATION: + i64 = *(int64_t *)dst; + format_duration(buf, sizeof(buf), i64); + ret = strlen(buf); // no overflow possible, checked by an assert + break; + case AV_OPT_TYPE_COLOR: + ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", + (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], + (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); + break; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: + + i64 = *(int64_t *)dst; + ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); + break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_CHLAYOUT: + ret = av_channel_layout_describe(dst, buf, sizeof(buf)); + break; + case AV_OPT_TYPE_DICT: + if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { + *out_val = NULL; + return 0; + } + return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':'); + default: + return AVERROR(EINVAL); + } + + if (ret >= sizeof(buf)) + return AVERROR(EINVAL); + *out_val = av_strdup(buf); + return *out_val ? 0 : AVERROR(ENOMEM); +} + +static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum, + int search_flags) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + goto error; + + dst = ((uint8_t *)target_obj) + o->offset; + + if (o_out) *o_out= o; + + return read_number(o, dst, num, den, intnum); + +error: + *den = + *intnum = 0; + return -1; +} + +int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + if (num == den) + *out_val = intnum; + else + *out_val = num * intnum / den; + return 0; +} + +int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + *out_val = num * intnum / den; + return 0; +} + +int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + + if (num == 1.0 && (int)intnum == intnum) + *out_val = (AVRational){intnum, den}; + else + *out_val = av_d2q(num*intnum/den, 1<<24); + return 0; +} + +int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not an image size.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + if (w_out) *w_out = *(int *)dst; + if (h_out) *h_out = *((int *)dst+1); + return 0; +} + +int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + + if (num == 1.0 && (int)intnum == intnum) + *out_val = (AVRational) { intnum, den }; + else + *out_val = av_d2q(num * intnum / den, 1 << 24); + return 0; +} + +static int get_format(void *obj, const char *name, int search_flags, int *out_fmt, + enum AVOptionType type, const char *desc) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != type) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a %s format.\n", desc, name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *out_fmt = *(int *)dst; + return 0; +} + +int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) +{ + return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel"); +} + +int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) +{ + return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); +} + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a channel layout.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *cl = *(int64_t *)dst; + return 0; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHLAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a channel layout.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + return av_channel_layout_copy(cl, dst); +} + +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) +{ + void *target_obj; + AVDictionary *src; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_DICT) + return AVERROR(EINVAL); + + src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset); + av_dict_copy(out_val, src, 0); + + return 0; +} + +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) +{ + const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); + const AVOption *flag = av_opt_find(obj, flag_name, + field ? field->unit : NULL, 0, 0); + int64_t res; + + if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || + av_opt_get_int(obj, field_name, 0, &res) < 0) + return 0; + return res & flag->default_val.i64; +} + +static void log_int_value(void *av_log_obj, int level, int64_t i) +{ + if (i == INT_MAX) { + av_log(av_log_obj, level, "INT_MAX"); + } else if (i == INT_MIN) { + av_log(av_log_obj, level, "INT_MIN"); + } else if (i == UINT32_MAX) { + av_log(av_log_obj, level, "UINT32_MAX"); + } else if (i == INT64_MAX) { + av_log(av_log_obj, level, "I64_MAX"); + } else if (i == INT64_MIN) { + av_log(av_log_obj, level, "I64_MIN"); + } else { + av_log(av_log_obj, level, "%"PRId64, i); + } +} + +static void log_value(void *av_log_obj, int level, double d) +{ + if (d == INT_MAX) { + av_log(av_log_obj, level, "INT_MAX"); + } else if (d == INT_MIN) { + av_log(av_log_obj, level, "INT_MIN"); + } else if (d == UINT32_MAX) { + av_log(av_log_obj, level, "UINT32_MAX"); + } else if (d == (double)INT64_MAX) { + av_log(av_log_obj, level, "I64_MAX"); + } else if (d == INT64_MIN) { + av_log(av_log_obj, level, "I64_MIN"); + } else if (d == FLT_MAX) { + av_log(av_log_obj, level, "FLT_MAX"); + } else if (d == FLT_MIN) { + av_log(av_log_obj, level, "FLT_MIN"); + } else if (d == -FLT_MAX) { + av_log(av_log_obj, level, "-FLT_MAX"); + } else if (d == -FLT_MIN) { + av_log(av_log_obj, level, "-FLT_MIN"); + } else if (d == DBL_MAX) { + av_log(av_log_obj, level, "DBL_MAX"); + } else if (d == DBL_MIN) { + av_log(av_log_obj, level, "DBL_MIN"); + } else if (d == -DBL_MAX) { + av_log(av_log_obj, level, "-DBL_MAX"); + } else if (d == -DBL_MIN) { + av_log(av_log_obj, level, "-DBL_MIN"); + } else { + av_log(av_log_obj, level, "%g", d); + } +} + +static const char *get_opt_const_name(void *obj, const char *unit, int64_t value) +{ + const AVOption *opt = NULL; + + if (!unit) + return NULL; + while ((opt = av_opt_next(obj, opt))) + if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && + opt->default_val.i64 == value) + return opt->name; + return NULL; +} + +static char *get_opt_flags_string(void *obj, const char *unit, int64_t value) +{ + const AVOption *opt = NULL; + char flags[512]; + + flags[0] = 0; + if (!unit) + return NULL; + while ((opt = av_opt_next(obj, opt))) { + if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && + opt->default_val.i64 & value) { + if (flags[0]) + av_strlcatf(flags, sizeof(flags), "+"); + av_strlcatf(flags, sizeof(flags), "%s", opt->name); + } + } + if (flags[0]) + return av_strdup(flags); + return NULL; +} + +static void opt_list(void *obj, void *av_log_obj, const char *unit, + int req_flags, int rej_flags, enum AVOptionType parent_type) +{ + const AVOption *opt = NULL; + AVOptionRanges *r; + int i; + + while ((opt = av_opt_next(obj, opt))) { + if (!(opt->flags & req_flags) || (opt->flags & rej_flags)) + continue; + + /* Don't print CONST's on level one. + * Don't print anything but CONST's on level two. + * Only print items from the requested unit. + */ + if (!unit && opt->type == AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type != AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST) + av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); + else + av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", + (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-", + opt->name); + + switch (opt->type) { + case AV_OPT_TYPE_FLAGS: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_INT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_INT64: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_UINT64: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_DOUBLE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_FLOAT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_STRING: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_RATIONAL: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_BINARY: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_DICT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_IMAGE_SIZE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_VIDEO_RATE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_PIXEL_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_DURATION: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_COLOR: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_CHLAYOUT: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_BOOL: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_CONST: + if (parent_type == AV_OPT_TYPE_INT) + av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64); + else + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + default: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + } + av_log(av_log_obj, AV_LOG_INFO, "%c%c%c%c%c%c%c%c%c%c%c", + (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.', + (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.', + (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? 'F' : '.', + (opt->flags & AV_OPT_FLAG_VIDEO_PARAM) ? 'V' : '.', + (opt->flags & AV_OPT_FLAG_AUDIO_PARAM) ? 'A' : '.', + (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.', + (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.', + (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.', + (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.', + (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.', + (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.'); + + if (opt->help) + av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); + + if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) { + switch (opt->type) { + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_RATIONAL: + for (i = 0; i < r->nb_ranges; i++) { + av_log(av_log_obj, AV_LOG_INFO, " (from "); + log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min); + av_log(av_log_obj, AV_LOG_INFO, " to "); + log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max); + av_log(av_log_obj, AV_LOG_INFO, ")"); + } + break; + } + av_opt_freep_ranges(&r); + } + + if (opt->type != AV_OPT_TYPE_CONST && + opt->type != AV_OPT_TYPE_BINARY && + !((opt->type == AV_OPT_TYPE_COLOR || + opt->type == AV_OPT_TYPE_IMAGE_SIZE || + opt->type == AV_OPT_TYPE_STRING || + opt->type == AV_OPT_TYPE_DICT || + opt->type == AV_OPT_TYPE_CHLAYOUT || + opt->type == AV_OPT_TYPE_VIDEO_RATE) && + !opt->default_val.str)) { + av_log(av_log_obj, AV_LOG_INFO, " (default "); + switch (opt->type) { + case AV_OPT_TYPE_BOOL: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid")); + break; + case AV_OPT_TYPE_FLAGS: { + char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64); + if (def_flags) { + av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags); + av_freep(&def_flags); + } else { + av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); + } + break; + } + case AV_OPT_TYPE_DURATION: { + char buf[25]; + format_duration(buf, sizeof(buf), opt->default_val.i64); + av_log(av_log_obj, AV_LOG_INFO, "%s", buf); + break; + } + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_INT64: { + const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64); + if (def_const) + av_log(av_log_obj, AV_LOG_INFO, "%s", def_const); + else + log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); + break; + } + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: + log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); + break; + case AV_OPT_TYPE_RATIONAL: { + AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); + av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } + break; + case AV_OPT_TYPE_PIXEL_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_IMAGE_SIZE: + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_DICT: + case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_CHLAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); + break; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); + break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } + av_log(av_log_obj, AV_LOG_INFO, ")"); + } + + av_log(av_log_obj, AV_LOG_INFO, "\n"); + if (opt->unit && opt->type != AV_OPT_TYPE_CONST) + opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type); + } +} + +int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) +{ + if (!obj) + return -1; + + av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name); + + opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1); + + return 0; +} + +void av_opt_set_defaults(void *s) +{ + av_opt_set_defaults2(s, 0, 0); +} + +void av_opt_set_defaults2(void *s, int mask, int flags) +{ + const AVOption *opt = NULL; + while ((opt = av_opt_next(s, opt))) { + void *dst = ((uint8_t*)s) + opt->offset; + + if ((opt->flags & mask) != flags) + continue; + + if (opt->flags & AV_OPT_FLAG_READONLY) + continue; + + switch (opt->type) { + case AV_OPT_TYPE_CONST: + /* Nothing to be done here */ + break; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + write_number(s, opt, dst, 1, 1, opt->default_val.i64); + break; + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: { + double val; + val = opt->default_val.dbl; + write_number(s, opt, dst, val, 1, 1); + } + break; + case AV_OPT_TYPE_RATIONAL: { + AVRational val; + val = av_d2q(opt->default_val.dbl, INT_MAX); + write_number(s, opt, dst, 1, val.den, val.num); + } + break; + case AV_OPT_TYPE_COLOR: + set_string_color(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_STRING: + set_string(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_IMAGE_SIZE: + set_string_image_size(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_VIDEO_RATE: + set_string_video_rate(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_BINARY: + set_string_binary(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_CHLAYOUT: + set_string_channel_layout(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_DICT: + set_string_dict(s, opt, opt->default_val.str, dst); + break; + default: + av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", + opt->type, opt->name); + } + } +} + +/** + * Store the value in the field in ctx that is named like key. + * ctx must be an AVClass context, storing is done using AVOptions. + * + * @param buf the string to parse, buf will be updated to point at the + * separator just after the parsed key/value pair + * @param key_val_sep a 0-terminated list of characters used to + * separate key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @return 0 if the key/value pair has been successfully parsed and + * set, or a negative value corresponding to an AVERROR code in case + * of error: + * AVERROR(EINVAL) if the key/value pair cannot be parsed, + * the error code issued by av_opt_set() if the key/value pair + * cannot be set + */ +static int parse_key_value_pair(void *ctx, const char **buf, + const char *key_val_sep, const char *pairs_sep) +{ + char *key = av_get_token(buf, key_val_sep); + char *val; + int ret; + + if (!key) + return AVERROR(ENOMEM); + + if (*key && strspn(*buf, key_val_sep)) { + (*buf)++; + val = av_get_token(buf, pairs_sep); + if (!val) { + av_freep(&key); + return AVERROR(ENOMEM); + } + } else { + av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); + av_free(key); + return AVERROR(EINVAL); + } + + av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); + + ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); + + av_free(key); + av_free(val); + return ret; +} + +int av_set_options_string(void *ctx, const char *opts, + const char *key_val_sep, const char *pairs_sep) +{ + int ret, count = 0; + + if (!opts) + return 0; + + while (*opts) { + if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) + return ret; + count++; + + if (*opts) + opts++; + } + + return count; +} + +#define WHITESPACES " \n\t\r" + +static int is_key_char(char c) +{ + return (unsigned)((c | 32) - 'a') < 26 || + (unsigned)(c - '0') < 10 || + c == '-' || c == '_' || c == '/' || c == '.'; +} + +/** + * Read a key from a string. + * + * The key consists of is_key_char characters and must be terminated by a + * character from the delim string; spaces are ignored. + * + * @return 0 for success (even with ellipsis), <0 for failure + */ +static int get_key(const char **ropts, const char *delim, char **rkey) +{ + const char *opts = *ropts; + const char *key_start, *key_end; + + key_start = opts += strspn(opts, WHITESPACES); + while (is_key_char(*opts)) + opts++; + key_end = opts; + opts += strspn(opts, WHITESPACES); + if (!*opts || !strchr(delim, *opts)) + return AVERROR(EINVAL); + opts++; + if (!(*rkey = av_malloc(key_end - key_start + 1))) + return AVERROR(ENOMEM); + memcpy(*rkey, key_start, key_end - key_start); + (*rkey)[key_end - key_start] = 0; + *ropts = opts; + return 0; +} + +int av_opt_get_key_value(const char **ropts, + const char *key_val_sep, const char *pairs_sep, + unsigned flags, + char **rkey, char **rval) +{ + int ret; + char *key = NULL, *val; + const char *opts = *ropts; + + if ((ret = get_key(&opts, key_val_sep, &key)) < 0 && + !(flags & AV_OPT_FLAG_IMPLICIT_KEY)) + return AVERROR(EINVAL); + if (!(val = av_get_token(&opts, pairs_sep))) { + av_free(key); + return AVERROR(ENOMEM); + } + *ropts = opts; + *rkey = key; + *rval = val; + return 0; +} + +int av_opt_set_from_string(void *ctx, const char *opts, + const char *const *shorthand, + const char *key_val_sep, const char *pairs_sep) +{ + int ret, count = 0; + const char *dummy_shorthand = NULL; + char *av_uninit(parsed_key), *av_uninit(value); + const char *key; + + if (!opts) + return 0; + if (!shorthand) + shorthand = &dummy_shorthand; + + while (*opts) { + ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep, + *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, + &parsed_key, &value); + if (ret < 0) { + if (ret == AVERROR(EINVAL)) + av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts); + else + av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts, + av_err2str(ret)); + return ret; + } + if (*opts) + opts++; + if (parsed_key) { + key = parsed_key; + while (*shorthand) /* discard all remaining shorthand */ + shorthand++; + } else { + key = *(shorthand++); + } + + av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); + if ((ret = av_opt_set(ctx, key, value, 0)) < 0) { + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); + av_free(value); + av_free(parsed_key); + return ret; + } + + av_free(value); + av_free(parsed_key); + count++; + } + return count; +} + +void av_opt_free(void *obj) +{ + const AVOption *o = NULL; + while ((o = av_opt_next(obj, o))) { + switch (o->type) { + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_BINARY: + av_freep((uint8_t *)obj + o->offset); + break; + + case AV_OPT_TYPE_DICT: + av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset)); + break; + + case AV_OPT_TYPE_CHLAYOUT: + av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset)); + break; + + default: + break; + } + } +} + +int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) +{ + const AVDictionaryEntry *t = NULL; + AVDictionary *tmp = NULL; + int ret; + + if (!options) + return 0; + + while ((t = av_dict_iterate(*options, t))) { + ret = av_opt_set(obj, t->key, t->value, search_flags); + if (ret == AVERROR_OPTION_NOT_FOUND) + ret = av_dict_set(&tmp, t->key, t->value, AV_DICT_MULTIKEY); + if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); + av_dict_free(&tmp); + return ret; + } + } + av_dict_free(options); + *options = tmp; + return 0; +} + +int av_opt_set_dict(void *obj, AVDictionary **options) +{ + return av_opt_set_dict2(obj, options, 0); +} + +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags) +{ + return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); +} + +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj) +{ + const AVClass *c; + const AVOption *o = NULL; + + if(!obj) + return NULL; + + c= *(AVClass**)obj; + + if (!c) + return NULL; + + if (search_flags & AV_OPT_SEARCH_CHILDREN) { + if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { + void *iter = NULL; + const AVClass *child; + while (child = av_opt_child_class_iterate(c, &iter)) + if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) + return o; + } else { + void *child = NULL; + while (child = av_opt_child_next(obj, child)) + if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) + return o; + } + } + + while (o = av_opt_next(obj, o)) { + if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && + ((!unit && o->type != AV_OPT_TYPE_CONST) || + (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { + if (target_obj) { + if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) + *target_obj = obj; + else + *target_obj = NULL; + } + return o; + } + } + return NULL; +} + +void *av_opt_child_next(void *obj, void *prev) +{ + const AVClass *c = *(AVClass **)obj; + if (c->child_next) + return c->child_next(obj, prev); + return NULL; +} + +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) +{ + if (parent->child_class_iterate) + return parent->child_class_iterate(iter); + return NULL; +} + +void *av_opt_ptr(const AVClass *class, void *obj, const char *name) +{ + const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); + if(!opt) + return NULL; + return (uint8_t*)obj + opt->offset; +} + +static int opt_size(enum AVOptionType type) +{ + switch(type) { + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_FLAGS: + return sizeof(int); + case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + return sizeof(int64_t); + case AV_OPT_TYPE_DOUBLE: + return sizeof(double); + case AV_OPT_TYPE_FLOAT: + return sizeof(float); + case AV_OPT_TYPE_STRING: + return sizeof(uint8_t*); + case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_RATIONAL: + return sizeof(AVRational); + case AV_OPT_TYPE_BINARY: + return sizeof(uint8_t*) + sizeof(int); + case AV_OPT_TYPE_IMAGE_SIZE: + return sizeof(int[2]); + case AV_OPT_TYPE_PIXEL_FMT: + return sizeof(enum AVPixelFormat); + case AV_OPT_TYPE_SAMPLE_FMT: + return sizeof(enum AVSampleFormat); + case AV_OPT_TYPE_COLOR: + return 4; + } + return AVERROR(EINVAL); +} + +int av_opt_copy(void *dst, const void *src) +{ + const AVOption *o = NULL; + const AVClass *c; + int ret = 0; + + if (!src) + return AVERROR(EINVAL); + + c = *(AVClass **)src; + if (!c || c != *(AVClass **)dst) + return AVERROR(EINVAL); + + while ((o = av_opt_next(src, o))) { + void *field_dst = (uint8_t *)dst + o->offset; + void *field_src = (uint8_t *)src + o->offset; + uint8_t **field_dst8 = (uint8_t **)field_dst; + uint8_t **field_src8 = (uint8_t **)field_src; + + if (o->type == AV_OPT_TYPE_STRING) { + if (*field_dst8 != *field_src8) + av_freep(field_dst8); + *field_dst8 = av_strdup(*field_src8); + if (*field_src8 && !*field_dst8) + ret = AVERROR(ENOMEM); + } else if (o->type == AV_OPT_TYPE_BINARY) { + int len = *(int *)(field_src8 + 1); + if (*field_dst8 != *field_src8) + av_freep(field_dst8); + *field_dst8 = av_memdup(*field_src8, len); + if (len && !*field_dst8) { + ret = AVERROR(ENOMEM); + len = 0; + } + *(int *)(field_dst8 + 1) = len; + } else if (o->type == AV_OPT_TYPE_CONST) { + // do nothing + } else if (o->type == AV_OPT_TYPE_DICT) { + AVDictionary **sdict = (AVDictionary **) field_src; + AVDictionary **ddict = (AVDictionary **) field_dst; + int ret2; + if (*sdict != *ddict) + av_dict_free(ddict); + *ddict = NULL; + ret2 = av_dict_copy(ddict, *sdict, 0); + if (ret2 < 0) + ret = ret2; + } else if (o->type == AV_OPT_TYPE_CHLAYOUT) { + if (field_dst != field_src) + ret = av_channel_layout_copy(field_dst, field_src); + } else { + int size = opt_size(o->type); + if (size < 0) + ret = size; + else + memcpy(field_dst, field_src, size); + } + } + return ret; +} + +int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) +{ + int ret; + const AVClass *c = *(AVClass**)obj; + int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = c->query_ranges; + + if (!callback) + callback = av_opt_query_ranges_default; + + ret = callback(ranges_arg, obj, key, flags); + if (ret >= 0) { + if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE)) + ret = 1; + (*ranges_arg)->nb_components = ret; + } + return ret; +} + +int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) +{ + AVOptionRanges *ranges = av_mallocz(sizeof(*ranges)); + AVOptionRange **range_array = av_mallocz(sizeof(void*)); + AVOptionRange *range = av_mallocz(sizeof(*range)); + const AVOption *field = av_opt_find(obj, key, NULL, 0, flags); + int ret; + + *ranges_arg = NULL; + + if (!ranges || !range || !range_array || !field) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ranges->range = range_array; + ranges->range[0] = range; + ranges->nb_ranges = 1; + ranges->nb_components = 1; + range->is_range = 1; + range->value_min = field->min; + range->value_max = field->max; + + switch (field->type) { + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_COLOR: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + break; + case AV_OPT_TYPE_STRING: + range->component_min = 0; + range->component_max = 0x10FFFF; // max unicode value + range->value_min = -1; + range->value_max = INT_MAX; + break; + case AV_OPT_TYPE_RATIONAL: + range->component_min = INT_MIN; + range->component_max = INT_MAX; + break; + case AV_OPT_TYPE_IMAGE_SIZE: + range->component_min = 0; + range->component_max = INT_MAX/128/8; + range->value_min = 0; + range->value_max = INT_MAX/8; + break; + case AV_OPT_TYPE_VIDEO_RATE: + range->component_min = 1; + range->component_max = INT_MAX; + range->value_min = 1; + range->value_max = INT_MAX; + break; + default: + ret = AVERROR(ENOSYS); + goto fail; + } + + *ranges_arg = ranges; + return 1; +fail: + av_free(ranges); + av_free(range); + av_free(range_array); + return ret; +} + +void av_opt_freep_ranges(AVOptionRanges **rangesp) +{ + int i; + AVOptionRanges *ranges = *rangesp; + + if (!ranges) + return; + + for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) { + AVOptionRange *range = ranges->range[i]; + if (range) { + av_freep(&range->str); + av_freep(&ranges->range[i]); + } + } + av_freep(&ranges->range); + av_freep(rangesp); +} + +int av_opt_is_set_to_default(void *obj, const AVOption *o) +{ + int64_t i64; + double d, d2; + float f; + AVRational q; + int ret, w, h; + char *str; + void *dst; + + if (!o || !obj) + return AVERROR(EINVAL); + + dst = ((uint8_t*)obj) + o->offset; + + switch (o->type) { + case AV_OPT_TYPE_CONST: + return 1; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_INT: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + read_number(o, dst, NULL, NULL, &i64); + return o->default_val.i64 == i64; + case AV_OPT_TYPE_CHLAYOUT: { + AVChannelLayout ch_layout = { 0 }; + if (o->default_val.str) { + if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0) + return ret; + } + return !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout); + } + case AV_OPT_TYPE_STRING: + str = *(char **)dst; + if (str == o->default_val.str) //2 NULLs + return 1; + if (!str || !o->default_val.str) //1 NULL + return 0; + return !strcmp(str, o->default_val.str); + case AV_OPT_TYPE_DOUBLE: + read_number(o, dst, &d, NULL, NULL); + return o->default_val.dbl == d; + case AV_OPT_TYPE_FLOAT: + read_number(o, dst, &d, NULL, NULL); + f = o->default_val.dbl; + d2 = f; + return d2 == d; + case AV_OPT_TYPE_RATIONAL: + q = av_d2q(o->default_val.dbl, INT_MAX); + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_BINARY: { + struct { + uint8_t *data; + int size; + } tmp = {0}; + int opt_size = *(int *)((void **)dst + 1); + void *opt_ptr = *(void **)dst; + if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str))) + return 1; + if (!opt_size || !o->default_val.str || !strlen(o->default_val.str )) + return 0; + if (opt_size != strlen(o->default_val.str) / 2) + return 0; + ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); + if (!ret) + ret = !memcmp(opt_ptr, tmp.data, tmp.size); + av_free(tmp.data); + return ret; + } + case AV_OPT_TYPE_DICT: { + AVDictionary *dict1 = NULL; + AVDictionary *dict2 = *(AVDictionary **)dst; + const AVDictionaryEntry *en1 = NULL; + const AVDictionaryEntry *en2 = NULL; + ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0); + if (ret < 0) { + av_dict_free(&dict1); + return ret; + } + do { + en1 = av_dict_iterate(dict1, en1); + en2 = av_dict_iterate(dict2, en2); + } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value)); + av_dict_free(&dict1); + return (!en1 && !en2); + } + case AV_OPT_TYPE_IMAGE_SIZE: + if (!o->default_val.str || !strcmp(o->default_val.str, "none")) + w = h = 0; + else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) + return ret; + return (w == *(int *)dst) && (h == *((int *)dst+1)); + case AV_OPT_TYPE_VIDEO_RATE: + q = (AVRational){0, 0}; + if (o->default_val.str) { + if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0) + return ret; + } + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_COLOR: { + uint8_t color[4] = {0, 0, 0, 0}; + if (o->default_val.str) { + if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0) + return ret; + } + return !memcmp(color, dst, sizeof(color)); + } + default: + av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); + break; + } + return AVERROR_PATCHWELCOME; +} + +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) +{ + const AVOption *o; + void *target; + if (!obj) + return AVERROR(EINVAL); + o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); + if (!o) + return AVERROR_OPTION_NOT_FOUND; + return av_opt_is_set_to_default(target, o); +} + +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep) +{ + const AVOption *o = NULL; + uint8_t *buf; + AVBPrint bprint; + int ret, cnt = 0; + const char special_chars[] = {pairs_sep, key_val_sep, '\0'}; + + if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || + pairs_sep == '\\' || key_val_sep == '\\') { + av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); + return AVERROR(EINVAL); + } + + if (!obj || !buffer) + return AVERROR(EINVAL); + + *buffer = NULL; + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + + while (o = av_opt_next(obj, o)) { + if (o->type == AV_OPT_TYPE_CONST) + continue; + if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags) + continue; + else if (((o->flags & opt_flags) != opt_flags)) + continue; + if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) + continue; + if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { + av_bprint_finalize(&bprint, NULL); + return ret; + } + if (buf) { + if (cnt++) + av_bprint_append_data(&bprint, &pairs_sep, 1); + av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_bprint_append_data(&bprint, &key_val_sep, 1); + av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_freep(&buf); + } + } + ret = av_bprint_finalize(&bprint, buffer); + if (ret < 0) + return ret; + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/opt.h b/arm/raspi/third_party/ffmpeg/libavutil/opt.h new file mode 100644 index 00000000..461b5d3b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/opt.h @@ -0,0 +1,891 @@ +/* + * AVOptions + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_OPT_H +#define AVUTIL_OPT_H + +/** + * @file + * AVOptions + */ + +#include "rational.h" +#include "avutil.h" +#include "channel_layout.h" +#include "dict.h" +#include "log.h" +#include "pixfmt.h" +#include "samplefmt.h" + +/** + * @defgroup avoptions AVOptions + * @ingroup lavu_data + * @{ + * AVOptions provide a generic system to declare options on arbitrary structs + * ("objects"). An option can have a help text, a type and a range of possible + * values. Options may then be enumerated, read and written to. + * + * @section avoptions_implement Implementing AVOptions + * This section describes how to add AVOptions capabilities to a struct. + * + * All AVOptions-related information is stored in an AVClass. Therefore + * the first member of the struct should be a pointer to an AVClass describing it. + * The option field of the AVClass must be set to a NULL-terminated static array + * of AVOptions. Each AVOption must have a non-empty name, a type, a default + * value and for number-type AVOptions also a range of allowed values. It must + * also declare an offset in bytes from the start of the struct, where the field + * associated with this AVOption is located. Other fields in the AVOption struct + * should also be set when applicable, but are not required. + * + * The following example illustrates an AVOptions-enabled struct: + * @code + * typedef struct test_struct { + * const AVClass *class; + * int int_opt; + * char *str_opt; + * uint8_t *bin_opt; + * int bin_len; + * } test_struct; + * + * static const AVOption test_options[] = { + * { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt), + * AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX }, + * { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt), + * AV_OPT_TYPE_STRING }, + * { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt), + * AV_OPT_TYPE_BINARY }, + * { NULL }, + * }; + * + * static const AVClass test_class = { + * .class_name = "test class", + * .item_name = av_default_item_name, + * .option = test_options, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * @endcode + * + * Next, when allocating your struct, you must ensure that the AVClass pointer + * is set to the correct value. Then, av_opt_set_defaults() can be called to + * initialize defaults. After that the struct is ready to be used with the + * AVOptions API. + * + * When cleaning up, you may use the av_opt_free() function to automatically + * free all the allocated string and binary options. + * + * Continuing with the above example: + * + * @code + * test_struct *alloc_test_struct(void) + * { + * test_struct *ret = av_mallocz(sizeof(*ret)); + * ret->class = &test_class; + * av_opt_set_defaults(ret); + * return ret; + * } + * void free_test_struct(test_struct **foo) + * { + * av_opt_free(*foo); + * av_freep(foo); + * } + * @endcode + * + * @subsection avoptions_implement_nesting Nesting + * It may happen that an AVOptions-enabled struct contains another + * AVOptions-enabled struct as a member (e.g. AVCodecContext in + * libavcodec exports generic options, while its priv_data field exports + * codec-specific options). In such a case, it is possible to set up the + * parent struct to export a child's options. To do that, simply + * implement AVClass.child_next() and AVClass.child_class_iterate() in the + * parent struct's AVClass. + * Assuming that the test_struct from above now also contains a + * child_struct field: + * + * @code + * typedef struct child_struct { + * AVClass *class; + * int flags_opt; + * } child_struct; + * static const AVOption child_opts[] = { + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX }, + * { NULL }, + * }; + * static const AVClass child_class = { + * .class_name = "child class", + * .item_name = av_default_item_name, + * .option = child_opts, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * + * void *child_next(void *obj, void *prev) + * { + * test_struct *t = obj; + * if (!prev && t->child_struct) + * return t->child_struct; + * return NULL + * } + * const AVClass child_class_iterate(void **iter) + * { + * const AVClass *c = *iter ? NULL : &child_class; + * *iter = (void*)(uintptr_t)c; + * return c; + * } + * @endcode + * Putting child_next() and child_class_iterate() as defined above into + * test_class will now make child_struct's options accessible through + * test_struct (again, proper setup as described above needs to be done on + * child_struct right after it is created). + * + * From the above example it might not be clear why both child_next() + * and child_class_iterate() are needed. The distinction is that child_next() + * iterates over actually existing objects, while child_class_iterate() + * iterates over all possible child classes. E.g. if an AVCodecContext + * was initialized to use a codec which has private options, then its + * child_next() will return AVCodecContext.priv_data and finish + * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will + * iterate over all available codecs with private options. + * + * @subsection avoptions_implement_named_constants Named constants + * It is possible to create named constants for options. Simply set the unit + * field of the option the constants should apply to a string and + * create the constants themselves as options of type AV_OPT_TYPE_CONST + * with their unit field set to the same string. + * Their default_val field should contain the value of the named + * constant. + * For example, to add some named constants for the test_flags option + * above, put the following into the child_opts array: + * @code + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" }, + * { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" }, + * @endcode + * + * @section avoptions_use Using AVOptions + * This section deals with accessing options in an AVOptions-enabled struct. + * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or + * AVFormatContext in libavformat. + * + * @subsection avoptions_use_examine Examining AVOptions + * The basic functions for examining options are av_opt_next(), which iterates + * over all options defined for one object, and av_opt_find(), which searches + * for an option with the given name. + * + * The situation is more complicated with nesting. An AVOptions-enabled struct + * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag + * to av_opt_find() will make the function search children recursively. + * + * For enumerating there are basically two cases. The first is when you want to + * get all options that may potentially exist on the struct and its children + * (e.g. when constructing documentation). In that case you should call + * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The + * second case is when you have an already initialized struct with all its + * children and you want to get all options that can be actually written or read + * from it. In that case you should call av_opt_child_next() recursively (and + * av_opt_next() on each result). + * + * @subsection avoptions_use_get_set Reading and writing AVOptions + * When setting options, you often have a string read directly from the + * user. In such a case, simply passing it to av_opt_set() is enough. For + * non-string type options, av_opt_set() will parse the string according to the + * option type. + * + * Similarly av_opt_get() will read any option type and convert it to a string + * which will be returned. Do not forget that the string is allocated, so you + * have to free it with av_free(). + * + * In some cases it may be more convenient to put all options into an + * AVDictionary and call av_opt_set_dict() on it. A specific case of this + * are the format/codec open functions in lavf/lavc which take a dictionary + * filled with option as a parameter. This makes it possible to set some options + * that cannot be set otherwise, since e.g. the input file format is not known + * before the file is actually opened. + */ + +enum AVOptionType{ + AV_OPT_TYPE_FLAGS, + AV_OPT_TYPE_INT, + AV_OPT_TYPE_INT64, + AV_OPT_TYPE_DOUBLE, + AV_OPT_TYPE_FLOAT, + AV_OPT_TYPE_STRING, + AV_OPT_TYPE_RATIONAL, + AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length + AV_OPT_TYPE_DICT, + AV_OPT_TYPE_UINT64, + AV_OPT_TYPE_CONST, + AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers + AV_OPT_TYPE_PIXEL_FMT, + AV_OPT_TYPE_SAMPLE_FMT, + AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational + AV_OPT_TYPE_DURATION, + AV_OPT_TYPE_COLOR, +#if FF_API_OLD_CHANNEL_LAYOUT + AV_OPT_TYPE_CHANNEL_LAYOUT, +#endif + AV_OPT_TYPE_BOOL, + AV_OPT_TYPE_CHLAYOUT, +}; + +/** + * AVOption + */ +typedef struct AVOption { + const char *name; + + /** + * short English help text + * @todo What about other languages? + */ + const char *help; + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; + enum AVOptionType type; + + /** + * the default value for scalar options + */ + union { + int64_t i64; + double dbl; + const char *str; + /* TODO those are unused now */ + AVRational q; + } default_val; + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option + + int flags; +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +/** + * The option is intended for exporting values to the caller. + */ +#define AV_OPT_FLAG_EXPORT 64 +/** + * The option may not be set through the AVOptions API, only read. + * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. + */ +#define AV_OPT_FLAG_READONLY 128 +#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering +#define AV_OPT_FLAG_RUNTIME_PARAM (1<<15) ///< a generic parameter which can be set by the user at runtime +#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering +#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information +#define AV_OPT_FLAG_CHILD_CONSTS (1<<18) ///< set if option constants can also reside in child objects +//FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ + const char *unit; +} AVOption; + +/** + * A single allowed range of values, or a single allowed value. + */ +typedef struct AVOptionRange { + const char *str; + /** + * Value range. + * For string ranges this represents the min/max length. + * For dimensions this represents the min/max pixel count or width/height in multi-component case. + */ + double value_min, value_max; + /** + * Value's component range. + * For string this represents the unicode range for chars, 0-127 limits to ASCII. + */ + double component_min, component_max; + /** + * Range flag. + * If set to 1 the struct encodes a range, if set to 0 a single value. + */ + int is_range; +} AVOptionRange; + +/** + * List of AVOptionRange structs. + */ +typedef struct AVOptionRanges { + /** + * Array of option ranges. + * + * Most of option types use just one component. + * Following describes multi-component option types: + * + * AV_OPT_TYPE_IMAGE_SIZE: + * component index 0: range of pixel count (width * height). + * component index 1: range of width. + * component index 2: range of height. + * + * @note To obtain multi-component version of this structure, user must + * provide AV_OPT_MULTI_COMPONENT_RANGE to av_opt_query_ranges or + * av_opt_query_ranges_default function. + * + * Multi-component range can be read as in following example: + * + * @code + * int range_index, component_index; + * AVOptionRanges *ranges; + * AVOptionRange *range[3]; //may require more than 3 in the future. + * av_opt_query_ranges(&ranges, obj, key, AV_OPT_MULTI_COMPONENT_RANGE); + * for (range_index = 0; range_index < ranges->nb_ranges; range_index++) { + * for (component_index = 0; component_index < ranges->nb_components; component_index++) + * range[component_index] = ranges->range[ranges->nb_ranges * component_index + range_index]; + * //do something with range here. + * } + * av_opt_freep_ranges(&ranges); + * @endcode + */ + AVOptionRange **range; + /** + * Number of ranges per component. + */ + int nb_ranges; + /** + * Number of componentes. + */ + int nb_components; +} AVOptionRanges; + +/** + * Show the obj options. + * + * @param req_flags requested flags for the options to show. Show only the + * options for which it is opt->flags & req_flags. + * @param rej_flags rejected flags for the options to show. Show only the + * options for which it is !(opt->flags & req_flags). + * @param av_log_obj log context to use for showing the options + */ +int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags); + +/** + * Set the values of all AVOption fields to their default values. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + */ +void av_opt_set_defaults(void *s); + +/** + * Set the values of all AVOption fields to their default values. Only these + * AVOption fields for which (opt->flags & mask) == flags will have their + * default applied to s. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + * @param mask combination of AV_OPT_FLAG_* + * @param flags combination of AV_OPT_FLAG_* + */ +void av_opt_set_defaults2(void *s, int mask, int flags); + +/** + * Parse the key/value pairs list in opts. For each key/value pair + * found, stores the value in the field in ctx that is named like the + * key. ctx must be an AVClass context, storing is done using + * AVOptions. + * + * @param opts options string to parse, may be NULL + * @param key_val_sep a 0-terminated list of characters used to + * separate key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @return the number of successfully set key/value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_opt_set() if a key/value pair + * cannot be set + */ +int av_set_options_string(void *ctx, const char *opts, + const char *key_val_sep, const char *pairs_sep); + +/** + * Parse the key-value pairs list in opts. For each key=value pair found, + * set the value of the corresponding option in ctx. + * + * @param ctx the AVClass object to set options on + * @param opts the options string, key-value pairs separated by a + * delimiter + * @param shorthand a NULL-terminated array of options names for shorthand + * notation: if the first field in opts has no key part, + * the key is taken from the first element of shorthand; + * then again for the second, etc., until either opts is + * finished, shorthand is finished or a named option is + * found; after that, all options must be named + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @return the number of successfully set key=value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_set_string3() if a key/value pair + * cannot be set + * + * Options names must use only the following characters: a-z A-Z 0-9 - . / _ + * Separators must use characters distinct from option names and from each + * other. + */ +int av_opt_set_from_string(void *ctx, const char *opts, + const char *const *shorthand, + const char *key_val_sep, const char *pairs_sep); +/** + * Free all allocated objects in obj. + */ +void av_opt_free(void *obj); + +/** + * Check whether a particular flag is set in a flags field. + * + * @param field_name the name of the flag field option + * @param flag_name the name of the flag to check + * @return non-zero if the flag is set, zero if the flag isn't set, + * isn't of the right type, or the flags field doesn't exist. + */ +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict(void *obj, struct AVDictionary **options); + + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags); + +/** + * Extract a key-value pair from the beginning of a string. + * + * @param ropts pointer to the options string, will be updated to + * point to the rest of the string (one of the pairs_sep + * or the final NUL) + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @param flags flags; see the AV_OPT_FLAG_* values below + * @param rkey parsed key; must be freed using av_free() + * @param rval parsed value; must be freed using av_free() + * + * @return >=0 for success, or a negative value corresponding to an + * AVERROR code in case of error; in particular: + * AVERROR(EINVAL) if no key is present + * + */ +int av_opt_get_key_value(const char **ropts, + const char *key_val_sep, const char *pairs_sep, + unsigned flags, + char **rkey, char **rval); + +enum { + + /** + * Accept to parse a value without a key; the key will then be returned + * as NULL. + */ + AV_OPT_FLAG_IMPLICIT_KEY = 1, +}; + +/** + * @defgroup opt_eval_funcs Evaluating option strings + * @{ + * This group of functions can be used to evaluate option strings + * and get numbers out of them. They do the same thing as av_opt_set(), + * except the result is written into the caller-supplied pointer. + * + * @param obj a struct whose first element is a pointer to AVClass. + * @param o an option for which the string is to be evaluated. + * @param val string to be evaluated. + * @param *_out value of the string will be written here. + * + * @return 0 on success, a negative number on failure. + */ +int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out); +int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out); +int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out); +int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out); +int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out); +int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out); +/** + * @} + */ + +#define AV_OPT_SEARCH_CHILDREN (1 << 0) /**< Search in possible children of the + given object first. */ +/** + * The obj passed to av_opt_find() is fake -- only a double pointer to AVClass + * instead of a required pointer to a struct containing AVClass. This is + * useful for searching for options without needing to allocate the corresponding + * object. + */ +#define AV_OPT_SEARCH_FAKE_OBJ (1 << 1) + +/** + * In av_opt_get, return NULL if the option has a pointer type and is set to NULL, + * rather than returning an empty string. + */ +#define AV_OPT_ALLOW_NULL (1 << 2) + +/** + * Allows av_opt_query_ranges and av_opt_query_ranges_default to return more than + * one component for certain option types. + * @see AVOptionRanges for details. + */ +#define AV_OPT_MULTI_COMPONENT_RANGE (1 << 12) + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return A pointer to the option found, or NULL if no option + * was found. + * + * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable + * directly with av_opt_set(). Use special calls which take an options + * AVDictionary (e.g. avformat_open_input()) to set options found with this + * flag. + */ +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * @param[out] target_obj if non-NULL, an object to which the option belongs will be + * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present + * in search_flags. This parameter is ignored if search_flags contain + * AV_OPT_SEARCH_FAKE_OBJ. + * + * @return A pointer to the option found, or NULL if no option + * was found. + */ +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj); + +/** + * Iterate over all AVOptions belonging to obj. + * + * @param obj an AVOptions-enabled struct or a double pointer to an + * AVClass describing it. + * @param prev result of the previous call to av_opt_next() on this object + * or NULL + * @return next AVOption or NULL + */ +const AVOption *av_opt_next(const void *obj, const AVOption *prev); + +/** + * Iterate over AVOptions-enabled children of obj. + * + * @param prev result of a previous call to this function or NULL + * @return next AVOptions-enabled child or NULL + */ +void *av_opt_child_next(void *obj, void *prev); + +/** + * Iterate over potential AVOptions-enabled children of parent. + * + * @param iter a pointer where iteration state is stored. + * @return AVClass corresponding to next potential child or NULL + */ +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter); + +/** + * @defgroup opt_set_funcs Option setting functions + * @{ + * Those functions set the field of obj with the given name to value. + * + * @param[in] obj A struct whose first element is a pointer to an AVClass. + * @param[in] name the name of the field to set + * @param[in] val The value to set. In case of av_opt_set() if the field is not + * of a string type, then the given string is parsed. + * SI postfixes and some named scalars are supported. + * If the field is of a numeric type, it has to be a numeric or named + * scalar. Behavior with more than one scalar and +- infix operators + * is undefined. + * If the field is of a flags type, it has to be a sequence of numeric + * scalars or named flags separated by '+' or '-'. Prefixing a flag + * with '+' causes it to be set without affecting the other flags; + * similarly, '-' unsets a flag. + * If the field is of a dictionary type, it has to be a ':' separated list of + * key=value parameters. Values containing ':' special characters must be + * escaped. + * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be set on a child of obj. + * + * @return 0 if the value has been set, or an AVERROR code in case of + * error: + * AVERROR_OPTION_NOT_FOUND if no matching option exists + * AVERROR(ERANGE) if the value is out of range + * AVERROR(EINVAL) if the value is not valid + */ +int av_opt_set (void *obj, const char *name, const char *val, int search_flags); +int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); +int av_opt_set_double (void *obj, const char *name, double val, int search_flags); +int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); +int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags); +int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); +int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); +int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); +#if FF_API_OLD_CHANNEL_LAYOUT +attribute_deprecated +int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); +#endif +int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags); +/** + * @note Any old dictionary present is discarded and replaced with a copy of the new one. The + * caller still owns val is and responsible for freeing it. + */ +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); + +/** + * Set a binary option to an integer list. + * + * @param obj AVClass object to set options on + * @param name name of the binary option + * @param val pointer to an integer list (must have the correct type with + * regard to the contents of the list) + * @param term list terminator (usually 0 or -1) + * @param flags search flags + */ +#define av_opt_set_int_list(obj, name, val, term, flags) \ + (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \ + AVERROR(EINVAL) : \ + av_opt_set_bin(obj, name, (const uint8_t *)(val), \ + av_int_list_length(val, term) * sizeof(*(val)), flags)) + +/** + * @} + */ + +/** + * @defgroup opt_get_funcs Option getting functions + * @{ + * Those functions get a value of the option with the given name from an object. + * + * @param[in] obj a struct whose first element is a pointer to an AVClass. + * @param[in] name name of the option to get. + * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be found in a child of obj. + * @param[out] out_val value of the option will be written here + * @return >=0 on success, a negative error code otherwise + */ +/** + * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller + * + * @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the + * option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT + * and is set to NULL, *out_val will be set to NULL instead of an allocated + * empty string. + */ +int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); +int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); +int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val); +int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out); +int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); +int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); +int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); +#if FF_API_OLD_CHANNEL_LAYOUT +attribute_deprecated +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); +#endif +int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout); +/** + * @param[out] out_val The returned dictionary is a copy of the actual value and must + * be freed with av_dict_free() by the caller + */ +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val); +/** + * @} + */ +/** + * Gets a pointer to the requested field in a struct. + * This function allows accessing a struct even when its fields are moved or + * renamed since the application making the access has been compiled, + * + * @returns a pointer to the field, it can be cast to the correct type and read + * or written to. + */ +void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name); + +/** + * Free an AVOptionRanges struct and set it to NULL. + */ +void av_opt_freep_ranges(AVOptionRanges **ranges); + +/** + * Get a list of allowed ranges for the given option. + * + * The returned list may depend on other fields in obj like for example profile. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_freep_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Copy options from src object into dest object. + * + * The underlying AVClass of both src and dest must coincide. The guarantee + * below does not apply if this is not fulfilled. + * + * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object. + * Original memory allocated for such options is freed unless both src and dest options points to the same memory. + * + * Even on error it is guaranteed that allocated options from src and dest + * no longer alias each other afterwards; in particular calling av_opt_free() + * on both src and dest is safe afterwards if dest has been memdup'ed from src. + * + * @param dest Object to copy from + * @param src Object to copy into + * @return 0 on success, negative on error + */ +int av_opt_copy(void *dest, const void *src); + +/** + * Get a default list of allowed ranges for the given option. + * + * This list is constructed without using the AVClass.query_ranges() callback + * and can be used as fallback from within the callback. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_free_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Check if given option is set to its default value. + * + * Options o must belong to the obj. This function must not be called to check child's options state. + * @see av_opt_is_set_to_default_by_name(). + * + * @param obj AVClass object to check option on + * @param o option to be checked + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default(void *obj, const AVOption *o); + +/** + * Check if given option is set to its default value. + * + * @param obj AVClass object to check option on + * @param name option name + * @param search_flags combination of AV_OPT_SEARCH_* + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags); + + +#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only. +#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only. + +/** + * Serialize object's options. + * + * Create a string containing object's serialized options. + * Such string may be passed back to av_opt_set_from_string() in order to restore option values. + * A key/value or pairs separator occurring in the serialized value or + * name string are escaped through the av_escape() function. + * + * @param[in] obj AVClass object to serialize + * @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG) + * @param[in] flags combination of AV_OPT_SERIALIZE_* flags + * @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep character used to separate key from value + * @param[in] pairs_sep character used to separate two pairs from each other + * @return >= 0 on success, negative on error + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + */ +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep); +/** + * @} + */ + +#endif /* AVUTIL_OPT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/parseutils.c b/arm/raspi/third_party/ffmpeg/libavutil/parseutils.c new file mode 100644 index 00000000..94e88e0a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/parseutils.c @@ -0,0 +1,790 @@ +/* + * 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 + * misc parsing utilities + */ + +#include + +#include "avstring.h" +#include "avutil.h" +#include "common.h" +#include "eval.h" +#include "log.h" +#include "random_seed.h" +#include "time_internal.h" +#include "parseutils.h" +#include "time.h" + +#ifdef TEST + +#define av_get_random_seed av_get_random_seed_deterministic +static uint32_t av_get_random_seed_deterministic(void); + +#define av_gettime() 1331972053200000 + +#endif + +int av_parse_ratio(AVRational *q, const char *str, int max, + int log_offset, void *log_ctx) +{ + char c; + int ret; + + if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) { + double d; + ret = av_expr_parse_and_eval(&d, str, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, log_offset, log_ctx); + if (ret < 0) + return ret; + *q = av_d2q(d, max); + } else { + av_reduce(&q->num, &q->den, q->num, q->den, max); + } + + return 0; +} + +typedef struct VideoSizeAbbr { + const char *abbr; + int width, height; +} VideoSizeAbbr; + +typedef struct VideoRateAbbr { + const char *abbr; + AVRational rate; +} VideoRateAbbr; + +static const VideoSizeAbbr video_size_abbrs[] = { + { "ntsc", 720, 480 }, + { "pal", 720, 576 }, + { "qntsc", 352, 240 }, /* VCD compliant NTSC */ + { "qpal", 352, 288 }, /* VCD compliant PAL */ + { "sntsc", 640, 480 }, /* square pixel NTSC */ + { "spal", 768, 576 }, /* square pixel PAL */ + { "film", 352, 240 }, + { "ntsc-film", 352, 240 }, + { "sqcif", 128, 96 }, + { "qcif", 176, 144 }, + { "cif", 352, 288 }, + { "4cif", 704, 576 }, + { "16cif", 1408,1152 }, + { "qqvga", 160, 120 }, + { "qvga", 320, 240 }, + { "vga", 640, 480 }, + { "svga", 800, 600 }, + { "xga", 1024, 768 }, + { "uxga", 1600,1200 }, + { "qxga", 2048,1536 }, + { "sxga", 1280,1024 }, + { "qsxga", 2560,2048 }, + { "hsxga", 5120,4096 }, + { "wvga", 852, 480 }, + { "wxga", 1366, 768 }, + { "wsxga", 1600,1024 }, + { "wuxga", 1920,1200 }, + { "woxga", 2560,1600 }, + { "wqhd", 2560,1440 }, + { "wqsxga", 3200,2048 }, + { "wquxga", 3840,2400 }, + { "whsxga", 6400,4096 }, + { "whuxga", 7680,4800 }, + { "cga", 320, 200 }, + { "ega", 640, 350 }, + { "hd480", 852, 480 }, + { "hd720", 1280, 720 }, + { "hd1080", 1920,1080 }, + { "quadhd", 2560,1440 }, + { "2k", 2048,1080 }, /* Digital Cinema System Specification */ + { "2kdci", 2048,1080 }, + { "2kflat", 1998,1080 }, + { "2kscope", 2048, 858 }, + { "4k", 4096,2160 }, /* Digital Cinema System Specification */ + { "4kdci", 4096,2160 }, + { "4kflat", 3996,2160 }, + { "4kscope", 4096,1716 }, + { "nhd", 640,360 }, + { "hqvga", 240,160 }, + { "wqvga", 400,240 }, + { "fwqvga", 432,240 }, + { "hvga", 480,320 }, + { "qhd", 960,540 }, + { "uhd2160", 3840,2160 }, + { "uhd4320", 7680,4320 }, +}; + +static const VideoRateAbbr video_rate_abbrs[]= { + { "ntsc", { 30000, 1001 } }, + { "pal", { 25, 1 } }, + { "qntsc", { 30000, 1001 } }, /* VCD compliant NTSC */ + { "qpal", { 25, 1 } }, /* VCD compliant PAL */ + { "sntsc", { 30000, 1001 } }, /* square pixel NTSC */ + { "spal", { 25, 1 } }, /* square pixel PAL */ + { "film", { 24, 1 } }, + { "ntsc-film", { 24000, 1001 } }, +}; + +static const char *months[12] = { + "january", "february", "march", "april", "may", "june", "july", "august", + "september", "october", "november", "december" +}; + +int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str) +{ + int i; + int n = FF_ARRAY_ELEMS(video_size_abbrs); + const char *p; + int width = 0, height = 0; + + for (i = 0; i < n; i++) { + if (!strcmp(video_size_abbrs[i].abbr, str)) { + width = video_size_abbrs[i].width; + height = video_size_abbrs[i].height; + break; + } + } + if (i == n) { + width = strtol(str, (void*)&p, 10); + if (*p) + p++; + height = strtol(p, (void*)&p, 10); + + /* trailing extraneous data detected, like in 123x345foobar */ + if (*p) + return AVERROR(EINVAL); + } + if (width <= 0 || height <= 0) + return AVERROR(EINVAL); + *width_ptr = width; + *height_ptr = height; + return 0; +} + +int av_parse_video_rate(AVRational *rate, const char *arg) +{ + int i, ret; + int n = FF_ARRAY_ELEMS(video_rate_abbrs); + + /* First, we check our abbreviation table */ + for (i = 0; i < n; ++i) + if (!strcmp(video_rate_abbrs[i].abbr, arg)) { + *rate = video_rate_abbrs[i].rate; + return 0; + } + + /* Then, we try to parse it as fraction */ + if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) + return ret; + if (rate->num <= 0 || rate->den <= 0) + return AVERROR(EINVAL); + return 0; +} + +typedef struct ColorEntry { + const char *name; ///< a string representing the name of the color + uint8_t rgb_color[3]; ///< RGB values for the color +} ColorEntry; + +static const ColorEntry color_table[] = { + { "AliceBlue", { 0xF0, 0xF8, 0xFF } }, + { "AntiqueWhite", { 0xFA, 0xEB, 0xD7 } }, + { "Aqua", { 0x00, 0xFF, 0xFF } }, + { "Aquamarine", { 0x7F, 0xFF, 0xD4 } }, + { "Azure", { 0xF0, 0xFF, 0xFF } }, + { "Beige", { 0xF5, 0xF5, 0xDC } }, + { "Bisque", { 0xFF, 0xE4, 0xC4 } }, + { "Black", { 0x00, 0x00, 0x00 } }, + { "BlanchedAlmond", { 0xFF, 0xEB, 0xCD } }, + { "Blue", { 0x00, 0x00, 0xFF } }, + { "BlueViolet", { 0x8A, 0x2B, 0xE2 } }, + { "Brown", { 0xA5, 0x2A, 0x2A } }, + { "BurlyWood", { 0xDE, 0xB8, 0x87 } }, + { "CadetBlue", { 0x5F, 0x9E, 0xA0 } }, + { "Chartreuse", { 0x7F, 0xFF, 0x00 } }, + { "Chocolate", { 0xD2, 0x69, 0x1E } }, + { "Coral", { 0xFF, 0x7F, 0x50 } }, + { "CornflowerBlue", { 0x64, 0x95, 0xED } }, + { "Cornsilk", { 0xFF, 0xF8, 0xDC } }, + { "Crimson", { 0xDC, 0x14, 0x3C } }, + { "Cyan", { 0x00, 0xFF, 0xFF } }, + { "DarkBlue", { 0x00, 0x00, 0x8B } }, + { "DarkCyan", { 0x00, 0x8B, 0x8B } }, + { "DarkGoldenRod", { 0xB8, 0x86, 0x0B } }, + { "DarkGray", { 0xA9, 0xA9, 0xA9 } }, + { "DarkGreen", { 0x00, 0x64, 0x00 } }, + { "DarkKhaki", { 0xBD, 0xB7, 0x6B } }, + { "DarkMagenta", { 0x8B, 0x00, 0x8B } }, + { "DarkOliveGreen", { 0x55, 0x6B, 0x2F } }, + { "Darkorange", { 0xFF, 0x8C, 0x00 } }, + { "DarkOrchid", { 0x99, 0x32, 0xCC } }, + { "DarkRed", { 0x8B, 0x00, 0x00 } }, + { "DarkSalmon", { 0xE9, 0x96, 0x7A } }, + { "DarkSeaGreen", { 0x8F, 0xBC, 0x8F } }, + { "DarkSlateBlue", { 0x48, 0x3D, 0x8B } }, + { "DarkSlateGray", { 0x2F, 0x4F, 0x4F } }, + { "DarkTurquoise", { 0x00, 0xCE, 0xD1 } }, + { "DarkViolet", { 0x94, 0x00, 0xD3 } }, + { "DeepPink", { 0xFF, 0x14, 0x93 } }, + { "DeepSkyBlue", { 0x00, 0xBF, 0xFF } }, + { "DimGray", { 0x69, 0x69, 0x69 } }, + { "DodgerBlue", { 0x1E, 0x90, 0xFF } }, + { "FireBrick", { 0xB2, 0x22, 0x22 } }, + { "FloralWhite", { 0xFF, 0xFA, 0xF0 } }, + { "ForestGreen", { 0x22, 0x8B, 0x22 } }, + { "Fuchsia", { 0xFF, 0x00, 0xFF } }, + { "Gainsboro", { 0xDC, 0xDC, 0xDC } }, + { "GhostWhite", { 0xF8, 0xF8, 0xFF } }, + { "Gold", { 0xFF, 0xD7, 0x00 } }, + { "GoldenRod", { 0xDA, 0xA5, 0x20 } }, + { "Gray", { 0x80, 0x80, 0x80 } }, + { "Green", { 0x00, 0x80, 0x00 } }, + { "GreenYellow", { 0xAD, 0xFF, 0x2F } }, + { "HoneyDew", { 0xF0, 0xFF, 0xF0 } }, + { "HotPink", { 0xFF, 0x69, 0xB4 } }, + { "IndianRed", { 0xCD, 0x5C, 0x5C } }, + { "Indigo", { 0x4B, 0x00, 0x82 } }, + { "Ivory", { 0xFF, 0xFF, 0xF0 } }, + { "Khaki", { 0xF0, 0xE6, 0x8C } }, + { "Lavender", { 0xE6, 0xE6, 0xFA } }, + { "LavenderBlush", { 0xFF, 0xF0, 0xF5 } }, + { "LawnGreen", { 0x7C, 0xFC, 0x00 } }, + { "LemonChiffon", { 0xFF, 0xFA, 0xCD } }, + { "LightBlue", { 0xAD, 0xD8, 0xE6 } }, + { "LightCoral", { 0xF0, 0x80, 0x80 } }, + { "LightCyan", { 0xE0, 0xFF, 0xFF } }, + { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } }, + { "LightGreen", { 0x90, 0xEE, 0x90 } }, + { "LightGrey", { 0xD3, 0xD3, 0xD3 } }, + { "LightPink", { 0xFF, 0xB6, 0xC1 } }, + { "LightSalmon", { 0xFF, 0xA0, 0x7A } }, + { "LightSeaGreen", { 0x20, 0xB2, 0xAA } }, + { "LightSkyBlue", { 0x87, 0xCE, 0xFA } }, + { "LightSlateGray", { 0x77, 0x88, 0x99 } }, + { "LightSteelBlue", { 0xB0, 0xC4, 0xDE } }, + { "LightYellow", { 0xFF, 0xFF, 0xE0 } }, + { "Lime", { 0x00, 0xFF, 0x00 } }, + { "LimeGreen", { 0x32, 0xCD, 0x32 } }, + { "Linen", { 0xFA, 0xF0, 0xE6 } }, + { "Magenta", { 0xFF, 0x00, 0xFF } }, + { "Maroon", { 0x80, 0x00, 0x00 } }, + { "MediumAquaMarine", { 0x66, 0xCD, 0xAA } }, + { "MediumBlue", { 0x00, 0x00, 0xCD } }, + { "MediumOrchid", { 0xBA, 0x55, 0xD3 } }, + { "MediumPurple", { 0x93, 0x70, 0xD8 } }, + { "MediumSeaGreen", { 0x3C, 0xB3, 0x71 } }, + { "MediumSlateBlue", { 0x7B, 0x68, 0xEE } }, + { "MediumSpringGreen", { 0x00, 0xFA, 0x9A } }, + { "MediumTurquoise", { 0x48, 0xD1, 0xCC } }, + { "MediumVioletRed", { 0xC7, 0x15, 0x85 } }, + { "MidnightBlue", { 0x19, 0x19, 0x70 } }, + { "MintCream", { 0xF5, 0xFF, 0xFA } }, + { "MistyRose", { 0xFF, 0xE4, 0xE1 } }, + { "Moccasin", { 0xFF, 0xE4, 0xB5 } }, + { "NavajoWhite", { 0xFF, 0xDE, 0xAD } }, + { "Navy", { 0x00, 0x00, 0x80 } }, + { "OldLace", { 0xFD, 0xF5, 0xE6 } }, + { "Olive", { 0x80, 0x80, 0x00 } }, + { "OliveDrab", { 0x6B, 0x8E, 0x23 } }, + { "Orange", { 0xFF, 0xA5, 0x00 } }, + { "OrangeRed", { 0xFF, 0x45, 0x00 } }, + { "Orchid", { 0xDA, 0x70, 0xD6 } }, + { "PaleGoldenRod", { 0xEE, 0xE8, 0xAA } }, + { "PaleGreen", { 0x98, 0xFB, 0x98 } }, + { "PaleTurquoise", { 0xAF, 0xEE, 0xEE } }, + { "PaleVioletRed", { 0xD8, 0x70, 0x93 } }, + { "PapayaWhip", { 0xFF, 0xEF, 0xD5 } }, + { "PeachPuff", { 0xFF, 0xDA, 0xB9 } }, + { "Peru", { 0xCD, 0x85, 0x3F } }, + { "Pink", { 0xFF, 0xC0, 0xCB } }, + { "Plum", { 0xDD, 0xA0, 0xDD } }, + { "PowderBlue", { 0xB0, 0xE0, 0xE6 } }, + { "Purple", { 0x80, 0x00, 0x80 } }, + { "Red", { 0xFF, 0x00, 0x00 } }, + { "RosyBrown", { 0xBC, 0x8F, 0x8F } }, + { "RoyalBlue", { 0x41, 0x69, 0xE1 } }, + { "SaddleBrown", { 0x8B, 0x45, 0x13 } }, + { "Salmon", { 0xFA, 0x80, 0x72 } }, + { "SandyBrown", { 0xF4, 0xA4, 0x60 } }, + { "SeaGreen", { 0x2E, 0x8B, 0x57 } }, + { "SeaShell", { 0xFF, 0xF5, 0xEE } }, + { "Sienna", { 0xA0, 0x52, 0x2D } }, + { "Silver", { 0xC0, 0xC0, 0xC0 } }, + { "SkyBlue", { 0x87, 0xCE, 0xEB } }, + { "SlateBlue", { 0x6A, 0x5A, 0xCD } }, + { "SlateGray", { 0x70, 0x80, 0x90 } }, + { "Snow", { 0xFF, 0xFA, 0xFA } }, + { "SpringGreen", { 0x00, 0xFF, 0x7F } }, + { "SteelBlue", { 0x46, 0x82, 0xB4 } }, + { "Tan", { 0xD2, 0xB4, 0x8C } }, + { "Teal", { 0x00, 0x80, 0x80 } }, + { "Thistle", { 0xD8, 0xBF, 0xD8 } }, + { "Tomato", { 0xFF, 0x63, 0x47 } }, + { "Turquoise", { 0x40, 0xE0, 0xD0 } }, + { "Violet", { 0xEE, 0x82, 0xEE } }, + { "Wheat", { 0xF5, 0xDE, 0xB3 } }, + { "White", { 0xFF, 0xFF, 0xFF } }, + { "WhiteSmoke", { 0xF5, 0xF5, 0xF5 } }, + { "Yellow", { 0xFF, 0xFF, 0x00 } }, + { "YellowGreen", { 0x9A, 0xCD, 0x32 } }, +}; + +static int color_table_compare(const void *lhs, const void *rhs) +{ + return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name); +} + +#define ALPHA_SEP '@' + +int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, + void *log_ctx) +{ + char *tail, color_string2[128]; + const ColorEntry *entry; + int len, hex_offset = 0; + + if (color_string[0] == '#') { + hex_offset = 1; + } else if (!strncmp(color_string, "0x", 2)) + hex_offset = 2; + + if (slen < 0) + slen = strlen(color_string); + av_strlcpy(color_string2, color_string + hex_offset, + FFMIN(slen-hex_offset+1, sizeof(color_string2))); + if ((tail = strchr(color_string2, ALPHA_SEP))) + *tail++ = 0; + len = strlen(color_string2); + rgba_color[3] = 255; + + if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) { + int rgba = av_get_random_seed(); + rgba_color[0] = rgba >> 24; + rgba_color[1] = rgba >> 16; + rgba_color[2] = rgba >> 8; + rgba_color[3] = rgba; + } else if (hex_offset || + strspn(color_string2, "0123456789ABCDEFabcdef") == len) { + char *tail; + unsigned int rgba = strtoul(color_string2, &tail, 16); + + if (*tail || (len != 6 && len != 8)) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2); + return AVERROR(EINVAL); + } + if (len == 8) { + rgba_color[3] = rgba; + rgba >>= 8; + } + rgba_color[0] = rgba >> 16; + rgba_color[1] = rgba >> 8; + rgba_color[2] = rgba; + } else { + entry = bsearch(color_string2, + color_table, + FF_ARRAY_ELEMS(color_table), + sizeof(ColorEntry), + color_table_compare); + if (!entry) { + av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2); + return AVERROR(EINVAL); + } + memcpy(rgba_color, entry->rgb_color, 3); + } + + if (tail) { + double alpha; + const char *alpha_string = tail; + if (!strncmp(alpha_string, "0x", 2)) { + alpha = strtoul(alpha_string, &tail, 16); + } else { + double norm_alpha = strtod(alpha_string, &tail); + if (norm_alpha < 0.0 || norm_alpha > 1.0) + alpha = 256; + else + alpha = 255 * norm_alpha; + } + + if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n", + alpha_string, color_string); + return AVERROR(EINVAL); + } + rgba_color[3] = alpha; + } + + return 0; +} + +const char *av_get_known_color_name(int color_idx, const uint8_t **rgbp) +{ + const ColorEntry *color; + + if ((unsigned)color_idx >= FF_ARRAY_ELEMS(color_table)) + return NULL; + + color = &color_table[color_idx]; + if (rgbp) + *rgbp = color->rgb_color; + + return color->name; +} + +/* get a positive number between n_min and n_max, for a maximum length + of len_max. Return -1 if error. */ +static int date_get_num(const char **pp, + int n_min, int n_max, int len_max) +{ + int i, val, c; + const char *p; + + p = *pp; + val = 0; + for(i = 0; i < len_max; i++) { + c = *p; + if (!av_isdigit(c)) + break; + val = (val * 10) + c - '0'; + p++; + } + /* no number read ? */ + if (p == *pp) + return -1; + if (val < n_min || val > n_max) + return -1; + *pp = p; + return val; +} + +static int date_get_month(const char **pp) { + int i = 0; + for (; i < 12; i++) { + if (!av_strncasecmp(*pp, months[i], 3)) { + const char *mo_full = months[i] + 3; + int len = strlen(mo_full); + *pp += 3; + if (len > 0 && !av_strncasecmp(*pp, mo_full, len)) + *pp += len; + return i; + } + } + return -1; +} + +char *av_small_strptime(const char *p, const char *fmt, struct tm *dt) +{ + int c, val; + + while((c = *fmt++)) { + if (c != '%') { + if (av_isspace(c)) + for (; *p && av_isspace(*p); p++); + else if (*p != c) + return NULL; + else p++; + continue; + } + + c = *fmt++; + switch(c) { + case 'H': + case 'J': + val = date_get_num(&p, 0, c == 'H' ? 23 : INT_MAX, c == 'H' ? 2 : 4); + + if (val == -1) + return NULL; + dt->tm_hour = val; + break; + case 'M': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_min = val; + break; + case 'S': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_sec = val; + break; + case 'Y': + val = date_get_num(&p, 0, 9999, 4); + if (val == -1) + return NULL; + dt->tm_year = val - 1900; + break; + case 'm': + val = date_get_num(&p, 1, 12, 2); + if (val == -1) + return NULL; + dt->tm_mon = val - 1; + break; + case 'd': + val = date_get_num(&p, 1, 31, 2); + if (val == -1) + return NULL; + dt->tm_mday = val; + break; + case 'T': + p = av_small_strptime(p, "%H:%M:%S", dt); + if (!p) + return NULL; + break; + case 'b': + case 'B': + case 'h': + val = date_get_month(&p); + if (val == -1) + return NULL; + dt->tm_mon = val; + break; + case '%': + if (*p++ != '%') + return NULL; + break; + default: + return NULL; + } + } + + return (char*)p; +} + +time_t av_timegm(struct tm *tm) +{ + time_t t; + + int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; + + if (m < 3) { + m += 12; + y--; + } + + t = 86400LL * + (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); + + t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; + + return t; +} + +int av_parse_time(int64_t *timeval, const char *timestr, int duration) +{ + const char *p, *q; + int64_t t, now64; + time_t now; + struct tm dt = { 0 }, tmbuf; + int today = 0, negative = 0, microseconds = 0, suffix = 1000000; + int i; + static const char * const date_fmt[] = { + "%Y - %m - %d", + "%Y%m%d", + }; + static const char * const time_fmt[] = { + "%H:%M:%S", + "%H%M%S", + }; + static const char * const tz_fmt[] = { + "%H:%M", + "%H%M", + "%H", + }; + + p = timestr; + q = NULL; + *timeval = INT64_MIN; + if (!duration) { + now64 = av_gettime(); + now = now64 / 1000000; + + if (!av_strcasecmp(timestr, "now")) { + *timeval = now64; + return 0; + } + + /* parse the year-month-day part */ + for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) { + q = av_small_strptime(p, date_fmt[i], &dt); + if (q) + break; + } + + /* if the year-month-day part is missing, then take the + * current year-month-day time */ + if (!q) { + today = 1; + q = p; + } + p = q; + + if (*p == 'T' || *p == 't') + p++; + else + while (av_isspace(*p)) + p++; + + /* parse the hour-minute-second part */ + for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) { + q = av_small_strptime(p, time_fmt[i], &dt); + if (q) + break; + } + } else { + /* parse timestr as a duration */ + if (p[0] == '-') { + negative = 1; + ++p; + } + /* parse timestr as HH:MM:SS */ + q = av_small_strptime(p, "%J:%M:%S", &dt); + if (!q) { + /* parse timestr as MM:SS */ + q = av_small_strptime(p, "%M:%S", &dt); + dt.tm_hour = 0; + } + if (!q) { + char *o; + /* parse timestr as S+ */ + errno = 0; + t = strtoll(p, &o, 10); + if (o == p) /* the parsing didn't succeed */ + return AVERROR(EINVAL); + if (errno == ERANGE) + return AVERROR(ERANGE); + q = o; + } else { + t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; + } + } + + /* Now we have all the fields that we can get */ + if (!q) + return AVERROR(EINVAL); + + /* parse the .m... part */ + if (*q == '.') { + int n; + q++; + for (n = 100000; n >= 1; n /= 10, q++) { + if (!av_isdigit(*q)) + break; + microseconds += n * (*q - '0'); + } + while (av_isdigit(*q)) + q++; + } + + if (duration) { + if (q[0] == 'm' && q[1] == 's') { + suffix = 1000; + microseconds /= 1000; + q += 2; + } else if (q[0] == 'u' && q[1] == 's') { + suffix = 1; + microseconds = 0; + q += 2; + } else if (*q == 's') + q++; + } else { + int is_utc = *q == 'Z' || *q == 'z'; + int tzoffset = 0; + q += is_utc; + if (!today && !is_utc && (*q == '+' || *q == '-')) { + struct tm tz = { 0 }; + int sign = (*q == '+' ? -1 : 1); + q++; + p = q; + for (i = 0; i < FF_ARRAY_ELEMS(tz_fmt); i++) { + q = av_small_strptime(p, tz_fmt[i], &tz); + if (q) + break; + } + if (!q) + return AVERROR(EINVAL); + tzoffset = sign * (tz.tm_hour * 60 + tz.tm_min) * 60; + is_utc = 1; + } + if (today) { /* fill in today's date */ + struct tm dt2 = is_utc ? *gmtime_r(&now, &tmbuf) : *localtime_r(&now, &tmbuf); + dt2.tm_hour = dt.tm_hour; + dt2.tm_min = dt.tm_min; + dt2.tm_sec = dt.tm_sec; + dt = dt2; + } + dt.tm_isdst = is_utc ? 0 : -1; + t = is_utc ? av_timegm(&dt) : mktime(&dt); + t += tzoffset; + } + + /* Check that we are at the end of the string */ + if (*q) + return AVERROR(EINVAL); + + if (INT64_MAX / suffix < t || t < INT64_MIN / suffix) + return AVERROR(ERANGE); + t *= suffix; + if (INT64_MAX - microseconds < t) + return AVERROR(ERANGE); + t += microseconds; + if (t == INT64_MIN && negative) + return AVERROR(ERANGE); + *timeval = negative ? -t : t; + return 0; +} + +int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) +{ + const char *p; + char tag[128], *q; + + p = info; + if (*p == '?') + p++; + for(;;) { + q = tag; + while (*p != '\0' && *p != '=' && *p != '&') { + if ((q - tag) < sizeof(tag) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + q = arg; + if (*p == '=') { + p++; + while (*p != '&' && *p != '\0') { + if ((q - arg) < arg_size - 1) { + if (*p == '+') + *q++ = ' '; + else + *q++ = *p; + } + p++; + } + } + *q = '\0'; + if (!strcmp(tag, tag1)) + return 1; + if (*p != '&') + break; + p++; + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/parseutils.h b/arm/raspi/third_party/ffmpeg/libavutil/parseutils.h new file mode 100644 index 00000000..dad5c277 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/parseutils.h @@ -0,0 +1,197 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PARSEUTILS_H +#define AVUTIL_PARSEUTILS_H + +#include + +#include "rational.h" + +/** + * @file + * misc parsing utilities + */ + +/** + * Parse str and store the parsed ratio in q. + * + * Note that a ratio with infinite (1/0) or negative value is + * considered valid, so you should check on the returned value if you + * want to exclude those values. + * + * The undefined value can be expressed using the "0:0" string. + * + * @param[in,out] q pointer to the AVRational which will contain the ratio + * @param[in] str the string to parse: it has to be a string in the format + * num:den, a float number or an expression + * @param[in] max the maximum allowed numerator and denominator + * @param[in] log_offset log level offset which is applied to the log + * level of log_ctx + * @param[in] log_ctx parent logging context + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_ratio(AVRational *q, const char *str, int max, + int log_offset, void *log_ctx); + +#define av_parse_ratio_quiet(rate, str, max) \ + av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL) + +/** + * Parse str and put in width_ptr and height_ptr the detected values. + * + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * height value + * @param[in] str the string to parse: it has to be a string in the format + * width x height or a valid video size abbreviation. + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parse str and store the detected values in *rate. + * + * @param[in,out] rate pointer to the AVRational which will contain the detected + * frame rate + * @param[in] str the string to parse: it has to be a string in the format + * rate_num / rate_den, a float number or a valid video rate abbreviation + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_rate(AVRational *rate, const char *str); + +/** + * Put the RGBA values that correspond to color_string in rgba_color. + * + * @param rgba_color 4-elements array of uint8_t values, where the respective + * red, green, blue and alpha component values are written. + * @param color_string a string specifying a color. It can be the name of + * a color (case insensitive match) or a [0x|#]RRGGBB[AA] sequence, + * possibly followed by "@" and a string representing the alpha + * component. + * The alpha component may be a string composed by "0x" followed by an + * hexadecimal number or a decimal number between 0.0 and 1.0, which + * represents the opacity value (0x00/0.0 means completely transparent, + * 0xff/1.0 completely opaque). + * If the alpha component is not specified then 0xff is assumed. + * The string "random" will result in a random color. + * @param slen length of the initial part of color_string containing the + * color. It can be set to -1 if color_string is a null terminated string + * containing nothing else than the color. + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log()). Can be NULL. + * @return >= 0 in case of success, a negative value in case of + * failure (for example if color_string cannot be parsed). + */ +int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, + void *log_ctx); + +/** + * Get the name of a color from the internal table of hard-coded named + * colors. + * + * This function is meant to enumerate the color names recognized by + * av_parse_color(). + * + * @param color_idx index of the requested color, starting from 0 + * @param rgb if not NULL, will point to a 3-elements array with the color value in RGB + * @return the color name string or NULL if color_idx is not in the array + */ +const char *av_get_known_color_name(int color_idx, const uint8_t **rgb); + +/** + * Parse timestr and return in *time a corresponding number of + * microseconds. + * + * @param timeval puts here the number of microseconds corresponding + * to the string in timestr. If the string represents a duration, it + * is the number of microseconds contained in the time interval. If + * the string is a date, is the number of microseconds since 1st of + * January, 1970 up to the time of the parsed date. If timestr cannot + * be successfully parsed, set *time to INT64_MIN. + + * @param timestr a string representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH:MM:SS[.m...]]]}|{HHMMSS[.m...]]]}}[Z] + * now + * @endcode + * If the value is "now" it takes the current time. + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * - If a duration the syntax is: + * @code + * [-][HH:]MM:SS[.m...] + * [-]S+[.m...] + * @endcode + * @param duration flag which tells how to interpret timestr, if not + * zero timestr is interpreted as a duration, otherwise as a date + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_parse_time(int64_t *timeval, const char *timestr, int duration); + +/** + * Attempt to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Simplified version of strptime + * + * Parse the input string p according to the format string fmt and + * store its results in the structure dt. + * This implementation supports only a subset of the formats supported + * by the standard strptime(). + * + * The supported input field descriptors are listed below. + * - `%%H`: the hour as a decimal number, using a 24-hour clock, in the + * range '00' through '23' + * - `%%J`: hours as a decimal number, in the range '0' through INT_MAX + * - `%%M`: the minute as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - `%%S`: the second as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - `%%Y`: the year as a decimal number, using the Gregorian calendar + * - `%%m`: the month as a decimal number, in the range '1' through '12' + * - `%%d`: the day of the month as a decimal number, in the range '1' + * through '31' + * - `%%T`: alias for `%%H:%%M:%%S` + * - `%%`: a literal `%` + * + * @return a pointer to the first character not processed in this function + * call. In case the input string contains more characters than + * required by the format string the return value points right after + * the last consumed input character. In case the whole input string + * is consumed the return value points to the null byte at the end of + * the string. On failure NULL is returned. + */ +char *av_small_strptime(const char *p, const char *fmt, struct tm *dt); + +/** + * Convert the decomposed UTC time in tm to a time_t value. + */ +time_t av_timegm(struct tm *tm); + +#endif /* AVUTIL_PARSEUTILS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/pca.c b/arm/raspi/third_party/ffmpeg/libavutil/pca.c new file mode 100644 index 00000000..4e52c7b3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/pca.c @@ -0,0 +1,173 @@ +/* + * principal component analysis (PCA) + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * principal component analysis (PCA) + */ + +#include "common.h" +#include "pca.h" + +typedef struct PCA{ + int count; + int n; + double *covariance; + double *mean; + double *z; +}PCA; + +PCA *ff_pca_init(int n){ + PCA *pca; + if(n<=0) + return NULL; + + pca= av_mallocz(sizeof(*pca)); + if (!pca) + return NULL; + + pca->n= n; + pca->z = av_malloc_array(n, sizeof(*pca->z)); + pca->count=0; + pca->covariance= av_calloc(n*n, sizeof(double)); + pca->mean= av_calloc(n, sizeof(double)); + + if (!pca->z || !pca->covariance || !pca->mean) { + ff_pca_free(pca); + return NULL; + } + + return pca; +} + +void ff_pca_free(PCA *pca){ + av_freep(&pca->covariance); + av_freep(&pca->mean); + av_freep(&pca->z); + av_free(pca); +} + +void ff_pca_add(PCA *pca, const double *v){ + int i, j; + const int n= pca->n; + + for(i=0; imean[i] += v[i]; + for(j=i; jcovariance[j + i*n] += v[i]*v[j]; + } + pca->count++; +} + +int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){ + int i, j, pass; + int k=0; + const int n= pca->n; + double *z = pca->z; + + memset(eigenvector, 0, sizeof(double)*n*n); + + for(j=0; jmean[j] /= pca->count; + eigenvector[j + j*n] = 1.0; + for(i=0; i<=j; i++){ + pca->covariance[j + i*n] /= pca->count; + pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j]; + pca->covariance[i + j*n] = pca->covariance[j + i*n]; + } + eigenvalue[j]= pca->covariance[j + j*n]; + z[j]= 0; + } + + for(pass=0; pass < 50; pass++){ + double sum=0; + + for(i=0; icovariance[j + i*n]); + + if(sum == 0){ + for(i=0; i maxvalue){ + maxvalue= eigenvalue[j]; + k= j; + } + } + eigenvalue[k]= eigenvalue[i]; + eigenvalue[i]= maxvalue; + for(j=0; jcovariance[j + i*n]; + double t,c,s,tau,theta, h; + + if(pass < 3 && fabs(covar) < sum / (5*n*n)) //FIXME why pass < 3 + continue; + if(fabs(covar) == 0.0) //FIXME should not be needed + continue; + if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){ + pca->covariance[j + i*n]=0.0; + continue; + } + + h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]); + theta=0.5*h/covar; + t=1.0/(fabs(theta)+sqrt(1.0+theta*theta)); + if(theta < 0.0) t = -t; + + c=1.0/sqrt(1+t*t); + s=t*c; + tau=s/(1.0+c); + z[i] -= t*covar; + z[j] += t*covar; + +#define ROTATE(a,i,j,k,l) {\ + double g=a[j + i*n];\ + double h=a[l + k*n];\ + a[j + i*n]=g-s*(h+g*tau);\ + a[l + k*n]=h+s*(g-h*tau); } + for(k=0; kcovariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j)) + } + ROTATE(eigenvector,k,i,k,j) + } + pca->covariance[j + i*n]=0.0; + } + } + for (i=0; i + * + * 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 + * principal component analysis (PCA) + */ + +#ifndef AVUTIL_PCA_H +#define AVUTIL_PCA_H + +struct PCA *ff_pca_init(int n); +void ff_pca_free(struct PCA *pca); +void ff_pca_add(struct PCA *pca, const double *v); +int ff_pca(struct PCA *pca, double *eigenvector, double *eigenvalue); + +#endif /* AVUTIL_PCA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.c b/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.c new file mode 100644 index 00000000..62a2ae08 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.c @@ -0,0 +1,3327 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "avstring.h" +#include "common.h" +#include "pixfmt.h" +#include "pixdesc.h" +#include "intreadwrite.h" + +void av_read_image_line2(void *dst, + const uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, + int read_pal_component, + int dst_element_size) +{ + AVComponentDescriptor comp = desc->comp[c]; + int plane = comp.plane; + int depth = comp.depth; + unsigned mask = (1ULL << depth) - 1; + int shift = comp.shift; + int step = comp.step; + int flags = desc->flags; + uint16_t *dst16 = dst; + uint32_t *dst32 = dst; + + if (flags & AV_PIX_FMT_FLAG_BITSTREAM) { + if (depth == 10) { + // Assume all channels are packed into a 32bit value + const uint8_t *byte_p = data[plane] + y * linesize[plane]; + const uint32_t *p = (uint32_t *)byte_p; + + while (w--) { + int val = AV_RB32(p); + val = (val >> comp.offset) & mask; + if (read_pal_component) + val = data[1][4*val + c]; + if (dst_element_size == 4) *dst32++ = val; + else *dst16++ = val; + p++; + } + } else { + int skip = x * step + comp.offset; + const uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3); + int shift = 8 - depth - (skip & 7); + + while (w--) { + int val = (*p >> shift) & mask; + if (read_pal_component) + val = data[1][4*val + c]; + shift -= step; + p -= shift >> 3; + shift &= 7; + if (dst_element_size == 4) *dst32++ = val; + else *dst16++ = val; + } + } + } else { + const uint8_t *p = data[plane] + y * linesize[plane] + + x * step + comp.offset; + int is_8bit = shift + depth <= 8; + int is_16bit= shift + depth <=16; + + if (is_8bit) + p += !!(flags & AV_PIX_FMT_FLAG_BE); + + while (w--) { + unsigned val; + if (is_8bit) val = *p; + else if(is_16bit) val = flags & AV_PIX_FMT_FLAG_BE ? AV_RB16(p) : AV_RL16(p); + else val = flags & AV_PIX_FMT_FLAG_BE ? AV_RB32(p) : AV_RL32(p); + val = (val >> shift) & mask; + if (read_pal_component) + val = data[1][4 * val + c]; + p += step; + if (dst_element_size == 4) *dst32++ = val; + else *dst16++ = val; + } + } +} + +void av_read_image_line(uint16_t *dst, + const uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, + int read_pal_component) +{ + av_read_image_line2(dst, data, linesize, desc,x, y, c, w, + read_pal_component, + 2); +} + +void av_write_image_line2(const void *src, + uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size) +{ + AVComponentDescriptor comp = desc->comp[c]; + int plane = comp.plane; + int depth = comp.depth; + int step = comp.step; + int flags = desc->flags; + const uint32_t *src32 = src; + const uint16_t *src16 = src; + + if (flags & AV_PIX_FMT_FLAG_BITSTREAM) { + if (depth == 10) { + // Assume all channels are packed into a 32bit value + const uint8_t *byte_p = data[plane] + y * linesize[plane]; + uint32_t *p = (uint32_t *)byte_p; + int offset = comp.offset; + uint32_t mask = ((1ULL << depth) - 1) << offset; + + while (w--) { + uint16_t val = src_element_size == 4 ? *src32++ : *src16++; + AV_WB32(p, (AV_RB32(p) & ~mask) | (val << offset)); + p++; + } + } else { + int skip = x * step + comp.offset; + uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3); + int shift = 8 - depth - (skip & 7); + + while (w--) { + *p |= (src_element_size == 4 ? *src32++ : *src16++) << shift; + shift -= step; + p -= shift >> 3; + shift &= 7; + } + } + } else { + int shift = comp.shift; + uint8_t *p = data[plane] + y * linesize[plane] + + x * step + comp.offset; + + if (shift + depth <= 8) { + p += !!(flags & AV_PIX_FMT_FLAG_BE); + while (w--) { + *p |= ((src_element_size == 4 ? *src32++ : *src16++) << shift); + p += step; + } + } else { + while (w--) { + unsigned s = (src_element_size == 4 ? *src32++ : *src16++); + if (shift + depth <= 16) { + if (flags & AV_PIX_FMT_FLAG_BE) { + uint16_t val = AV_RB16(p) | (s << shift); + AV_WB16(p, val); + } else { + uint16_t val = AV_RL16(p) | (s << shift); + AV_WL16(p, val); + } + } else { + if (flags & AV_PIX_FMT_FLAG_BE) { + uint32_t val = AV_RB32(p) | (s << shift); + AV_WB32(p, val); + } else { + uint32_t val = AV_RL32(p) | (s << shift); + AV_WL32(p, val); + } + } + p += step; + } + } + } +} + +void av_write_image_line(const uint16_t *src, + uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w) +{ + av_write_image_line2(src, data, linesize, desc, x, y, c, w, 2); +} + +static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { + [AV_PIX_FMT_YUV420P] = { + .name = "yuv420p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUYV422] = { + .name = "yuyv422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 8 }, /* Y */ + { 0, 4, 1, 0, 8 }, /* U */ + { 0, 4, 3, 0, 8 }, /* V */ + }, + }, + [AV_PIX_FMT_YVYU422] = { + .name = "yvyu422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 8 }, /* Y */ + { 0, 4, 3, 0, 8 }, /* U */ + { 0, 4, 1, 0, 8 }, /* V */ + }, + }, + [AV_PIX_FMT_Y210LE] = { + .name = "y210le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 6, 10 }, /* Y */ + { 0, 8, 2, 6, 10 }, /* U */ + { 0, 8, 6, 6, 10 }, /* V */ + }, + }, + [AV_PIX_FMT_Y210BE] = { + .name = "y210be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 6, 10 }, /* Y */ + { 0, 8, 2, 6, 10 }, /* U */ + { 0, 8, 6, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_RGB24] = { + .name = "rgb24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 3, 0, 0, 8 }, /* R */ + { 0, 3, 1, 0, 8 }, /* G */ + { 0, 3, 2, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR24] = { + .name = "bgr24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 3, 2, 0, 8 }, /* R */ + { 0, 3, 1, 0, 8 }, /* G */ + { 0, 3, 0, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_X2RGB10LE] = { + .name = "x2rgb10le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 4, 10 }, /* R */ + { 0, 4, 1, 2, 10 }, /* G */ + { 0, 4, 0, 0, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_X2RGB10BE] = { + .name = "x2rgb10be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 4, 10 }, /* R */ + { 0, 4, 1, 2, 10 }, /* G */ + { 0, 4, 2, 0, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_X2BGR10LE] = { + .name = "x2bgr10le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 0, 10 }, /* R */ + { 0, 4, 1, 2, 10 }, /* G */ + { 0, 4, 2, 4, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_X2BGR10BE] = { + .name = "x2bgr10be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 0, 10 }, /* R */ + { 0, 4, 1, 2, 10 }, /* G */ + { 0, 4, 0, 4, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_YUV422P] = { + .name = "yuv422p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P] = { + .name = "yuv444p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV410P] = { + .name = "yuv410p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 2, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV411P] = { + .name = "yuv411p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ411P] = { + .name = "yuvj411p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_GRAY8] = { + .name = "gray", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + }, + .alias = "gray8,y8", + }, + [AV_PIX_FMT_MONOWHITE] = { + .name = "monow", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM, + }, + [AV_PIX_FMT_MONOBLACK] = { + .name = "monob", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 7, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM, + }, + [AV_PIX_FMT_PAL8] = { + .name = "pal8", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, + }, + .flags = AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVJ420P] = { + .name = "yuvj420p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ422P] = { + .name = "yuvj422p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ444P] = { + .name = "yuvj444p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, +#if FF_API_XVMC + [AV_PIX_FMT_XVMC] = { + .name = "xvmc", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, +#endif + [AV_PIX_FMT_UYVY422] = { + .name = "uyvy422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 0, 8 }, /* Y */ + { 0, 4, 0, 0, 8 }, /* U */ + { 0, 4, 2, 0, 8 }, /* V */ + }, + }, + [AV_PIX_FMT_UYYVYY411] = { + .name = "uyyvyy411", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 1, 0, 8 }, /* Y */ + { 0, 6, 0, 0, 8 }, /* U */ + { 0, 6, 3, 0, 8 }, /* V */ + }, + }, + [AV_PIX_FMT_BGR8] = { + .name = "bgr8", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 3 }, /* R */ + { 0, 1, 0, 3, 3 }, /* G */ + { 0, 1, 0, 6, 2 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR4] = { + .name = "bgr4", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 3, 0, 1 }, /* R */ + { 0, 4, 1, 0, 2 }, /* G */ + { 0, 4, 0, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR4_BYTE] = { + .name = "bgr4_byte", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 1 }, /* R */ + { 0, 1, 0, 1, 2 }, /* G */ + { 0, 1, 0, 3, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB8] = { + .name = "rgb8", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 6, 2 }, /* R */ + { 0, 1, 0, 3, 3 }, /* G */ + { 0, 1, 0, 0, 3 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB4] = { + .name = "rgb4", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 1 }, /* R */ + { 0, 4, 1, 0, 2 }, /* G */ + { 0, 4, 3, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB4_BYTE] = { + .name = "rgb4_byte", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 3, 1 }, /* R */ + { 0, 1, 0, 1, 2 }, /* G */ + { 0, 1, 0, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_NV12] = { + .name = "nv12", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 2, 0, 0, 8 }, /* U */ + { 1, 2, 1, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV21] = { + .name = "nv21", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 2, 1, 0, 8 }, /* U */ + { 1, 2, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_ARGB] = { + .name = "argb", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 1, 0, 8 }, /* R */ + { 0, 4, 2, 0, 8 }, /* G */ + { 0, 4, 3, 0, 8 }, /* B */ + { 0, 4, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGBA] = { + .name = "rgba", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 8 }, /* R */ + { 0, 4, 1, 0, 8 }, /* G */ + { 0, 4, 2, 0, 8 }, /* B */ + { 0, 4, 3, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_ABGR] = { + .name = "abgr", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 3, 0, 8 }, /* R */ + { 0, 4, 2, 0, 8 }, /* G */ + { 0, 4, 1, 0, 8 }, /* B */ + { 0, 4, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGRA] = { + .name = "bgra", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 2, 0, 8 }, /* R */ + { 0, 4, 1, 0, 8 }, /* G */ + { 0, 4, 0, 0, 8 }, /* B */ + { 0, 4, 3, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_0RGB] = { + .name = "0rgb", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 1, 0, 8 }, /* R */ + { 0, 4, 2, 0, 8 }, /* G */ + { 0, 4, 3, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB0] = { + .name = "rgb0", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 0, 8 }, /* R */ + { 0, 4, 1, 0, 8 }, /* G */ + { 0, 4, 2, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_0BGR] = { + .name = "0bgr", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 3, 0, 8 }, /* R */ + { 0, 4, 2, 0, 8 }, /* G */ + { 0, 4, 1, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR0] = { + .name = "bgr0", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 0, 8 }, /* R */ + { 0, 4, 1, 0, 8 }, /* G */ + { 0, 4, 0, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GRAY9BE] = { + .name = "gray9be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y9be", + }, + [AV_PIX_FMT_GRAY9LE] = { + .name = "gray9le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + }, + .alias = "y9le", + }, + [AV_PIX_FMT_GRAY10BE] = { + .name = "gray10be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y10be", + }, + [AV_PIX_FMT_GRAY10LE] = { + .name = "gray10le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + }, + .alias = "y10le", + }, + [AV_PIX_FMT_GRAY12BE] = { + .name = "gray12be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y12be", + }, + [AV_PIX_FMT_GRAY12LE] = { + .name = "gray12le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + }, + .alias = "y12le", + }, + [AV_PIX_FMT_GRAY14BE] = { + .name = "gray14be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y14be", + }, + [AV_PIX_FMT_GRAY14LE] = { + .name = "gray14le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + }, + .alias = "y14le", + }, + [AV_PIX_FMT_GRAY16BE] = { + .name = "gray16be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y16be", + }, + [AV_PIX_FMT_GRAY16LE] = { + .name = "gray16le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + }, + .alias = "y16le", + }, + [AV_PIX_FMT_YUV440P] = { + .name = "yuv440p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ440P] = { + .name = "yuvj440p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P10LE] = { + .name = "yuv440p10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P10BE] = { + .name = "yuv440p10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P12LE] = { + .name = "yuv440p12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P12BE] = { + .name = "yuv440p12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVA420P] = { + .name = "yuva420p", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + { 3, 1, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P] = { + .name = "yuva422p", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + { 3, 1, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P] = { + .name = "yuva444p", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 1, 0, 0, 8 }, /* U */ + { 2, 1, 0, 0, 8 }, /* V */ + { 3, 1, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P9BE] = { + .name = "yuva420p9be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P9LE] = { + .name = "yuva420p9le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P9BE] = { + .name = "yuva422p9be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P9LE] = { + .name = "yuva422p9le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P9BE] = { + .name = "yuva444p9be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P9LE] = { + .name = "yuva444p9le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + { 3, 2, 0, 0, 9 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P10BE] = { + .name = "yuva420p10be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P10LE] = { + .name = "yuva420p10le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P10BE] = { + .name = "yuva422p10be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P10LE] = { + .name = "yuva422p10le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P10BE] = { + .name = "yuva444p10be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P10LE] = { + .name = "yuva444p10le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P16BE] = { + .name = "yuva420p16be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P16LE] = { + .name = "yuva420p16le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P16BE] = { + .name = "yuva422p16be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P16LE] = { + .name = "yuva422p16le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P16BE] = { + .name = "yuva444p16be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P16LE] = { + .name = "yuva444p16le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGB48BE] = { + .name = "rgb48be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 0, 16 }, /* R */ + { 0, 6, 2, 0, 16 }, /* G */ + { 0, 6, 4, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_RGB48LE] = { + .name = "rgb48le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 0, 16 }, /* R */ + { 0, 6, 2, 0, 16 }, /* G */ + { 0, 6, 4, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGBA64BE] = { + .name = "rgba64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 4, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGBA64LE] = { + .name = "rgba64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 4, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGB565BE] = { + .name = "rgb565be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 3, 5 }, /* R */ + { 0, 2, 0, 5, 6 }, /* G */ + { 0, 2, 0, 0, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB565LE] = { + .name = "rgb565le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 3, 5 }, /* R */ + { 0, 2, 0, 5, 6 }, /* G */ + { 0, 2, 0, 0, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB555BE] = { + .name = "rgb555be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 2, 5 }, /* R */ + { 0, 2, 0, 5, 5 }, /* G */ + { 0, 2, 0, 0, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB555LE] = { + .name = "rgb555le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 2, 5 }, /* R */ + { 0, 2, 0, 5, 5 }, /* G */ + { 0, 2, 0, 0, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB444BE] = { + .name = "rgb444be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 0, 4 }, /* R */ + { 0, 2, 0, 4, 4 }, /* G */ + { 0, 2, 0, 0, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB444LE] = { + .name = "rgb444le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 0, 4 }, /* R */ + { 0, 2, 0, 4, 4 }, /* G */ + { 0, 2, 0, 0, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR48BE] = { + .name = "bgr48be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 4, 0, 16 }, /* R */ + { 0, 6, 2, 0, 16 }, /* G */ + { 0, 6, 0, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR48LE] = { + .name = "bgr48le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 4, 0, 16 }, /* R */ + { 0, 6, 2, 0, 16 }, /* G */ + { 0, 6, 0, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGRA64BE] = { + .name = "bgra64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 4, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 0, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGRA64LE] = { + .name = "bgra64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 4, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 0, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGR565BE] = { + .name = "bgr565be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5 }, /* R */ + { 0, 2, 0, 5, 6 }, /* G */ + { 0, 2, -1, 3, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR565LE] = { + .name = "bgr565le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5 }, /* R */ + { 0, 2, 0, 5, 6 }, /* G */ + { 0, 2, 1, 3, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR555BE] = { + .name = "bgr555be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5 }, /* R */ + { 0, 2, 0, 5, 5 }, /* G */ + { 0, 2, -1, 2, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR555LE] = { + .name = "bgr555le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5 }, /* R */ + { 0, 2, 0, 5, 5 }, /* G */ + { 0, 2, 1, 2, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR444BE] = { + .name = "bgr444be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 4 }, /* R */ + { 0, 2, 0, 4, 4 }, /* G */ + { 0, 2, -1, 0, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR444LE] = { + .name = "bgr444le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 4 }, /* R */ + { 0, 2, 0, 4, 4 }, /* G */ + { 0, 2, 1, 0, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_VAAPI] = { + .name = "vaapi", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_YUV420P9LE] = { + .name = "yuv420p9le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P9BE] = { + .name = "yuv420p9be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P10LE] = { + .name = "yuv420p10le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P10BE] = { + .name = "yuv420p10be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P12LE] = { + .name = "yuv420p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P12BE] = { + .name = "yuv420p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P14LE] = { + .name = "yuv420p14le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P14BE] = { + .name = "yuv420p14be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P16LE] = { + .name = "yuv420p16le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P16BE] = { + .name = "yuv420p16be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P9LE] = { + .name = "yuv422p9le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P9BE] = { + .name = "yuv422p9be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P10LE] = { + .name = "yuv422p10le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P10BE] = { + .name = "yuv422p10be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P12LE] = { + .name = "yuv422p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P12BE] = { + .name = "yuv422p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P14LE] = { + .name = "yuv422p14le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P14BE] = { + .name = "yuv422p14be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P16LE] = { + .name = "yuv422p16le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P16BE] = { + .name = "yuv422p16be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P16LE] = { + .name = "yuv444p16le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P16BE] = { + .name = "yuv444p16be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 2, 0, 0, 16 }, /* U */ + { 2, 2, 0, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P10LE] = { + .name = "yuv444p10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P10BE] = { + .name = "yuv444p10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 2, 0, 0, 10 }, /* U */ + { 2, 2, 0, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P9LE] = { + .name = "yuv444p9le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P9BE] = { + .name = "yuv444p9be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9 }, /* Y */ + { 1, 2, 0, 0, 9 }, /* U */ + { 2, 2, 0, 0, 9 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P12LE] = { + .name = "yuv444p12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P12BE] = { + .name = "yuv444p12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P14LE] = { + .name = "yuv444p14le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P14BE] = { + .name = "yuv444p14be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14 }, /* Y */ + { 1, 2, 0, 0, 14 }, /* U */ + { 2, 2, 0, 0, 14 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_D3D11VA_VLD] = { + .name = "d3d11va_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_DXVA2_VLD] = { + .name = "dxva2_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_YA8] = { + .name = "ya8", + .nb_components = 2, + .comp = { + { 0, 2, 0, 0, 8 }, /* Y */ + { 0, 2, 1, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + .alias = "gray8a", + }, + [AV_PIX_FMT_YA16LE] = { + .name = "ya16le", + .nb_components = 2, + .comp = { + { 0, 4, 0, 0, 16 }, /* Y */ + { 0, 4, 2, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YA16BE] = { + .name = "ya16be", + .nb_components = 2, + .comp = { + { 0, 4, 0, 0, 16 }, /* Y */ + { 0, 4, 2, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_VIDEOTOOLBOX] = { + .name = "videotoolbox_vld", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GBRP] = { + .name = "gbrp", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 1, 0, 0, 8 }, /* R */ + { 0, 1, 0, 0, 8 }, /* G */ + { 1, 1, 0, 0, 8 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP9LE] = { + .name = "gbrp9le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 9 }, /* R */ + { 0, 2, 0, 0, 9 }, /* G */ + { 1, 2, 0, 0, 9 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP9BE] = { + .name = "gbrp9be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 9 }, /* R */ + { 0, 2, 0, 0, 9 }, /* G */ + { 1, 2, 0, 0, 9 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP10LE] = { + .name = "gbrp10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10 }, /* R */ + { 0, 2, 0, 0, 10 }, /* G */ + { 1, 2, 0, 0, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP10BE] = { + .name = "gbrp10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10 }, /* R */ + { 0, 2, 0, 0, 10 }, /* G */ + { 1, 2, 0, 0, 10 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP12LE] = { + .name = "gbrp12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12 }, /* R */ + { 0, 2, 0, 0, 12 }, /* G */ + { 1, 2, 0, 0, 12 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP12BE] = { + .name = "gbrp12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12 }, /* R */ + { 0, 2, 0, 0, 12 }, /* G */ + { 1, 2, 0, 0, 12 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP14LE] = { + .name = "gbrp14le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 14 }, /* R */ + { 0, 2, 0, 0, 14 }, /* G */ + { 1, 2, 0, 0, 14 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP14BE] = { + .name = "gbrp14be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 14 }, /* R */ + { 0, 2, 0, 0, 14 }, /* G */ + { 1, 2, 0, 0, 14 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP16LE] = { + .name = "gbrp16le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16 }, /* R */ + { 0, 2, 0, 0, 16 }, /* G */ + { 1, 2, 0, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP16BE] = { + .name = "gbrp16be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16 }, /* R */ + { 0, 2, 0, 0, 16 }, /* G */ + { 1, 2, 0, 0, 16 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRAP] = { + .name = "gbrap", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 1, 0, 0, 8 }, /* R */ + { 0, 1, 0, 0, 8 }, /* G */ + { 1, 1, 0, 0, 8 }, /* B */ + { 3, 1, 0, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP16LE] = { + .name = "gbrap16le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16 }, /* R */ + { 0, 2, 0, 0, 16 }, /* G */ + { 1, 2, 0, 0, 16 }, /* B */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP16BE] = { + .name = "gbrap16be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16 }, /* R */ + { 0, 2, 0, 0, 16 }, /* G */ + { 1, 2, 0, 0, 16 }, /* B */ + { 3, 2, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_VDPAU] = { + .name = "vdpau", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_XYZ12LE] = { + .name = "xyz12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 4, 12 }, /* X */ + { 0, 6, 2, 4, 12 }, /* Y */ + { 0, 6, 4, 4, 12 }, /* Z */ + }, + /*.flags = -- not used*/ + }, + [AV_PIX_FMT_XYZ12BE] = { + .name = "xyz12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 4, 12 }, /* X */ + { 0, 6, 2, 4, 12 }, /* Y */ + { 0, 6, 4, 4, 12 }, /* Z */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + }, + +#define BAYER8_DESC_COMMON \ + .nb_components= 3, \ + .log2_chroma_w= 0, \ + .log2_chroma_h= 0, \ + .comp = { \ + { 0, 1, 0, 0, 2 }, \ + { 0, 1, 0, 0, 4 }, \ + { 0, 1, 0, 0, 2 }, \ + }, \ + +#define BAYER16_DESC_COMMON \ + .nb_components= 3, \ + .log2_chroma_w= 0, \ + .log2_chroma_h= 0, \ + .comp = { \ + { 0, 2, 0, 0, 4 }, \ + { 0, 2, 0, 0, 8 }, \ + { 0, 2, 0, 0, 4 }, \ + }, \ + + [AV_PIX_FMT_BAYER_BGGR8] = { + .name = "bayer_bggr8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_BGGR16LE] = { + .name = "bayer_bggr16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_BGGR16BE] = { + .name = "bayer_bggr16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB8] = { + .name = "bayer_rggb8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB16LE] = { + .name = "bayer_rggb16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB16BE] = { + .name = "bayer_rggb16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG8] = { + .name = "bayer_gbrg8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG16LE] = { + .name = "bayer_gbrg16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG16BE] = { + .name = "bayer_gbrg16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG8] = { + .name = "bayer_grbg8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG16LE] = { + .name = "bayer_grbg16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG16BE] = { + .name = "bayer_grbg16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_NV16] = { + .name = "nv16", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 2, 0, 0, 8 }, /* U */ + { 1, 2, 1, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV20LE] = { + .name = "nv20le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 4, 0, 0, 10 }, /* U */ + { 1, 4, 2, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV20BE] = { + .name = "nv20be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10 }, /* Y */ + { 1, 4, 0, 0, 10 }, /* U */ + { 1, 4, 2, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_QSV] = { + .name = "qsv", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_MEDIACODEC] = { + .name = "mediacodec", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_MMAL] = { + .name = "mmal", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_CUDA] = { + .name = "cuda", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_AYUV64LE] = { + .name = "ayuv64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 2, 0, 16 }, /* Y */ + { 0, 8, 4, 0, 16 }, /* U */ + { 0, 8, 6, 0, 16 }, /* V */ + { 0, 8, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_AYUV64BE] = { + .name = "ayuv64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 2, 0, 16 }, /* Y */ + { 0, 8, 4, 0, 16 }, /* U */ + { 0, 8, 6, 0, 16 }, /* V */ + { 0, 8, 0, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_P010LE] = { + .name = "p010le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P010BE] = { + .name = "p010be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P012LE] = { + .name = "p012le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 4, 12 }, /* Y */ + { 1, 4, 0, 4, 12 }, /* U */ + { 1, 4, 2, 4, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P012BE] = { + .name = "p012be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 4, 12 }, /* Y */ + { 1, 4, 0, 4, 12 }, /* U */ + { 1, 4, 2, 4, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P016LE] = { + .name = "p016le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P016BE] = { + .name = "p016be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_GBRAP12LE] = { + .name = "gbrap12le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12 }, /* R */ + { 0, 2, 0, 0, 12 }, /* G */ + { 1, 2, 0, 0, 12 }, /* B */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP12BE] = { + .name = "gbrap12be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12 }, /* R */ + { 0, 2, 0, 0, 12 }, /* G */ + { 1, 2, 0, 0, 12 }, /* B */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP10LE] = { + .name = "gbrap10le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10 }, /* R */ + { 0, 2, 0, 0, 10 }, /* G */ + { 1, 2, 0, 0, 10 }, /* B */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP10BE] = { + .name = "gbrap10be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10 }, /* R */ + { 0, 2, 0, 0, 10 }, /* G */ + { 1, 2, 0, 0, 10 }, /* B */ + { 3, 2, 0, 0, 10 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_D3D11] = { + .name = "d3d11", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GBRPF32BE] = { + .name = "gbrpf32be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32 }, /* R */ + { 0, 4, 0, 0, 32 }, /* G */ + { 1, 4, 0, 0, 32 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRPF32LE] = { + .name = "gbrpf32le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32 }, /* R */ + { 0, 4, 0, 0, 32 }, /* G */ + { 1, 4, 0, 0, 32 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRAPF32BE] = { + .name = "gbrapf32be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32 }, /* R */ + { 0, 4, 0, 0, 32 }, /* G */ + { 1, 4, 0, 0, 32 }, /* B */ + { 3, 4, 0, 0, 32 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRAPF32LE] = { + .name = "gbrapf32le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32 }, /* R */ + { 0, 4, 0, 0, 32 }, /* G */ + { 1, 4, 0, 0, 32 }, /* B */ + { 3, 4, 0, 0, 32 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_DRM_PRIME] = { + .name = "drm_prime", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_OPENCL] = { + .name = "opencl", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GRAYF32BE] = { + .name = "grayf32be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 32 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT, + .alias = "yf32be", + }, + [AV_PIX_FMT_GRAYF32LE] = { + .name = "grayf32le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 32 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_FLOAT, + .alias = "yf32le", + }, + [AV_PIX_FMT_YUVA422P12BE] = { + .name = "yuva422p12be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P12LE] = { + .name = "yuva422p12le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P12BE] = { + .name = "yuva444p12be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P12LE] = { + .name = "yuva444p12le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12 }, /* Y */ + { 1, 2, 0, 0, 12 }, /* U */ + { 2, 2, 0, 0, 12 }, /* V */ + { 3, 2, 0, 0, 12 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_NV24] = { + .name = "nv24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 2, 0, 0, 8 }, /* U */ + { 1, 2, 1, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV42] = { + .name = "nv42", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8 }, /* Y */ + { 1, 2, 1, 0, 8 }, /* U */ + { 1, 2, 0, 0, 8 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_VULKAN] = { + .name = "vulkan", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_P210BE] = { + .name = "p210be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P210LE] = { + .name = "p210le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P410BE] = { + .name = "p410be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P410LE] = { + .name = "p410le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 6, 10 }, /* Y */ + { 1, 4, 0, 6, 10 }, /* U */ + { 1, 4, 2, 6, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P216BE] = { + .name = "p216be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P216LE] = { + .name = "p216le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P416BE] = { + .name = "p416be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P416LE] = { + .name = "p416le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16 }, /* Y */ + { 1, 4, 0, 0, 16 }, /* U */ + { 1, 4, 2, 0, 16 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_VUYA] = { + .name = "vuya", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 2, 0, 8 }, /* Y */ + { 0, 4, 1, 0, 8 }, /* U */ + { 0, 4, 0, 0, 8 }, /* V */ + { 0, 4, 3, 0, 8 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_VUYX] = { + .name = "vuyx", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 2, 0, 8 }, /* Y */ + { 0, 4, 1, 0, 8 }, /* U */ + { 0, 4, 0, 0, 8 }, /* V */ + }, + }, + [AV_PIX_FMT_RGBAF16BE] = { + .name = "rgbaf16be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 4, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_RGBAF16LE] = { + .name = "rgbaf16le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16 }, /* R */ + { 0, 8, 2, 0, 16 }, /* G */ + { 0, 8, 4, 0, 16 }, /* B */ + { 0, 8, 6, 0, 16 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA | + AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_Y212LE] = { + .name = "y212le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 4, 12 }, /* Y */ + { 0, 8, 2, 4, 12 }, /* U */ + { 0, 8, 6, 4, 12 }, /* V */ + }, + }, + [AV_PIX_FMT_Y212BE] = { + .name = "y212be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 4, 12 }, /* Y */ + { 0, 8, 2, 4, 12 }, /* U */ + { 0, 8, 6, 4, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_XV30LE] = { + .name = "xv30le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 1, 2, 10 }, /* Y */ + { 0, 4, 0, 0, 10 }, /* U */ + { 0, 4, 2, 4, 10 }, /* V */ + }, + }, + [AV_PIX_FMT_XV30BE] = { + .name = "xv30be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 32, 10, 0, 10 }, /* Y */ + { 0, 32, 0, 0, 10 }, /* U */ + { 0, 32, 20, 0, 10 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_BITSTREAM, + }, + [AV_PIX_FMT_XV36LE] = { + .name = "xv36le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 8, 2, 4, 12 }, /* Y */ + { 0, 8, 0, 4, 12 }, /* U */ + { 0, 8, 4, 4, 12 }, /* V */ + }, + }, + [AV_PIX_FMT_XV36BE] = { + .name = "xv36be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 8, 2, 4, 12 }, /* Y */ + { 0, 8, 0, 4, 12 }, /* U */ + { 0, 8, 4, 4, 12 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_RGBF32BE] = { + .name = "rgbf32be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 12, 0, 0, 32 }, /* R */ + { 0, 12, 4, 0, 32 }, /* G */ + { 0, 12, 8, 0, 32 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_RGBF32LE] = { + .name = "rgbf32le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 12, 0, 0, 32 }, /* R */ + { 0, 12, 4, 0, 32 }, /* G */ + { 0, 12, 8, 0, 32 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_RGBAF32BE] = { + .name = "rgbaf32be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 16, 0, 0, 32 }, /* R */ + { 0, 16, 4, 0, 32 }, /* G */ + { 0, 16, 8, 0, 32 }, /* B */ + { 0, 16, 12, 0, 32 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGBAF32LE] = { + .name = "rgbaf32le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 16, 0, 0, 32 }, /* R */ + { 0, 16, 4, 0, 32 }, /* G */ + { 0, 16, 8, 0, 32 }, /* B */ + { 0, 16, 12, 0, 32 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT | + AV_PIX_FMT_FLAG_ALPHA, + }, +}; + +static const char * const color_range_names[] = { + [AVCOL_RANGE_UNSPECIFIED] = "unknown", + [AVCOL_RANGE_MPEG] = "tv", + [AVCOL_RANGE_JPEG] = "pc", +}; + +static const char * const color_primaries_names[AVCOL_PRI_NB] = { + [AVCOL_PRI_RESERVED0] = "reserved", + [AVCOL_PRI_BT709] = "bt709", + [AVCOL_PRI_UNSPECIFIED] = "unknown", + [AVCOL_PRI_RESERVED] = "reserved", + [AVCOL_PRI_BT470M] = "bt470m", + [AVCOL_PRI_BT470BG] = "bt470bg", + [AVCOL_PRI_SMPTE170M] = "smpte170m", + [AVCOL_PRI_SMPTE240M] = "smpte240m", + [AVCOL_PRI_FILM] = "film", + [AVCOL_PRI_BT2020] = "bt2020", + [AVCOL_PRI_SMPTE428] = "smpte428", + [AVCOL_PRI_SMPTE431] = "smpte431", + [AVCOL_PRI_SMPTE432] = "smpte432", + [AVCOL_PRI_EBU3213] = "ebu3213", +}; + +static const char * const color_transfer_names[] = { + [AVCOL_TRC_RESERVED0] = "reserved", + [AVCOL_TRC_BT709] = "bt709", + [AVCOL_TRC_UNSPECIFIED] = "unknown", + [AVCOL_TRC_RESERVED] = "reserved", + [AVCOL_TRC_GAMMA22] = "bt470m", + [AVCOL_TRC_GAMMA28] = "bt470bg", + [AVCOL_TRC_SMPTE170M] = "smpte170m", + [AVCOL_TRC_SMPTE240M] = "smpte240m", + [AVCOL_TRC_LINEAR] = "linear", + [AVCOL_TRC_LOG] = "log100", + [AVCOL_TRC_LOG_SQRT] = "log316", + [AVCOL_TRC_IEC61966_2_4] = "iec61966-2-4", + [AVCOL_TRC_BT1361_ECG] = "bt1361e", + [AVCOL_TRC_IEC61966_2_1] = "iec61966-2-1", + [AVCOL_TRC_BT2020_10] = "bt2020-10", + [AVCOL_TRC_BT2020_12] = "bt2020-12", + [AVCOL_TRC_SMPTE2084] = "smpte2084", + [AVCOL_TRC_SMPTE428] = "smpte428", + [AVCOL_TRC_ARIB_STD_B67] = "arib-std-b67", +}; + +static const char * const color_space_names[] = { + [AVCOL_SPC_RGB] = "gbr", + [AVCOL_SPC_BT709] = "bt709", + [AVCOL_SPC_UNSPECIFIED] = "unknown", + [AVCOL_SPC_RESERVED] = "reserved", + [AVCOL_SPC_FCC] = "fcc", + [AVCOL_SPC_BT470BG] = "bt470bg", + [AVCOL_SPC_SMPTE170M] = "smpte170m", + [AVCOL_SPC_SMPTE240M] = "smpte240m", + [AVCOL_SPC_YCGCO] = "ycgco", + [AVCOL_SPC_BT2020_NCL] = "bt2020nc", + [AVCOL_SPC_BT2020_CL] = "bt2020c", + [AVCOL_SPC_SMPTE2085] = "smpte2085", + [AVCOL_SPC_CHROMA_DERIVED_NCL] = "chroma-derived-nc", + [AVCOL_SPC_CHROMA_DERIVED_CL] = "chroma-derived-c", + [AVCOL_SPC_ICTCP] = "ictcp", +}; + +static const char * const chroma_location_names[] = { + [AVCHROMA_LOC_UNSPECIFIED] = "unspecified", + [AVCHROMA_LOC_LEFT] = "left", + [AVCHROMA_LOC_CENTER] = "center", + [AVCHROMA_LOC_TOPLEFT] = "topleft", + [AVCHROMA_LOC_TOP] = "top", + [AVCHROMA_LOC_BOTTOMLEFT] = "bottomleft", + [AVCHROMA_LOC_BOTTOM] = "bottom", +}; + +static enum AVPixelFormat get_pix_fmt_internal(const char *name) +{ + enum AVPixelFormat pix_fmt; + + for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) + if (av_pix_fmt_descriptors[pix_fmt].name && + (!strcmp(av_pix_fmt_descriptors[pix_fmt].name, name) || + av_match_name(name, av_pix_fmt_descriptors[pix_fmt].alias))) + return pix_fmt; + + return AV_PIX_FMT_NONE; +} + +const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt) +{ + return (unsigned)pix_fmt < AV_PIX_FMT_NB ? + av_pix_fmt_descriptors[pix_fmt].name : NULL; +} + +#if HAVE_BIGENDIAN +# define X_NE(be, le) be +#else +# define X_NE(be, le) le +#endif + +enum AVPixelFormat av_get_pix_fmt(const char *name) +{ + enum AVPixelFormat pix_fmt; + + if (!strcmp(name, "rgb32")) + name = X_NE("argb", "bgra"); + else if (!strcmp(name, "bgr32")) + name = X_NE("abgr", "rgba"); + + pix_fmt = get_pix_fmt_internal(name); + if (pix_fmt == AV_PIX_FMT_NONE) { + char name2[32]; + + snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le")); + pix_fmt = get_pix_fmt_internal(name2); + } + + return pix_fmt; +} + +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc) +{ + int c, bits = 0; + int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h; + + for (c = 0; c < pixdesc->nb_components; c++) { + int s = c == 1 || c == 2 ? 0 : log2_pixels; + bits += pixdesc->comp[c].depth << s; + } + + return bits >> log2_pixels; +} + +int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc) +{ + int c, bits = 0; + int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h; + int steps[4] = {0}; + + for (c = 0; c < pixdesc->nb_components; c++) { + const AVComponentDescriptor *comp = &pixdesc->comp[c]; + int s = c == 1 || c == 2 ? 0 : log2_pixels; + steps[comp->plane] = comp->step << s; + } + for (c = 0; c < 4; c++) + bits += steps[c]; + + if(!(pixdesc->flags & AV_PIX_FMT_FLAG_BITSTREAM)) + bits *= 8; + + return bits >> log2_pixels; +} + +char *av_get_pix_fmt_string(char *buf, int buf_size, + enum AVPixelFormat pix_fmt) +{ + /* print header */ + if (pix_fmt < 0) { + snprintf (buf, buf_size, "name" " nb_components" " nb_bits"); + } else { + const AVPixFmtDescriptor *pixdesc = &av_pix_fmt_descriptors[pix_fmt]; + snprintf(buf, buf_size, "%-11s %7d %10d", pixdesc->name, + pixdesc->nb_components, av_get_bits_per_pixel(pixdesc)); + } + + return buf; +} + +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt) +{ + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return NULL; + return &av_pix_fmt_descriptors[pix_fmt]; +} + +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev) +{ + if (!prev) + return &av_pix_fmt_descriptors[0]; + while (prev - av_pix_fmt_descriptors < FF_ARRAY_ELEMS(av_pix_fmt_descriptors) - 1) { + prev++; + if (prev->name) + return prev; + } + return NULL; +} + +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc) +{ + if (desc < av_pix_fmt_descriptors || + desc >= av_pix_fmt_descriptors + FF_ARRAY_ELEMS(av_pix_fmt_descriptors)) + return AV_PIX_FMT_NONE; + + return desc - av_pix_fmt_descriptors; +} + +int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, + int *h_shift, int *v_shift) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + if (!desc) + return AVERROR(ENOSYS); + *h_shift = desc->log2_chroma_w; + *v_shift = desc->log2_chroma_h; + + return 0; +} + +int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i, planes[4] = { 0 }, ret = 0; + + if (!desc) + return AVERROR(EINVAL); + + for (i = 0; i < desc->nb_components; i++) + planes[desc->comp[i].plane] = 1; + for (i = 0; i < FF_ARRAY_ELEMS(planes); i++) + ret += planes[i]; + return ret; +} + +enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + char name[16]; + int i; + + if (!desc || strlen(desc->name) < 2) + return AV_PIX_FMT_NONE; + av_strlcpy(name, desc->name, sizeof(name)); + i = strlen(name) - 2; + if (strcmp(name + i, "be") && strcmp(name + i, "le")) + return AV_PIX_FMT_NONE; + + name[i] ^= 'b' ^ 'l'; + + return get_pix_fmt_internal(name); +} + +#define FF_COLOR_NA -1 +#define FF_COLOR_RGB 0 /**< RGB color space */ +#define FF_COLOR_GRAY 1 /**< gray color space */ +#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ +#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ +#define FF_COLOR_XYZ 4 + +#define pixdesc_has_alpha(pixdesc) \ + ((pixdesc)->flags & AV_PIX_FMT_FLAG_ALPHA) + + +static int get_color_type(const AVPixFmtDescriptor *desc) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL) + return FF_COLOR_RGB; + + if(desc->nb_components == 1 || desc->nb_components == 2) + return FF_COLOR_GRAY; + + if (desc->name) { + if (av_strstart(desc->name, "yuvj", NULL)) + return FF_COLOR_YUV_JPEG; + + if (av_strstart(desc->name, "xyz", NULL)) + return FF_COLOR_XYZ; + } + + if(desc->flags & AV_PIX_FMT_FLAG_RGB) + return FF_COLOR_RGB; + + if(desc->nb_components == 0) + return FF_COLOR_NA; + + return FF_COLOR_YUV; +} + +static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i; + + if (!desc || !desc->nb_components) { + *min = *max = 0; + return AVERROR(EINVAL); + } + + *min = INT_MAX, *max = -INT_MAX; + for (i = 0; i < desc->nb_components; i++) { + *min = FFMIN(desc->comp[i].depth, *min); + *max = FFMAX(desc->comp[i].depth, *max); + } + return 0; +} + +static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + unsigned *lossp, unsigned consider) +{ + const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); + const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); + int src_color, dst_color; + int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; + int ret, loss, i, nb_components; + int score = INT_MAX - 1; + + if (!src_desc || !dst_desc) + return -4; + + if ((src_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) || + (dst_desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + if (dst_pix_fmt == src_pix_fmt) + return -1; + else + return -2; + } + + /* compute loss */ + *lossp = loss = 0; + + if (dst_pix_fmt == src_pix_fmt) + return INT_MAX; + + if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) + return -3; + if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) + return -3; + + src_color = get_color_type(src_desc); + dst_color = get_color_type(dst_desc); + if (dst_pix_fmt == AV_PIX_FMT_PAL8) + nb_components = FFMIN(src_desc->nb_components, 4); + else + nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); + + for (i = 0; i < nb_components; i++) { + int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : (dst_desc->comp[i].depth - 1); + int depth_delta = src_desc->comp[i].depth - 1 - depth_minus1; + if (depth_delta > 0 && (consider & FF_LOSS_DEPTH)) { + loss |= FF_LOSS_DEPTH; + score -= 65536 >> depth_minus1; + } else if (depth_delta < 0 && (consider & FF_LOSS_EXCESS_DEPTH)) { + // Favour formats where bit depth exactly matches. If all other + // scoring is equal, we'd rather use the bit depth that most closely + // matches the source. + loss |= FF_LOSS_EXCESS_DEPTH; + score += depth_delta; + } + } + + if (consider & FF_LOSS_RESOLUTION) { + if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { + loss |= FF_LOSS_RESOLUTION; + score -= 256 << dst_desc->log2_chroma_w; + } + if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) { + loss |= FF_LOSS_RESOLUTION; + score -= 256 << dst_desc->log2_chroma_h; + } + // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side + if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && + dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { + score += 512; + } + } + + if (consider & FF_LOSS_EXCESS_RESOLUTION) { + // Favour formats where chroma subsampling exactly matches. If all other + // scoring is equal, we'd rather use the subsampling that most closely + // matches the source. + if (dst_desc->log2_chroma_w < src_desc->log2_chroma_w) { + loss |= FF_LOSS_EXCESS_RESOLUTION; + score -= 1 << (src_desc->log2_chroma_w - dst_desc->log2_chroma_w); + } + + if (dst_desc->log2_chroma_h < src_desc->log2_chroma_h) { + loss |= FF_LOSS_EXCESS_RESOLUTION; + score -= 1 << (src_desc->log2_chroma_h - dst_desc->log2_chroma_h); + } + + // don't favour 411 over 420, because 420 has much better support on the + // decoder side. + if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 2 && + dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 2) { + score += 4; + } + } + + if(consider & FF_LOSS_COLORSPACE) + switch(dst_color) { + case FF_COLOR_RGB: + if (src_color != FF_COLOR_RGB && + src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_GRAY: + if (src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV: + if (src_color != FF_COLOR_YUV) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV_JPEG: + if (src_color != FF_COLOR_YUV_JPEG && + src_color != FF_COLOR_YUV && + src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + default: + /* fail safe test */ + if (src_color != dst_color) + loss |= FF_LOSS_COLORSPACE; + break; + } + if(loss & FF_LOSS_COLORSPACE) + score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth - 1, src_desc->comp[0].depth - 1); + + if (dst_color == FF_COLOR_GRAY && + src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) { + loss |= FF_LOSS_CHROMA; + score -= 2 * 65536; + } + if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) { + loss |= FF_LOSS_ALPHA; + score -= 65536; + } + if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) && + (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) { + loss |= FF_LOSS_COLORQUANT; + score -= 65536; + } + + *lossp = loss; + return score; +} + +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha) +{ + int loss; + int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA); + if (ret < 0) + return ret; + return loss; +} + +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +{ + enum AVPixelFormat dst_pix_fmt; + int loss1, loss2, loss_mask; + const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1); + const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); + int score1, score2; + + if (!desc1) { + dst_pix_fmt = dst_pix_fmt2; + } else if (!desc2) { + dst_pix_fmt = dst_pix_fmt1; + } else { + loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ + if(!has_alpha) + loss_mask &= ~FF_LOSS_ALPHA; + + score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); + score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); + + if (score1 == score2) { + if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { + dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; + } else { + dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; + } + } else { + dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; + } + } + + if (loss_ptr) + *loss_ptr = av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); + return dst_pix_fmt; +} + +const char *av_color_range_name(enum AVColorRange range) +{ + return (unsigned) range < AVCOL_RANGE_NB ? + color_range_names[range] : NULL; +} + +int av_color_range_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) { + if (av_strstart(name, color_range_names[i], NULL)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_primaries_name(enum AVColorPrimaries primaries) +{ + return (unsigned) primaries < AVCOL_PRI_NB ? + color_primaries_names[primaries] : NULL; +} + +int av_color_primaries_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) { + if (!color_primaries_names[i]) + continue; + + if (av_strstart(name, color_primaries_names[i], NULL)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer) +{ + return (unsigned) transfer < AVCOL_TRC_NB ? + color_transfer_names[transfer] : NULL; +} + +int av_color_transfer_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) { + if (!color_transfer_names[i]) + continue; + + if (av_strstart(name, color_transfer_names[i], NULL)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_space_name(enum AVColorSpace space) +{ + return (unsigned) space < AVCOL_SPC_NB ? + color_space_names[space] : NULL; +} + +int av_color_space_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) { + if (!color_space_names[i]) + continue; + + if (av_strstart(name, color_space_names[i], NULL)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_chroma_location_name(enum AVChromaLocation location) +{ + return (unsigned) location < AVCHROMA_LOC_NB ? + chroma_location_names[location] : NULL; +} + +int av_chroma_location_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) { + if (!chroma_location_names[i]) + continue; + + if (av_strstart(name, chroma_location_names[i], NULL)) + return i; + } + + return AVERROR(EINVAL); +} + +int av_chroma_location_enum_to_pos(int *xpos, int *ypos, enum AVChromaLocation pos) +{ + if (pos <= AVCHROMA_LOC_UNSPECIFIED || pos >= AVCHROMA_LOC_NB) + return AVERROR(EINVAL); + pos--; + + *xpos = (pos&1) * 128; + *ypos = ((pos>>1)^(pos<4)) * 128; + + return 0; +} + +enum AVChromaLocation av_chroma_location_pos_to_enum(int xpos, int ypos) +{ + int pos, xout, yout; + + for (pos = AVCHROMA_LOC_UNSPECIFIED + 1; pos < AVCHROMA_LOC_NB; pos++) { + if (av_chroma_location_enum_to_pos(&xout, &yout, pos) == 0 && xout == xpos && yout == ypos) + return pos; + } + return AVCHROMA_LOC_UNSPECIFIED; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.h b/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.h new file mode 100644 index 00000000..0df73e6e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/pixdesc.h @@ -0,0 +1,435 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXDESC_H +#define AVUTIL_PIXDESC_H + +#include + +#include "attributes.h" +#include "pixfmt.h" + +typedef struct AVComponentDescriptor { + /** + * Which of the 4 planes contains the component. + */ + int plane; + + /** + * Number of elements between 2 horizontally consecutive pixels. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int step; + + /** + * Number of elements before the component of the first pixel. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int offset; + + /** + * Number of least significant bits that must be shifted away + * to get the value. + */ + int shift; + + /** + * Number of bits in the component. + */ + int depth; +} AVComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct AVPixFmtDescriptor { + const char *name; + uint8_t nb_components; ///< The number of components each pixel has, (1-4) + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = AV_CEIL_RSHIFT(luma_width, log2_chroma_w) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_w; + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= AV_CEIL_RSHIFT(luma_height, log2_chroma_h) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_h; + + /** + * Combination of AV_PIX_FMT_FLAG_... flags. + */ + uint64_t flags; + + /** + * Parameters that describe how pixels are packed. + * If the format has 1 or 2 components, then luma is 0. + * If the format has 3 or 4 components: + * if the RGB flag is set then 0 is red, 1 is green and 2 is blue; + * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V. + * + * If present, the Alpha channel is always the last component. + */ + AVComponentDescriptor comp[4]; + + /** + * Alternative comma-separated names. + */ + const char *alias; +} AVPixFmtDescriptor; + +/** + * Pixel format is big-endian. + */ +#define AV_PIX_FMT_FLAG_BE (1 << 0) +/** + * Pixel format has a palette in data[1], values are indexes in this palette. + */ +#define AV_PIX_FMT_FLAG_PAL (1 << 1) +/** + * All values of a component are bit-wise packed end to end. + */ +#define AV_PIX_FMT_FLAG_BITSTREAM (1 << 2) +/** + * Pixel format is an HW accelerated format. + */ +#define AV_PIX_FMT_FLAG_HWACCEL (1 << 3) +/** + * At least one pixel component is not in the first data plane. + */ +#define AV_PIX_FMT_FLAG_PLANAR (1 << 4) +/** + * The pixel format contains RGB-like data (as opposed to YUV/grayscale). + */ +#define AV_PIX_FMT_FLAG_RGB (1 << 5) + +/** + * The pixel format has an alpha channel. This is set on all formats that + * support alpha in some way, including AV_PIX_FMT_PAL8. The alpha is always + * straight, never pre-multiplied. + * + * If a codec or a filter does not support alpha, it should set all alpha to + * opaque, or use the equivalent pixel formats without alpha component, e.g. + * AV_PIX_FMT_RGB0 (or AV_PIX_FMT_RGB24 etc.) instead of AV_PIX_FMT_RGBA. + */ +#define AV_PIX_FMT_FLAG_ALPHA (1 << 7) + +/** + * The pixel format is following a Bayer pattern + */ +#define AV_PIX_FMT_FLAG_BAYER (1 << 8) + +/** + * The pixel format contains IEEE-754 floating point values. Precision (double, + * single, or half) should be determined by the pixel size (64, 32, or 16 bits). + */ +#define AV_PIX_FMT_FLAG_FLOAT (1 << 9) + +/** + * Return the number of bits per pixel used by the pixel format + * described by pixdesc. Note that this is not the same as the number + * of bits per sample. + * + * The returned number of bits refers to the number of bits actually + * used for storing the pixel information, that is padding bits are + * not counted. + */ +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * Return the number of bits per pixel for the pixel format + * described by pixdesc, including any padding or unused bits. + */ +int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * @return a pixel format descriptor for provided pixel format or NULL if + * this pixel format is unknown. + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt); + +/** + * Iterate over all pixel format descriptors known to libavutil. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev); + +/** + * @return an AVPixelFormat id described by desc, or AV_PIX_FMT_NONE if desc + * is not a valid pointer to a pixel format descriptor. + */ +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); + +/** + * Utility function to access log2_chroma_w log2_chroma_h from + * the pixel format AVPixFmtDescriptor. + * + * @param[in] pix_fmt the pixel format + * @param[out] h_shift store log2_chroma_w (horizontal/width shift) + * @param[out] v_shift store log2_chroma_h (vertical/height shift) + * + * @return 0 on success, AVERROR(ENOSYS) on invalid or unknown pixel format + */ +int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, + int *h_shift, int *v_shift); + +/** + * @return number of planes in pix_fmt, a negative AVERROR if pix_fmt is not a + * valid pixel format. + */ +int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt); + +/** + * @return the name for provided color range or NULL if unknown. + */ +const char *av_color_range_name(enum AVColorRange range); + +/** + * @return the AVColorRange value for name or an AVError if not found. + */ +int av_color_range_from_name(const char *name); + +/** + * @return the name for provided color primaries or NULL if unknown. + */ +const char *av_color_primaries_name(enum AVColorPrimaries primaries); + +/** + * @return the AVColorPrimaries value for name or an AVError if not found. + */ +int av_color_primaries_from_name(const char *name); + +/** + * @return the name for provided color transfer or NULL if unknown. + */ +const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer); + +/** + * @return the AVColorTransferCharacteristic value for name or an AVError if not found. + */ +int av_color_transfer_from_name(const char *name); + +/** + * @return the name for provided color space or NULL if unknown. + */ +const char *av_color_space_name(enum AVColorSpace space); + +/** + * @return the AVColorSpace value for name or an AVError if not found. + */ +int av_color_space_from_name(const char *name); + +/** + * @return the name for provided chroma location or NULL if unknown. + */ +const char *av_chroma_location_name(enum AVChromaLocation location); + +/** + * @return the AVChromaLocation value for name or an AVError if not found. + */ +int av_chroma_location_from_name(const char *name); + +/** + * Converts AVChromaLocation to swscale x/y chroma position. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +int av_chroma_location_enum_to_pos(int *xpos, int *ypos, enum AVChromaLocation pos); + +/** + * Converts swscale x/y chroma position to AVChromaLocation. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +enum AVChromaLocation av_chroma_location_pos_to_enum(int xpos, int ypos); + +/** + * Return the pixel format corresponding to name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns AV_PIX_FMT_NONE. + */ +enum AVPixelFormat av_get_pix_fmt(const char *name); + +/** + * Return the short name for a pixel format, NULL in case pix_fmt is + * unknown. + * + * @see av_get_pix_fmt(), av_get_pix_fmt_string() + */ +const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt); + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or a header if pix_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param pix_fmt the number of the pixel format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + */ +char *av_get_pix_fmt_string(char *buf, int buf_size, + enum AVPixelFormat pix_fmt); + +/** + * Read a line from an image, and write the values of the + * pixel format component c to dst. + * + * @param data the array containing the pointers to the planes of the image + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to read + * @param y the vertical coordinate of the first pixel to read + * @param w the width of the line to read, that is the number of + * values to write to dst + * @param read_pal_component if not zero and the format is a paletted + * format writes the values corresponding to the palette + * component c in data[1] to dst, rather than the palette indexes in + * data[0]. The behavior is undefined if the format is not paletted. + * @param dst_element_size size of elements in dst array (2 or 4 byte) + */ +void av_read_image_line2(void *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component, + int dst_element_size); + +void av_read_image_line(uint16_t *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component); + +/** + * Write the values from src to the pixel format component c of an + * image line. + * + * @param src array containing the values to write + * @param data the array containing the pointers to the planes of the + * image to write into. It is supposed to be zeroed. + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to write + * @param y the vertical coordinate of the first pixel to write + * @param w the width of the line to write, that is the number of + * values to write to the image line + * @param src_element_size size of elements in src array (2 or 4 byte) + */ +void av_write_image_line2(const void *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size); + +void av_write_image_line(const uint16_t *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w); + +/** + * Utility function to swap the endianness of a pixel format. + * + * @param[in] pix_fmt the pixel format + * + * @return pixel format with swapped endianness if it exists, + * otherwise AV_PIX_FMT_NONE + */ +enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ +#define FF_LOSS_EXCESS_RESOLUTION 0x0040 /**< loss due to unneeded extra resolution */ +#define FF_LOSS_EXCESS_DEPTH 0x0080 /**< loss due to unneeded extra color depth */ + + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha); + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +#endif /* AVUTIL_PIXDESC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.c b/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.c new file mode 100644 index 00000000..820889a1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.c @@ -0,0 +1,95 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "pixelutils.h" + +#if CONFIG_PIXELUTILS +#include +#include + +#include "attributes.h" +#include "macros.h" + +#include "x86/pixelutils.h" + +static av_always_inline int sad_wxh(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2, + int w, int h) +{ + int x, y, sum = 0; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + sum += abs(src1[x] - src2[x]); + src1 += stride1; + src2 += stride2; + } + return sum; +} + +#define DECLARE_BLOCK_FUNCTIONS(size) \ +static int block_sad_##size##x##size##_c(const uint8_t *src1, ptrdiff_t stride1, \ + const uint8_t *src2, ptrdiff_t stride2) \ +{ \ + return sad_wxh(src1, stride1, src2, stride2, size, size); \ +} + +DECLARE_BLOCK_FUNCTIONS(2) +DECLARE_BLOCK_FUNCTIONS(4) +DECLARE_BLOCK_FUNCTIONS(8) +DECLARE_BLOCK_FUNCTIONS(16) +DECLARE_BLOCK_FUNCTIONS(32) + +static const av_pixelutils_sad_fn sad_c[] = { + block_sad_2x2_c, + block_sad_4x4_c, + block_sad_8x8_c, + block_sad_16x16_c, + block_sad_32x32_c, +}; +#else +#include "log.h" +#endif /* CONFIG_PIXELUTILS */ + +av_pixelutils_sad_fn av_pixelutils_get_sad_fn(int w_bits, int h_bits, int aligned, void *log_ctx) +{ +#if !CONFIG_PIXELUTILS + av_log(log_ctx, AV_LOG_ERROR, "pixelutils support is required " + "but libavutil is not compiled with it\n"); + return NULL; +#else + av_pixelutils_sad_fn sad[FF_ARRAY_ELEMS(sad_c)]; + + memcpy(sad, sad_c, sizeof(sad)); + + if (w_bits < 1 || w_bits > FF_ARRAY_ELEMS(sad) || + h_bits < 1 || h_bits > FF_ARRAY_ELEMS(sad)) + return NULL; + if (w_bits != h_bits) // only squared sad for now + return NULL; + +#if ARCH_X86 + ff_pixelutils_sad_init_x86(sad, aligned); +#endif + + return sad[w_bits - 1]; +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.h b/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.h new file mode 100644 index 00000000..7a997cde --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/pixelutils.h @@ -0,0 +1,51 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXELUTILS_H +#define AVUTIL_PIXELUTILS_H + +#include +#include + +/** + * Sum of abs(src1[x] - src2[x]) + */ +typedef int (*av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +/** + * Get a potentially optimized pointer to a Sum-of-absolute-differences + * function (see the av_pixelutils_sad_fn prototype). + * + * @param w_bits 1< + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file + * pixel format definitions + */ + +#include "libavutil/avconfig.h" +#include "version.h" + +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 + +/** + * Pixel format. + * + * @note + * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little-endian CPU architectures and ARGB on + * big-endian CPUs. + * + * @note + * If the resolution is not a multiple of the chroma subsampling factor + * then the chroma plane resolution must be rounded up. + * + * @par + * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB32 palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + * + * @par + * For all the 8 bits per pixel formats, an RGB32 palette is in data[1] like + * for pal8. This palette is filled in automatically by the function + * allocating the picture. + */ +enum AVPixelFormat { + AV_PIX_FMT_NONE = -1, + AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + AV_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + AV_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + AV_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + AV_PIX_FMT_GRAY8, ///< Y , 8bpp + AV_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette + AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range + AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range + AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range + AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + AV_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + AV_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + AV_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + AV_PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... + AV_PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... + AV_PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... + AV_PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + + AV_PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + AV_PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range + AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian + + AV_PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian + AV_PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian + AV_PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined + + AV_PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian + AV_PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian + AV_PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined + + /** + * Hardware acceleration through VA-API, data[3] contains a + * VASurfaceID. + */ + AV_PIX_FMT_VAAPI, + + AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer + + AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_YA8, ///< 8 bits gray, 8 bits alpha + + AV_PIX_FMT_Y400A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + AV_PIX_FMT_GRAY8A= AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + + AV_PIX_FMT_BGR48BE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_BGR48LE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian + + /** + * The following 12 formats have the disadvantage of needing 1 format for each bit depth. + * Notice that each 9/10 bits sample is stored in 16 bits with extra padding. + * If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately is better. + */ + AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp + AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP + AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian + AV_PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little-endian + AV_PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big-endian + AV_PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little-endian + AV_PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little-endian + AV_PIX_FMT_YUVA422P, ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples) + AV_PIX_FMT_YUVA444P, ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples) + AV_PIX_FMT_YUVA420P9BE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian + AV_PIX_FMT_YUVA420P9LE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian + AV_PIX_FMT_YUVA422P9BE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA422P9LE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA444P9BE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA444P9LE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + + AV_PIX_FMT_VDPAU, ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface + + AV_PIX_FMT_XYZ12LE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_XYZ12BE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_NV16, ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_NV20LE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_NV20BE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + + AV_PIX_FMT_RGBA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + AV_PIX_FMT_BGRA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_BGRA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + + AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb + + AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) + AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) + + AV_PIX_FMT_GBRAP, ///< planar GBRA 4:4:4:4 32bpp + AV_PIX_FMT_GBRAP16BE, ///< planar GBRA 4:4:4:4 64bpp, big-endian + AV_PIX_FMT_GBRAP16LE, ///< planar GBRA 4:4:4:4 64bpp, little-endian + /** + * HW acceleration through QSV, data[3] contains a pointer to the + * mfxFrameSurface1 structure. + * + * Before FFmpeg 5.0: + * mfxFrameSurface1.Data.MemId contains a pointer when importing + * the following frames as QSV frames: + * + * VAAPI: + * mfxFrameSurface1.Data.MemId contains a pointer to VASurfaceID + * + * DXVA2: + * mfxFrameSurface1.Data.MemId contains a pointer to IDirect3DSurface9 + * + * FFmpeg 5.0 and above: + * mfxFrameSurface1.Data.MemId contains a pointer to the mfxHDLPair + * structure when importing the following frames as QSV frames: + * + * VAAPI: + * mfxHDLPair.first contains a VASurfaceID pointer. + * mfxHDLPair.second is always MFX_INFINITE. + * + * DXVA2: + * mfxHDLPair.first contains IDirect3DSurface9 pointer. + * mfxHDLPair.second is always MFX_INFINITE. + * + * D3D11: + * mfxHDLPair.first contains a ID3D11Texture2D pointer. + * mfxHDLPair.second contains the texture array index of the frame if the + * ID3D11Texture2D is an array texture, or always MFX_INFINITE if it is a + * normal texture. + */ + AV_PIX_FMT_QSV, + /** + * HW acceleration though MMAL, data[3] contains a pointer to the + * MMAL_BUFFER_HEADER_T structure. + */ + AV_PIX_FMT_MMAL, + + AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer + + /** + * HW acceleration through CUDA. data[i] contain CUdeviceptr pointers + * exactly as for system memory frames. + */ + AV_PIX_FMT_CUDA, + + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined + AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined + AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined + + AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian + AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian + AV_PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big-endian + AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian + AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range + + AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples + AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples + AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples + AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples + AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian + +#if FF_API_XVMC + AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing +#endif + + AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_AYUV64LE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_AYUV64BE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + + AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox + + AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian + AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian + + AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian + + AV_PIX_FMT_GBRAP10BE, ///< planar GBR 4:4:4:4 40bpp, big-endian + AV_PIX_FMT_GBRAP10LE, ///< planar GBR 4:4:4:4 40bpp, little-endian + + AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec + + AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian + AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian + AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian + AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian + + AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian + AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian + + /** + * Hardware surfaces for Direct3D11. + * + * This is preferred over the legacy AV_PIX_FMT_D3D11VA_VLD. The new D3D11 + * hwaccel API and filtering support AV_PIX_FMT_D3D11 only. + * + * data[0] contains a ID3D11Texture2D pointer, and data[1] contains the + * texture array index of the frame as intptr_t if the ID3D11Texture2D is + * an array texture (or always 0 if it's a normal texture). + */ + AV_PIX_FMT_D3D11, + + AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian + AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian + + AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian + AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian + AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian + AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian + + /** + * DRM-managed buffers exposed through PRIME buffer sharing. + * + * data[0] points to an AVDRMFrameDescriptor. + */ + AV_PIX_FMT_DRM_PRIME, + /** + * Hardware surfaces for OpenCL. + * + * data[i] contain 2D image objects (typed in C as cl_mem, used + * in OpenCL as image2d_t) for each plane of the surface. + */ + AV_PIX_FMT_OPENCL, + + AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian + AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian + + AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian + AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian + + AV_PIX_FMT_YUVA422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, little-endian + AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian + + AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped + + /** + * Vulkan hardware images. + * + * data[0] points to an AVVkFrame + */ + AV_PIX_FMT_VULKAN, + + AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian + AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian + + AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_X2BGR10LE, ///< packed BGR 10:10:10, 30bpp, (msb)2X 10B 10G 10R(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_X2BGR10BE, ///< packed BGR 10:10:10, 30bpp, (msb)2X 10B 10G 10R(lsb), big-endian, X=unused/undefined + + AV_PIX_FMT_P210BE, ///< interleaved chroma YUV 4:2:2, 20bpp, data in the high bits, big-endian + AV_PIX_FMT_P210LE, ///< interleaved chroma YUV 4:2:2, 20bpp, data in the high bits, little-endian + + AV_PIX_FMT_P410BE, ///< interleaved chroma YUV 4:4:4, 30bpp, data in the high bits, big-endian + AV_PIX_FMT_P410LE, ///< interleaved chroma YUV 4:4:4, 30bpp, data in the high bits, little-endian + + AV_PIX_FMT_P216BE, ///< interleaved chroma YUV 4:2:2, 32bpp, big-endian + AV_PIX_FMT_P216LE, ///< interleaved chroma YUV 4:2:2, 32bpp, little-endian + + AV_PIX_FMT_P416BE, ///< interleaved chroma YUV 4:4:4, 48bpp, big-endian + AV_PIX_FMT_P416LE, ///< interleaved chroma YUV 4:4:4, 48bpp, little-endian + + AV_PIX_FMT_VUYA, ///< packed VUYA 4:4:4, 32bpp, VUYAVUYA... + + AV_PIX_FMT_RGBAF16BE, ///< IEEE-754 half precision packed RGBA 16:16:16:16, 64bpp, RGBARGBA..., big-endian + AV_PIX_FMT_RGBAF16LE, ///< IEEE-754 half precision packed RGBA 16:16:16:16, 64bpp, RGBARGBA..., little-endian + + AV_PIX_FMT_VUYX, ///< packed VUYX 4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined + + AV_PIX_FMT_P012LE, ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, little-endian + AV_PIX_FMT_P012BE, ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, big-endian + + AV_PIX_FMT_Y212BE, ///< packed YUV 4:2:2 like YUYV422, 24bpp, data in the high bits, zeros in the low bits, big-endian + AV_PIX_FMT_Y212LE, ///< packed YUV 4:2:2 like YUYV422, 24bpp, data in the high bits, zeros in the low bits, little-endian + + AV_PIX_FMT_XV30BE, ///< packed XVYU 4:4:4, 32bpp, (msb)2X 10V 10Y 10U(lsb), big-endian, variant of Y410 where alpha channel is left undefined + AV_PIX_FMT_XV30LE, ///< packed XVYU 4:4:4, 32bpp, (msb)2X 10V 10Y 10U(lsb), little-endian, variant of Y410 where alpha channel is left undefined + + AV_PIX_FMT_XV36BE, ///< packed XVYU 4:4:4, 48bpp, data in the high bits, zeros in the low bits, big-endian, variant of Y412 where alpha channel is left undefined + AV_PIX_FMT_XV36LE, ///< packed XVYU 4:4:4, 48bpp, data in the high bits, zeros in the low bits, little-endian, variant of Y412 where alpha channel is left undefined + + AV_PIX_FMT_RGBF32BE, ///< IEEE-754 single precision packed RGB 32:32:32, 96bpp, RGBRGB..., big-endian + AV_PIX_FMT_RGBF32LE, ///< IEEE-754 single precision packed RGB 32:32:32, 96bpp, RGBRGB..., little-endian + + AV_PIX_FMT_RGBAF32BE, ///< IEEE-754 single precision packed RGBA 32:32:32:32, 128bpp, RGBARGBA..., big-endian + AV_PIX_FMT_RGBAF32LE, ///< IEEE-754 single precision packed RGBA 32:32:32:32, 128bpp, RGBARGBA..., little-endian + + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#if AV_HAVE_BIGENDIAN +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be +#else +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le +#endif + +#define AV_PIX_FMT_RGB32 AV_PIX_FMT_NE(ARGB, BGRA) +#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR) +#define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) +#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) +#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) +#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) + +#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) +#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) +#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) +#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) +#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) +#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) +#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) +#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) +#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE) +#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE) +#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE) +#define AV_PIX_FMT_BGR48 AV_PIX_FMT_NE(BGR48BE, BGR48LE) +#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE) +#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE) +#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE) +#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE) + +#define AV_PIX_FMT_YUV420P9 AV_PIX_FMT_NE(YUV420P9BE , YUV420P9LE) +#define AV_PIX_FMT_YUV422P9 AV_PIX_FMT_NE(YUV422P9BE , YUV422P9LE) +#define AV_PIX_FMT_YUV444P9 AV_PIX_FMT_NE(YUV444P9BE , YUV444P9LE) +#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) +#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) +#define AV_PIX_FMT_YUV440P10 AV_PIX_FMT_NE(YUV440P10BE, YUV440P10LE) +#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) +#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) +#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) +#define AV_PIX_FMT_YUV440P12 AV_PIX_FMT_NE(YUV440P12BE, YUV440P12LE) +#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) +#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE) +#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE) +#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE) +#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) +#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) +#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) + +#define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE , GBRP9LE) +#define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) +#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) +#define AV_PIX_FMT_GBRP14 AV_PIX_FMT_NE(GBRP14BE, GBRP14LE) +#define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) +#define AV_PIX_FMT_GBRAP10 AV_PIX_FMT_NE(GBRAP10BE, GBRAP10LE) +#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) +#define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) + +#define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) +#define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) +#define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) +#define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) + +#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) +#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) + +#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) + +#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) +#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) +#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) +#define AV_PIX_FMT_YUVA420P10 AV_PIX_FMT_NE(YUVA420P10BE, YUVA420P10LE) +#define AV_PIX_FMT_YUVA422P10 AV_PIX_FMT_NE(YUVA422P10BE, YUVA422P10LE) +#define AV_PIX_FMT_YUVA444P10 AV_PIX_FMT_NE(YUVA444P10BE, YUVA444P10LE) +#define AV_PIX_FMT_YUVA422P12 AV_PIX_FMT_NE(YUVA422P12BE, YUVA422P12LE) +#define AV_PIX_FMT_YUVA444P12 AV_PIX_FMT_NE(YUVA444P12BE, YUVA444P12LE) +#define AV_PIX_FMT_YUVA420P16 AV_PIX_FMT_NE(YUVA420P16BE, YUVA420P16LE) +#define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE) +#define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) + +#define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) +#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) +#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) +#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) +#define AV_PIX_FMT_P012 AV_PIX_FMT_NE(P012BE, P012LE) +#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) + +#define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) +#define AV_PIX_FMT_Y212 AV_PIX_FMT_NE(Y212BE, Y212LE) +#define AV_PIX_FMT_XV30 AV_PIX_FMT_NE(XV30BE, XV30LE) +#define AV_PIX_FMT_XV36 AV_PIX_FMT_NE(XV36BE, XV36LE) +#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) +#define AV_PIX_FMT_X2BGR10 AV_PIX_FMT_NE(X2BGR10BE, X2BGR10LE) + +#define AV_PIX_FMT_P210 AV_PIX_FMT_NE(P210BE, P210LE) +#define AV_PIX_FMT_P410 AV_PIX_FMT_NE(P410BE, P410LE) +#define AV_PIX_FMT_P216 AV_PIX_FMT_NE(P216BE, P216LE) +#define AV_PIX_FMT_P416 AV_PIX_FMT_NE(P416BE, P416LE) + +#define AV_PIX_FMT_RGBAF16 AV_PIX_FMT_NE(RGBAF16BE, RGBAF16LE) + +#define AV_PIX_FMT_RGBF32 AV_PIX_FMT_NE(RGBF32BE, RGBF32LE) +#define AV_PIX_FMT_RGBAF32 AV_PIX_FMT_NE(RGBAF32BE, RGBAF32LE) + +/** + * Chromaticity coordinates of the source primaries. + * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.1 and ITU-T H.273. + */ +enum AVColorPrimaries { + AVCOL_PRI_RESERVED0 = 0, + AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B + AVCOL_PRI_UNSPECIFIED = 2, + AVCOL_PRI_RESERVED = 3, + AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + + AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_PRI_SMPTE240M = 7, ///< identical to above, also called "SMPTE C" even though it uses D65 + AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C + AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 + AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) + AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, + AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 + AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 + AVCOL_PRI_EBU3213 = 22, ///< EBU Tech. 3213-E (nothing there) / one of JEDEC P22 group phosphors + AVCOL_PRI_JEDEC_P22 = AVCOL_PRI_EBU3213, + AVCOL_PRI_NB ///< Not part of ABI +}; + +/** + * Color Transfer Characteristic. + * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.2. + */ +enum AVColorTransferCharacteristic { + AVCOL_TRC_RESERVED0 = 0, + AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED = 2, + AVCOL_TRC_RESERVED = 3, + AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + AVCOL_TRC_SMPTE240M = 7, + AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" + AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system + AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system + AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems + AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, + AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 + AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, + AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" + AVCOL_TRC_NB ///< Not part of ABI +}; + +/** + * YUV colorspace type. + * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.3. + */ +enum AVColorSpace { + AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1 + AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B + AVCOL_SPC_UNSPECIFIED = 2, + AVCOL_SPC_RESERVED = 3, ///< reserved for future use by ITU-T and ISO/IEC just like 15-255 are + AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + AVCOL_SPC_SMPTE240M = 7, ///< derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries + AVCOL_SPC_YCGCO = 8, ///< used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, + AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x + AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system + AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system + AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp + AVCOL_SPC_NB ///< Not part of ABI +}; + +/** + * Visual content value range. + * + * These values are based on definitions that can be found in multiple + * specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance + * and colour-difference signals), ITU-T BT.2020 (Table 5 - Digital + * Representation) as well as ITU-T BT.2100 (Table 9 - Digital 10- and 12-bit + * integer representation). At the time of writing, the BT.2100 one is + * recommended, as it also defines the full range representation. + * + * Common definitions: + * - For RGB and luma planes such as Y in YCbCr and I in ICtCp, + * 'E' is the original value in range of 0.0 to 1.0. + * - For chroma planes such as Cb,Cr and Ct,Cp, 'E' is the original + * value in range of -0.5 to 0.5. + * - 'n' is the output bit depth. + * - For additional definitions such as rounding and clipping to valid n + * bit unsigned integer range, please refer to BT.2100 (Table 9). + */ +enum AVColorRange { + AVCOL_RANGE_UNSPECIFIED = 0, + + /** + * Narrow or limited range content. + * + * - For luma planes: + * + * (219 * E + 16) * 2^(n-8) + * + * F.ex. the range of 16-235 for 8 bits + * + * - For chroma planes: + * + * (224 * E + 128) * 2^(n-8) + * + * F.ex. the range of 16-240 for 8 bits + */ + AVCOL_RANGE_MPEG = 1, + + /** + * Full range content. + * + * - For RGB and luma planes: + * + * (2^n - 1) * E + * + * F.ex. the range of 0-255 for 8 bits + * + * - For chroma planes: + * + * (2^n - 1) * E + 2^(n - 1) + * + * F.ex. the range of 1-255 for 8 bits + */ + AVCOL_RANGE_JPEG = 2, + AVCOL_RANGE_NB ///< Not part of ABI +}; + +/** + * Location of chroma samples. + * + * Illustration showing the location of the first (top left) chroma sample of the + * image, the left shows only luma, the right + * shows the location of the chroma sample, the 2 could be imagined to overlay + * each other but are drawn separately due to limitations of ASCII + * + * 1st 2nd 1st 2nd horizontal luma sample positions + * v v v v + * ______ ______ + *1st luma line > |X X ... |3 4 X ... X are luma samples, + * | |1 2 1-6 are possible chroma positions + *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position + */ +enum AVChromaLocation { + AVCHROMA_LOC_UNSPECIFIED = 0, + AVCHROMA_LOC_LEFT = 1, ///< MPEG-2/4 4:2:0, H.264 default for 4:2:0 + AVCHROMA_LOC_CENTER = 2, ///< MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0 + AVCHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 + AVCHROMA_LOC_TOP = 4, + AVCHROMA_LOC_BOTTOMLEFT = 5, + AVCHROMA_LOC_BOTTOM = 6, + AVCHROMA_LOC_NB ///< Not part of ABI +}; + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/ppc/Makefile new file mode 100644 index 00000000..a0febf8d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/Makefile @@ -0,0 +1,6 @@ +OBJS += ppc/cpu.o \ + ppc/float_dsp_init.o \ + +ALTIVEC-OBJS += ppc/float_dsp_altivec.o \ + +VSX-OBJS += ppc/float_dsp_vsx.o \ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.c new file mode 100644 index 00000000..96b491c7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.c @@ -0,0 +1,162 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#ifdef __APPLE__ +#include +#elif defined(__linux__) +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#elif defined(__OpenBSD__) +#include +#include +#include +#elif defined(__AMIGAOS4__) +#include +#include +#include +#endif /* __APPLE__ */ + +#include "libavutil/avassert.h" +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +/** + * This function MAY rely on signal() or fork() in order to make sure AltiVec + * is present. + */ +int ff_get_cpu_flags_ppc(void) +{ +#if HAVE_ALTIVEC +#ifdef __AMIGAOS4__ + ULONG result = 0; + extern struct ExecIFace *IExec; + + IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE); + if (result == VECTORTYPE_ALTIVEC) + return AV_CPU_FLAG_ALTIVEC; + return 0; +#elif defined(__APPLE__) || defined(__OpenBSD__) +#ifdef __OpenBSD__ + int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC}; +#else + int sels[2] = {CTL_HW, HW_VECTORUNIT}; +#endif + int has_vu = 0; + size_t len = sizeof(has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) + return has_vu ? AV_CPU_FLAG_ALTIVEC : 0; + return 0; +#elif defined(__linux__) + // The linux kernel could have the altivec support disabled + // even if the cpu has it. + int i, ret = 0; + int fd = open("/proc/self/auxv", O_RDONLY); + unsigned long buf[64] = { 0 }; + ssize_t count; + + if (fd < 0) + return 0; + + while ((count = read(fd, buf, sizeof(buf))) > 0) { + for (i = 0; i < count / sizeof(*buf); i += 2) { + if (buf[i] == AT_NULL) + goto out; + if (buf[i] == AT_HWCAP) { + if (buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC) + ret = AV_CPU_FLAG_ALTIVEC; +#ifdef PPC_FEATURE_HAS_VSX + if (buf[i + 1] & PPC_FEATURE_HAS_VSX) + ret |= AV_CPU_FLAG_VSX; +#endif + if (ret & AV_CPU_FLAG_VSX) + av_assert0(ret & AV_CPU_FLAG_ALTIVEC); + } else if (buf[i] == AT_HWCAP2) { +#ifdef PPC_FEATURE2_ARCH_2_07 + if (buf[i + 1] & PPC_FEATURE2_ARCH_2_07) + ret |= AV_CPU_FLAG_POWER8; +#endif + } + } + } + +out: + close(fd); + return ret; +#elif CONFIG_RUNTIME_CPUDETECT && defined(__linux__) +#define PVR_G4_7400 0x000C +#define PVR_G5_970 0x0039 +#define PVR_G5_970FX 0x003C +#define PVR_G5_970MP 0x0044 +#define PVR_G5_970GX 0x0045 +#define PVR_POWER6 0x003E +#define PVR_POWER7 0x003F +#define PVR_POWER8 0x004B +#define PVR_CELL_PPU 0x0070 + int ret = 0; + int proc_ver; + // Support of mfspr PVR emulation added in Linux 2.6.17. + __asm__ volatile("mfspr %0, 287" : "=r" (proc_ver)); + proc_ver >>= 16; + if (proc_ver & 0x8000 || + proc_ver == PVR_G4_7400 || + proc_ver == PVR_G5_970 || + proc_ver == PVR_G5_970FX || + proc_ver == PVR_G5_970MP || + proc_ver == PVR_G5_970GX || + proc_ver == PVR_POWER6 || + proc_ver == PVR_POWER7 || + proc_ver == PVR_POWER8 || + proc_ver == PVR_CELL_PPU) + ret = AV_CPU_FLAG_ALTIVEC; + if (proc_ver == PVR_POWER7 || + proc_ver == PVR_POWER8) + ret |= AV_CPU_FLAG_VSX; + if (proc_ver == PVR_POWER8) + ret |= AV_CPU_FLAG_POWER8; + + return ret; +#else + // Since we were compiled for AltiVec, just assume we have it + // until someone comes up with a proper way (not involving signal hacks). + return AV_CPU_FLAG_ALTIVEC; +#endif /* __AMIGAOS4__ */ +#endif /* HAVE_ALTIVEC */ + return 0; +} + +size_t ff_get_cpu_max_align_ppc(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & (AV_CPU_FLAG_ALTIVEC | + AV_CPU_FLAG_VSX | + AV_CPU_FLAG_POWER8)) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.h new file mode 100644 index 00000000..36973a54 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/cpu.h @@ -0,0 +1,29 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PPC_CPU_H +#define AVUTIL_PPC_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define PPC_ALTIVEC(flags) CPUEXT(flags, ALTIVEC) +#define PPC_VSX(flags) CPUEXT(flags, VSX) +#define PPC_POWER8(flags) CPUEXT(flags, POWER8) + +#endif /* AVUTIL_PPC_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.c b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.c new file mode 100644 index 00000000..6aa3e51c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2006 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "util_altivec.h" +#include "float_dsp_altivec.h" + +void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1, + int len) +{ + int i; + vec_f d0, d1, s, zero = (vec_f)vec_splat_u32(0); + for (i = 0; i < len - 7; i += 8) { + d0 = vec_ld( 0, src0 + i); + s = vec_ld( 0, src1 + i); + d1 = vec_ld(16, src0 + i); + d0 = vec_madd(d0, s, zero); + d1 = vec_madd(d1, vec_ld(16, src1 + i), zero); + vec_st(d0, 0, dst + i); + vec_st(d1, 16, dst + i); + } +} + +void ff_vector_fmul_window_altivec(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + vec_f zero, t0, t1, s0, s1, wi, wj; + const vec_u8 reverse = vcprm(3, 2, 1, 0); + int i, j; + + dst += len; + win += len; + src0 += len; + + zero = (vec_f)vec_splat_u32(0); + + for (i = -len * 4, j = len * 4 - 16; i < 0; i += 16, j -= 16) { + s0 = vec_ld(i, src0); + s1 = vec_ld(j, src1); + wi = vec_ld(i, win); + wj = vec_ld(j, win); + + s1 = vec_perm(s1, s1, reverse); + wj = vec_perm(wj, wj, reverse); + + t0 = vec_madd(s0, wj, zero); + t0 = vec_nmsub(s1, wi, t0); + t1 = vec_madd(s0, wi, zero); + t1 = vec_madd(s1, wj, t1); + t1 = vec_perm(t1, t1, reverse); + + vec_st(t0, i, dst); + vec_st(t1, j, dst); + } +} + +void ff_vector_fmul_add_altivec(float *dst, const float *src0, + const float *src1, const float *src2, + int len) +{ + int i; + vec_f d, ss0, ss1, ss2, t0, t1, edges; + + for (i = 0; i < len - 3; i += 4) { + t0 = vec_ld(0, dst + i); + t1 = vec_ld(15, dst + i); + ss0 = vec_ld(0, src0 + i); + ss1 = vec_ld(0, src1 + i); + ss2 = vec_ld(0, src2 + i); + edges = vec_perm(t1, t0, vcprm(0, 1, 2, 3)); + d = vec_madd(ss0, ss1, ss2); + t1 = vec_perm(d, edges, vcprm(s0,s1,s2,s3)); + t0 = vec_perm(edges, d, vcprm(s0,s1,s2,s3)); + vec_st(t1, 15, dst + i); + vec_st(t0, 0, dst + i); + } +} + +void ff_vector_fmul_reverse_altivec(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + vec_f d, s0, s1, h0, l0, s2, s3; + vec_f zero = (vec_f)vec_splat_u32(0); + + src1 += len-4; + for(i = 0; i < len - 7; i += 8) { + s1 = vec_ld(0, src1 - i); // [a,b,c,d] + s0 = vec_ld(0, src0 + i); + l0 = vec_mergel(s1, s1); // [c,c,d,d] + s3 = vec_ld(-16, src1 - i); + h0 = vec_mergeh(s1, s1); // [a,a,b,b] + s2 = vec_ld(16, src0 + i); + s1 = vec_mergeh(vec_mergel(l0, h0), // [d,b,d,b] + vec_mergeh(l0, h0)); // [c,a,c,a] + // [d,c,b,a] + l0 = vec_mergel(s3, s3); + d = vec_madd(s0, s1, zero); + h0 = vec_mergeh(s3, s3); + vec_st(d, 0, dst + i); + s3 = vec_mergeh(vec_mergel(l0, h0), + vec_mergeh(l0, h0)); + d = vec_madd(s2, s3, zero); + vec_st(d, 16, dst + i); + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.h new file mode 100644 index 00000000..e1d530af --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_altivec.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2006 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H +#define AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H + +void ff_vector_fmul_altivec(float *dst, const float *src0, + const float *src1, int len); + +void ff_vector_fmul_window_altivec(float *dst, const float *src0, + const float *src1, const float *win, + int len); + +void ff_vector_fmul_add_altivec(float *dst, const float *src0, + const float *src1, const float *src2, + int len); + +void ff_vector_fmul_reverse_altivec(float *dst, const float *src0, + const float *src1, int len); + +#endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_init.c new file mode 100644 index 00000000..1d490bd9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_init.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "libavutil/ppc/cpu.h" +#include "float_dsp_altivec.h" +#include "float_dsp_vsx.h" + +av_cold void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact) +{ + if (PPC_ALTIVEC(av_get_cpu_flags())) { + fdsp->vector_fmul = ff_vector_fmul_altivec; + fdsp->vector_fmul_add = ff_vector_fmul_add_altivec; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_altivec; + + if (!bit_exact) { + fdsp->vector_fmul_window = ff_vector_fmul_window_altivec; + } + } + + // The disabled function below are near identical to altivec and have + // been disabled to reduce code duplication + if (PPC_VSX(av_get_cpu_flags())) { +// fdsp->vector_fmul = ff_vector_fmul_vsx; + fdsp->vector_fmul_add = ff_vector_fmul_add_vsx; +// fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vsx; + +// if (!bit_exact) { +// fdsp->vector_fmul_window = ff_vector_fmul_window_vsx; +// } + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.c b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.c new file mode 100644 index 00000000..a91e7c12 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "util_altivec.h" +#include "float_dsp_vsx.h" + +void ff_vector_fmul_vsx(float *dst, + const float *src0, const float *src1, + int len) +{ + int i; + vec_f d0, d1, zero = (vec_f)vec_splat_u32(0); + for (i = 0; i < len - 7; i += 8) { + d0 = vec_vsx_ld( 0, src0 + i); + d1 = vec_vsx_ld(16, src0 + i); + d0 = vec_madd(d0, vec_vsx_ld( 0, src1 + i), zero); + d1 = vec_madd(d1, vec_vsx_ld(16, src1 + i), zero); + vec_vsx_st(d0, 0, dst + i); + vec_vsx_st(d1, 16, dst + i); + } +} + +void ff_vector_fmul_window_vsx(float *dst, const float *src0, + const float *src1, const float *win, + int len) +{ + vec_f zero, t0, t1, s0, s1, wi, wj; + const vec_u8 reverse = vcprm(3, 2, 1, 0); + int i, j; + + dst += len; + win += len; + src0 += len; + + zero = (vec_f)vec_splat_u32(0); + + for (i = -len * 4, j = len * 4 - 16; i < 0; i += 16, j -= 16) { + s0 = vec_vsx_ld(i, src0); + s1 = vec_vsx_ld(j, src1); + wi = vec_vsx_ld(i, win); + wj = vec_vsx_ld(j, win); + + s1 = vec_perm(s1, s1, reverse); + wj = vec_perm(wj, wj, reverse); + + t0 = vec_madd(s0, wj, zero); + t0 = vec_nmsub(s1, wi, t0); + t1 = vec_madd(s0, wi, zero); + t1 = vec_madd(s1, wj, t1); + t1 = vec_perm(t1, t1, reverse); + + vec_vsx_st(t0, i, dst); + vec_vsx_st(t1, j, dst); + } +} + +void ff_vector_fmul_add_vsx(float *dst, const float *src0, + const float *src1, const float *src2, + int len) +{ + int i; + vec_f d, s0, s1, s2; + + for (i = 0; i < len - 3; i += 4) { + s0 = vec_vsx_ld(0, src0 + i); + s1 = vec_vsx_ld(0, src1 + i); + s2 = vec_vsx_ld(0, src2 + i); + d = vec_madd(s0, s1, s2); + vec_vsx_st(d, 0, dst + i); + } +} + +void ff_vector_fmul_reverse_vsx(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + vec_f d, s0, s1, h0, l0, s2, s3; + vec_f zero = (vec_f)vec_splat_u32(0); + + src1 += len - 4; + for (i = 0; i < len - 7; i += 8) { + s1 = vec_vsx_ld(0, src1 - i); // [a,b,c,d] + s0 = vec_vsx_ld(0, src0 + i); + l0 = vec_mergel(s1, s1); // [c,c,d,d] + s3 = vec_vsx_ld(-16, src1 - i); + h0 = vec_mergeh(s1, s1); // [a,a,b,b] + s2 = vec_vsx_ld(16, src0 + i); + s1 = vec_mergeh(vec_mergel(l0, h0), // [d,b,d,b] + vec_mergeh(l0, h0)); // [c,a,c,a] + // [d,c,b,a] + l0 = vec_mergel(s3, s3); + d = vec_madd(s0, s1, zero); + h0 = vec_mergeh(s3, s3); + vec_vsx_st(d, 0, dst + i); + s3 = vec_mergeh(vec_mergel(l0, h0), + vec_mergeh(l0, h0)); + d = vec_madd(s2, s3, zero); + vec_vsx_st(d, 16, dst + i); + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.h new file mode 100644 index 00000000..5d3cc5ed --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/float_dsp_vsx.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PPC_FLOAT_DSP_VSX_H +#define AVUTIL_PPC_FLOAT_DSP_VSX_H + +void ff_vector_fmul_vsx(float *dst, const float *src0, + const float *src1, int len); + +void ff_vector_fmul_window_vsx(float *dst, const float *src0, + const float *src1, const float *win, + int len); + +void ff_vector_fmul_add_vsx(float *dst, const float *src0, + const float *src1, const float *src2, + int len); + +void ff_vector_fmul_reverse_vsx(float *dst, const float *src0, + const float *src1, int len); + +#endif /* AVUTIL_PPC_FLOAT_DSP_VSX_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/intreadwrite.h new file mode 100644 index 00000000..7671676c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/intreadwrite.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PPC_INTREADWRITE_H +#define AVUTIL_PPC_INTREADWRITE_H + +#include +#include "config.h" + +#if HAVE_XFORM_ASM + +#if HAVE_BIGENDIAN +#define AV_RL16 av_read_bswap16 +#define AV_WL16 av_write_bswap16 +#define AV_RL32 av_read_bswap32 +#define AV_WL32 av_write_bswap32 +#define AV_RL64 av_read_bswap64 +#define AV_WL64 av_write_bswap64 + +#else +#define AV_RB16 av_read_bswap16 +#define AV_WB16 av_write_bswap16 +#define AV_RB32 av_read_bswap32 +#define AV_WB32 av_write_bswap32 +#define AV_RB64 av_read_bswap64 +#define AV_WB64 av_write_bswap64 + +#endif + +static av_always_inline uint16_t av_read_bswap16(const void *p) +{ + uint16_t v; + __asm__ ("lhbrx %0, %y1" : "=r"(v) : "Z"(*(const uint16_t*)p)); + return v; +} + +static av_always_inline void av_write_bswap16(void *p, uint16_t v) +{ + __asm__ ("sthbrx %1, %y0" : "=Z"(*(uint16_t*)p) : "r"(v)); +} + +static av_always_inline uint32_t av_read_bswap32(const void *p) +{ + uint32_t v; + __asm__ ("lwbrx %0, %y1" : "=r"(v) : "Z"(*(const uint32_t*)p)); + return v; +} + +static av_always_inline void av_write_bswap32(void *p, uint32_t v) +{ + __asm__ ("stwbrx %1, %y0" : "=Z"(*(uint32_t*)p) : "r"(v)); +} + +#if HAVE_LDBRX + +static av_always_inline uint64_t av_read_bswap64(const void *p) +{ + uint64_t v; + __asm__ ("ldbrx %0, %y1" : "=r"(v) : "Z"(*(const uint64_t*)p)); + return v; +} + +static av_always_inline void av_write_bswap64(void *p, uint64_t v) +{ + __asm__ ("stdbrx %1, %y0" : "=Z"(*(uint64_t*)p) : "r"(v)); +} + +#else + +static av_always_inline uint64_t av_read_bswap64(const void *p) +{ + union { uint64_t v; uint32_t hl[2]; } v; + __asm__ ("lwbrx %0, %y2 \n\t" + "lwbrx %1, %y3 \n\t" + : "=&r"(v.hl[1]), "=r"(v.hl[0]) + : "Z"(*(const uint32_t*)p), "Z"(*((const uint32_t*)p+1))); + return v.v; +} + +static av_always_inline void av_write_bswap64(void *p, uint64_t v) +{ + union { uint64_t v; uint32_t hl[2]; } vv = { v }; + __asm__ ("stwbrx %2, %y0 \n\t" + "stwbrx %3, %y1 \n\t" + : "=Z"(*(uint32_t*)p), "=Z"(*((uint32_t*)p+1)) + : "r"(vv.hl[1]), "r"(vv.hl[0])); +} + +#endif /* HAVE_LDBRX */ + +#endif /* HAVE_XFORM_ASM */ + +#endif /* AVUTIL_PPC_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/timer.h new file mode 100644 index 00000000..b28e6245 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/timer.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005 Luca Barbato + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PPC_TIMER_H +#define AVUTIL_PPC_TIMER_H + +#include + +#include "config.h" + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint32_t tbu, tbl, temp; + + /* from section 2.2.1 of the 32-bit PowerPC PEM */ + __asm__ volatile( + "mftbu %2\n" + "mftb %0\n" + "mftbu %1\n" + "cmpw %2,%1\n" + "bne $-0x10\n" + : "=r"(tbl), "=r"(tbu), "=r"(temp) + : + : "cc"); + + return (((uint64_t)tbu)<<32) | (uint64_t)tbl; +} + +#endif /* AVUTIL_PPC_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ppc/util_altivec.h b/arm/raspi/third_party/ffmpeg/libavutil/ppc/util_altivec.h new file mode 100644 index 00000000..2548011b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ppc/util_altivec.h @@ -0,0 +1,195 @@ +/* + * 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 + * Contains misc utility macros and inline functions + */ + +#ifndef AVUTIL_PPC_UTIL_ALTIVEC_H +#define AVUTIL_PPC_UTIL_ALTIVEC_H + +#include + +#include "config.h" + +/*********************************************************************** + * Vector types + **********************************************************************/ +#define vec_u8 vector unsigned char +#define vec_s8 vector signed char +#define vec_u16 vector unsigned short +#define vec_s16 vector signed short +#define vec_u32 vector unsigned int +#define vec_s32 vector signed int +#define vec_f vector float + +/*********************************************************************** + * Null vector + **********************************************************************/ +#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 ) + +#define zero_u8v (vec_u8) zerov +#define zero_s8v (vec_s8) zerov +#define zero_u16v (vec_u16) zerov +#define zero_s16v (vec_s16) zerov +#define zero_u32v (vec_u32) zerov +#define zero_s32v (vec_s32) zerov + +#if HAVE_ALTIVEC +#include + +// used to build registers permutation vectors (vcprm) +// the 's' are for words in the _s_econd vector +#define WORD_0 0x00,0x01,0x02,0x03 +#define WORD_1 0x04,0x05,0x06,0x07 +#define WORD_2 0x08,0x09,0x0a,0x0b +#define WORD_3 0x0c,0x0d,0x0e,0x0f +#define WORD_s0 0x10,0x11,0x12,0x13 +#define WORD_s1 0x14,0x15,0x16,0x17 +#define WORD_s2 0x18,0x19,0x1a,0x1b +#define WORD_s3 0x1c,0x1d,0x1e,0x1f +#define vcprm(a,b,c,d) (const vec_u8){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d} + +#define SWP_W2S0 0x02,0x03,0x00,0x01 +#define SWP_W2S1 0x06,0x07,0x04,0x05 +#define SWP_W2S2 0x0a,0x0b,0x08,0x09 +#define SWP_W2S3 0x0e,0x0f,0x0c,0x0d +#define SWP_W2Ss0 0x12,0x13,0x10,0x11 +#define SWP_W2Ss1 0x16,0x17,0x14,0x15 +#define SWP_W2Ss2 0x1a,0x1b,0x18,0x19 +#define SWP_W2Ss3 0x1e,0x1f,0x1c,0x1d +#define vcswapi2s(a,b,c,d) (const vector unsigned char){SWP_W2S ## a, SWP_W2S ## b, SWP_W2S ## c, SWP_W2S ## d} + +#define vcswapc() \ + (const vector unsigned char){0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00} + + +// Transpose 8x8 matrix of 16-bit elements (in-place) +#define TRANSPOSE8(a,b,c,d,e,f,g,h) \ +do { \ + vec_s16 A1, B1, C1, D1, E1, F1, G1, H1; \ + vec_s16 A2, B2, C2, D2, E2, F2, G2, H2; \ + \ + A1 = vec_mergeh (a, e); \ + B1 = vec_mergel (a, e); \ + C1 = vec_mergeh (b, f); \ + D1 = vec_mergel (b, f); \ + E1 = vec_mergeh (c, g); \ + F1 = vec_mergel (c, g); \ + G1 = vec_mergeh (d, h); \ + H1 = vec_mergel (d, h); \ + \ + A2 = vec_mergeh (A1, E1); \ + B2 = vec_mergel (A1, E1); \ + C2 = vec_mergeh (B1, F1); \ + D2 = vec_mergel (B1, F1); \ + E2 = vec_mergeh (C1, G1); \ + F2 = vec_mergel (C1, G1); \ + G2 = vec_mergeh (D1, H1); \ + H2 = vec_mergel (D1, H1); \ + \ + a = vec_mergeh (A2, E2); \ + b = vec_mergel (A2, E2); \ + c = vec_mergeh (B2, F2); \ + d = vec_mergel (B2, F2); \ + e = vec_mergeh (C2, G2); \ + f = vec_mergel (C2, G2); \ + g = vec_mergeh (D2, H2); \ + h = vec_mergel (D2, H2); \ +} while (0) + + +#if HAVE_BIGENDIAN +#define VEC_LD(offset,b) \ + vec_perm(vec_ld(offset, b), vec_ld((offset)+15, b), vec_lvsl(offset, b)) +#else +#define VEC_LD(offset,b) \ + vec_vsx_ld(offset, b) +#endif + +/** @brief loads unaligned vector @a *src with offset @a offset + and returns it */ +#if HAVE_BIGENDIAN +static inline vec_u8 unaligned_load(int offset, const uint8_t *src) +{ + register vec_u8 first = vec_ld(offset, src); + register vec_u8 second = vec_ld(offset + 15, src); + register vec_u8 mask = vec_lvsl(offset, src); + return vec_perm(first, second, mask); +} +static inline vec_u8 load_with_perm_vec(int offset, const uint8_t *src, vec_u8 perm_vec) +{ + vec_u8 a = vec_ld(offset, src); + vec_u8 b = vec_ld(offset + 15, src); + return vec_perm(a, b, perm_vec); +} +#else +#define unaligned_load(a,b) VEC_LD(a,b) +#define load_with_perm_vec(a,b,c) VEC_LD(a,b) +#endif + + +/** + * loads vector known misalignment + * @param perm_vec the align permute vector to combine the two loads from lvsl + */ + +#define vec_unaligned_load(b) VEC_LD(0, b) + +#if HAVE_BIGENDIAN +#define VEC_MERGEH(a, b) vec_mergeh(a, b) +#define VEC_MERGEL(a, b) vec_mergel(a, b) +#else +#define VEC_MERGEH(a, b) vec_mergeh(b, a) +#define VEC_MERGEL(a, b) vec_mergel(b, a) +#endif + +#if HAVE_BIGENDIAN +#define VEC_ST(a,b,c) vec_st(a,b,c) +#else +#define VEC_ST(a,b,c) vec_vsx_st(a,b,c) +#endif + +#if HAVE_BIGENDIAN +#define VEC_SPLAT16(a,b) vec_splat((vec_s16)(a), b) +#else +#define VEC_SPLAT16(a,b) vec_splat((vec_s16)(vec_perm(a, a, vcswapi2s(0,1,2,3))), b) +#endif + +#if HAVE_BIGENDIAN +#define VEC_SLD16(a,b,c) vec_sld(a, b, c) +#else +#define VEC_SLD16(a,b,c) vec_sld(b, a, c) +#endif + +#endif /* HAVE_ALTIVEC */ + +#if HAVE_VSX +#if HAVE_BIGENDIAN +#define vsx_ld_u8_s16(off, p) \ + ((vec_s16)vec_mergeh((vec_u8)vec_splat_u8(0), \ + (vec_u8)vec_vsx_ld((off), (p)))) +#else +#define vsx_ld_u8_s16(off, p) \ + ((vec_s16)vec_mergeh((vec_u8)vec_vsx_ld((off), (p)), \ + (vec_u8)vec_splat_u8(0))) +#endif /* HAVE_BIGENDIAN */ +#endif /* HAVE_VSX */ + +#endif /* AVUTIL_PPC_UTIL_ALTIVEC_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/qsort.h b/arm/raspi/third_party/ffmpeg/libavutil/qsort.h new file mode 100644 index 00000000..6014f88b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/qsort.h @@ -0,0 +1,122 @@ +/* + * copyright (c) 2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_QSORT_H +#define AVUTIL_QSORT_H + +#include "macros.h" + + +/** + * Quicksort + * This sort is fast, and fully inplace but not stable and it is possible + * to construct input that requires O(n^2) time but this is very unlikely to + * happen with non constructed input. + */ +#define AV_QSORT(p, num, type, cmp) do {\ + void *stack[64][2];\ + int sp= 1;\ + stack[0][0] = p;\ + stack[0][1] = (p)+(num)-1;\ + while(sp){\ + type *start= stack[--sp][0];\ + type *end = stack[ sp][1];\ + while(start < end){\ + if(start < end-1) {\ + int checksort=0;\ + type *right = end-2;\ + type *left = start+1;\ + type *mid = start + ((end-start)>>1);\ + if(cmp(start, end) > 0) {\ + if(cmp( end, mid) > 0) FFSWAP(type, *start, *mid);\ + else FFSWAP(type, *start, *end);\ + }else{\ + if(cmp(start, mid) > 0) FFSWAP(type, *start, *mid);\ + else checksort= 1;\ + }\ + if(cmp(mid, end) > 0){ \ + FFSWAP(type, *mid, *end);\ + checksort=0;\ + }\ + if(start == end-2) break;\ + FFSWAP(type, end[-1], *mid);\ + while(left <= right){\ + while(left<=right && cmp(left, end-1) < 0)\ + left++;\ + while(left<=right && cmp(right, end-1) > 0)\ + right--;\ + if(left <= right){\ + FFSWAP(type, *left, *right);\ + left++;\ + right--;\ + }\ + }\ + FFSWAP(type, end[-1], *left);\ + if(checksort && (mid == left-1 || mid == left)){\ + mid= start;\ + while(mid 0)\ + FFSWAP(type, *start, *end);\ + break;\ + }\ + }\ + }\ +} while (0) + +/** + * Merge sort, this sort requires a temporary buffer and is stable, its worst + * case time is O(n log n) + * @param p must be a lvalue pointer, this function may exchange it with tmp + * @param tmp must be a lvalue pointer, this function may exchange it with p + */ +#define AV_MSORT(p, tmp, num, type, cmp) do {\ + unsigned i, j, step;\ + for(step=1; step<(num); step+=step){\ + for(i=0; i<(num); i+=2*step){\ + unsigned a[2] = {i, i+step};\ + unsigned end = FFMIN(i+2*step, (num));\ + for(j=i; a[0] 0;\ + tmp[j] = p[ a[idx]++ ];\ + }\ + if(a[0]>=i+step) a[0] = a[1];\ + for(; j + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#if HAVE_BCRYPT +#include +#include +#endif +#include +#include +#include +#include +#include "avassert.h" +#include "file_open.h" +#include "internal.h" +#include "intreadwrite.h" +#include "timer.h" +#include "random_seed.h" +#include "sha.h" + +#ifndef TEST +#define TEST 0 +#endif + +static int read_random(uint32_t *dst, const char *file) +{ +#if HAVE_UNISTD_H + int fd = avpriv_open(file, O_RDONLY); + int err = -1; + + if (fd == -1) + return -1; + err = read(fd, dst, sizeof(*dst)); + close(fd); + + return err; +#else + return -1; +#endif +} + +static uint32_t get_generic_seed(void) +{ + uint64_t tmp[120/8]; + struct AVSHA *sha = (void*)tmp; + clock_t last_t = 0; + clock_t last_td = 0; + clock_t init_t = 0; + static uint64_t i = 0; + static uint32_t buffer[512] = { 0 }; + unsigned char digest[20]; + uint64_t last_i = i; + + av_assert0(sizeof(tmp) >= av_sha_size); + + if(TEST){ + memset(buffer, 0, sizeof(buffer)); + last_i = i = 0; + }else{ +#ifdef AV_READ_TIME + buffer[13] ^= AV_READ_TIME(); + buffer[41] ^= AV_READ_TIME()>>32; +#endif + } + + for (;;) { + clock_t t = clock(); + if (last_t + 2*last_td + (CLOCKS_PER_SEC > 1000) >= t) { + last_td = t - last_t; + buffer[i & 511] = 1664525*buffer[i & 511] + 1013904223 + (last_td % 3294638521U); + } else { + last_td = t - last_t; + buffer[++i & 511] += last_td % 3294638521U; + if ((t - init_t) >= CLOCKS_PER_SEC>>5) + if (last_i && i - last_i > 4 || i - last_i > 64 || TEST && i - last_i > 8) + break; + } + last_t = t; + if (!init_t) + init_t = t; + } + + if(TEST) { + buffer[0] = buffer[1] = 0; + } else { +#ifdef AV_READ_TIME + buffer[111] += AV_READ_TIME(); +#endif + } + + av_sha_init(sha, 160); + av_sha_update(sha, (const uint8_t *)buffer, sizeof(buffer)); + av_sha_final(sha, digest); + return AV_RB32(digest) + AV_RB32(digest + 16); +} + +uint32_t av_get_random_seed(void) +{ + uint32_t seed; + +#if HAVE_BCRYPT + BCRYPT_ALG_HANDLE algo_handle; + NTSTATUS ret = BCryptOpenAlgorithmProvider(&algo_handle, BCRYPT_RNG_ALGORITHM, + MS_PRIMITIVE_PROVIDER, 0); + if (BCRYPT_SUCCESS(ret)) { + NTSTATUS ret = BCryptGenRandom(algo_handle, (UCHAR*)&seed, sizeof(seed), 0); + BCryptCloseAlgorithmProvider(algo_handle, 0); + if (BCRYPT_SUCCESS(ret)) + return seed; + } +#endif + +#if HAVE_ARC4RANDOM + return arc4random(); +#endif + + if (read_random(&seed, "/dev/urandom") == sizeof(seed)) + return seed; + if (read_random(&seed, "/dev/random") == sizeof(seed)) + return seed; + return get_generic_seed(); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/random_seed.h b/arm/raspi/third_party/ffmpeg/libavutil/random_seed.h new file mode 100644 index 00000000..0462a048 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/random_seed.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2009 Baptiste Coudurier + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RANDOM_SEED_H +#define AVUTIL_RANDOM_SEED_H + +#include +/** + * @addtogroup lavu_crypto + * @{ + */ + +/** + * Get a seed to use in conjunction with random functions. + * This function tries to provide a good seed at a best effort bases. + * Its possible to call this function multiple times if more bits are needed. + * It can be quite slow, which is why it should only be used as seed for a faster + * PRNG. The quality of the seed depends on the platform. + */ +uint32_t av_get_random_seed(void); + +/** + * @} + */ + +#endif /* AVUTIL_RANDOM_SEED_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/rational.c b/arm/raspi/third_party/ffmpeg/libavutil/rational.c new file mode 100644 index 00000000..eb148ddb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/rational.c @@ -0,0 +1,193 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * rational numbers + * @author Michael Niedermayer + */ + +#include "avassert.h" +#include + +#include "common.h" +#include "mathematics.h" +#include "rational.h" + +int av_reduce(int *dst_num, int *dst_den, + int64_t num, int64_t den, int64_t max) +{ + AVRational a0 = { 0, 1 }, a1 = { 1, 0 }; + int sign = (num < 0) ^ (den < 0); + int64_t gcd = av_gcd(FFABS(num), FFABS(den)); + + if (gcd) { + num = FFABS(num) / gcd; + den = FFABS(den) / gcd; + } + if (num <= max && den <= max) { + a1 = (AVRational) { num, den }; + den = 0; + } + + while (den) { + uint64_t x = num / den; + int64_t next_den = num - den * x; + int64_t a2n = x * a1.num + a0.num; + int64_t a2d = x * a1.den + a0.den; + + if (a2n > max || a2d > max) { + if (a1.num) x = (max - a0.num) / a1.num; + if (a1.den) x = FFMIN(x, (max - a0.den) / a1.den); + + if (den * (2 * x * a1.den + a0.den) > num * a1.den) + a1 = (AVRational) { x * a1.num + a0.num, x * a1.den + a0.den }; + break; + } + + a0 = a1; + a1 = (AVRational) { a2n, a2d }; + num = den; + den = next_den; + } + av_assert2(av_gcd(a1.num, a1.den) <= 1U); + av_assert2(a1.num <= max && a1.den <= max); + + *dst_num = sign ? -a1.num : a1.num; + *dst_den = a1.den; + + return den == 0; +} + +AVRational av_mul_q(AVRational b, AVRational c) +{ + av_reduce(&b.num, &b.den, + b.num * (int64_t) c.num, + b.den * (int64_t) c.den, INT_MAX); + return b; +} + +AVRational av_div_q(AVRational b, AVRational c) +{ + return av_mul_q(b, (AVRational) { c.den, c.num }); +} + +AVRational av_add_q(AVRational b, AVRational c) { + av_reduce(&b.num, &b.den, + b.num * (int64_t) c.den + + c.num * (int64_t) b.den, + b.den * (int64_t) c.den, INT_MAX); + return b; +} + +AVRational av_sub_q(AVRational b, AVRational c) +{ + return av_add_q(b, (AVRational) { -c.num, c.den }); +} + +AVRational av_d2q(double d, int max) +{ + AVRational a; + int exponent; + int64_t den; + if (isnan(d)) + return (AVRational) { 0,0 }; + if (fabs(d) > INT_MAX + 3LL) + return (AVRational) { d < 0 ? -1 : 1, 0 }; + frexp(d, &exponent); + exponent = FFMAX(exponent-1, 0); + den = 1LL << (61 - exponent); + // (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64, + // see Ticket2713 for affected gcc/glibc versions + av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max); + if ((!a.num || !a.den) && d && max>0 && max n => a*d/b > n */ + int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP); + + /* rnd_down(a*d/b) < n => a*d/b < n */ + int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN); + + return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1); +} + +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list) +{ + int i, nearest_q_idx = 0; + for (i = 0; q_list[i].den; i++) + if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0) + nearest_q_idx = i; + + return nearest_q_idx; +} + +uint32_t av_q2intfloat(AVRational q) { + int64_t n; + int shift; + int sign = 0; + + if (q.den < 0) { + q.den *= -1; + q.num *= -1; + } + if (q.num < 0) { + q.num *= -1; + sign = 1; + } + + if (!q.num && !q.den) return 0xFFC00000; + if (!q.num) return 0; + if (!q.den) return 0x7F800000 | (q.num & 0x80000000); + + shift = 23 + av_log2(q.den) - av_log2(q.num); + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<24); + shift += n < (1<<23); + + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<23)); + + return sign<<31 | (150-shift)<<23 | (n - (1<<23)); +} + +AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def) +{ + int64_t gcd, lcm; + + gcd = av_gcd(a.den, b.den); + lcm = (a.den / gcd) * b.den; + return lcm < max_den ? av_make_q(av_gcd(a.num, b.num), lcm) : def; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/rational.h b/arm/raspi/third_party/ffmpeg/libavutil/rational.h new file mode 100644 index 00000000..8cbfc8e0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/rational.h @@ -0,0 +1,221 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_math_rational + * Utilties for rational number calculation. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include +#include +#include "attributes.h" + +/** + * @defgroup lavu_math_rational AVRational + * @ingroup lavu_math + * Rational number calculation. + * + * While rational numbers can be expressed as floating-point numbers, the + * conversion process is a lossy one, so are floating-point operations. On the + * other hand, the nature of FFmpeg demands highly accurate calculation of + * timestamps. This set of rational number utilities serves as a generic + * interface for manipulating rational numbers as pairs of numerators and + * denominators. + * + * Many of the functions that operate on AVRational's have the suffix `_q`, in + * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all + * rational numbers. + * + * @{ + */ + +/** + * Rational number (pair of numerator and denominator). + */ +typedef struct AVRational{ + int num; ///< Numerator + int den; ///< Denominator +} AVRational; + +/** + * Create an AVRational. + * + * Useful for compilers that do not support compound literals. + * + * @note The return value is not reduced. + * @see av_reduce() + */ +static inline AVRational av_make_q(int num, int den) +{ + AVRational r = { num, den }; + return r; +} + +/** + * Compare two rationals. + * + * @param a First rational + * @param b Second rational + * + * @return One of the following values: + * - 0 if `a == b` + * - 1 if `a > b` + * - -1 if `a < b` + * - `INT_MIN` if one of the values is of the form `0 / 0` + */ +static inline int av_cmp_q(AVRational a, AVRational b){ + const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; + + if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1; + else if(b.den && a.den) return 0; + else if(a.num && b.num) return (a.num>>31) - (b.num>>31); + else return INT_MIN; +} + +/** + * Convert an AVRational to a `double`. + * @param a AVRational to convert + * @return `a` in floating-point form + * @see av_d2q() + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduce a fraction. + * + * This is useful for framerate calculations. + * + * @param[out] dst_num Destination numerator + * @param[out] dst_den Destination denominator + * @param[in] num Source numerator + * @param[in] den Source denominator + * @param[in] max Maximum allowed values for `dst_num` & `dst_den` + * @return 1 if the operation is exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiply two rationals. + * @param b First rational + * @param c Second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divide one rational by another. + * @param b First rational + * @param c Second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Add two rationals. + * @param b First rational + * @param c Second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtract one rational from another. + * @param b First rational + * @param c Second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Invert a rational. + * @param q value + * @return 1 / q + */ +static av_always_inline AVRational av_inv_q(AVRational q) +{ + AVRational r = { q.den, q.num }; + return r; +} + +/** + * Convert a double precision floating point number to a rational. + * + * In case of infinity, the returned value is expressed as `{1, 0}` or + * `{-1, 0}` depending on the sign. + * + * @param d `double` to convert + * @param max Maximum allowed numerator and denominator + * @return `d` in AVRational form + * @see av_q2d() + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * Find which of the two rationals is closer to another rational. + * + * @param q Rational to be compared against + * @param q1 Rational to be tested + * @param q2 Rational to be tested + * @return One of the following values: + * - 1 if `q1` is nearer to `q` than `q2` + * - -1 if `q2` is nearer to `q` than `q1` + * - 0 if they have the same distance + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Find the value in a list of rationals nearest a given reference rational. + * + * @param q Reference rational + * @param q_list Array of rationals terminated by `{0, 0}` + * @return Index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +/** + * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point + * format. + * + * @param q Rational to be converted + * @return Equivalent floating-point value, expressed as an unsigned 32-bit + * integer. + * @note The returned value is platform-indepedant. + */ +uint32_t av_q2intfloat(AVRational q); + +/** + * Return the best rational so that a and b are multiple of it. + * If the resulting denominator is larger than max_den, return def. + */ +AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def); + +/** + * @} + */ + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/rc4.c b/arm/raspi/third_party/ffmpeg/libavutil/rc4.c new file mode 100644 index 00000000..74c1f489 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/rc4.c @@ -0,0 +1,66 @@ +/* + * RC4 encryption/decryption/pseudo-random number generator + * Copyright (c) 2007 Reimar Doeffinger + * + * loosely based on LibTomCrypt by Tom St Denis + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "error.h" +#include "macros.h" +#include "mem.h" +#include "rc4.h" + +AVRC4 *av_rc4_alloc(void) +{ + return av_mallocz(sizeof(struct AVRC4)); +} + +int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt) { + int i, j; + uint8_t y; + uint8_t *state = r->state; + int keylen = key_bits >> 3; + if (key_bits & 7) + return AVERROR(EINVAL); + for (i = 0; i < 256; i++) + state[i] = i; + y = 0; + // j is i % keylen + for (j = 0, i = 0; i < 256; i++, j++) { + if (j == keylen) j = 0; + y += state[i] + key[j]; + FFSWAP(uint8_t, state[i], state[y]); + } + r->x = 1; + r->y = state[1]; + return 0; +} + +void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) { + uint8_t x = r->x, y = r->y; + uint8_t *state = r->state; + while (count-- > 0) { + uint8_t sum = state[x] + state[y]; + FFSWAP(uint8_t, state[x], state[y]); + *dst++ = src ? *src++ ^ state[sum] : state[sum]; + x++; + y += state[x]; + } + r->x = x; r->y = y; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/rc4.h b/arm/raspi/third_party/ffmpeg/libavutil/rc4.h new file mode 100644 index 00000000..bf0ca6e9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/rc4.h @@ -0,0 +1,69 @@ +/* + * RC4 encryption/decryption/pseudo-random number generator + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RC4_H +#define AVUTIL_RC4_H + +#include + +/** + * @defgroup lavu_rc4 RC4 + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVRC4 { + uint8_t state[256]; + int x, y; +} AVRC4; + +/** + * Allocate an AVRC4 context. + */ +AVRC4 *av_rc4_alloc(void); + +/** + * @brief Initializes an AVRC4 context. + * + * @param d pointer to the AVRC4 context + * @param key buffer containig the key + * @param key_bits must be a multiple of 8 + * @param decrypt 0 for encryption, 1 for decryption, currently has no effect + * @return zero on success, negative value otherwise + */ +int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the RC4 algorithm. + * + * @param d pointer to the AVRC4 context + * @param count number of bytes + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst, may be NULL + * @param iv not (yet) used for RC4, should be NULL + * @param decrypt 0 for encryption, 1 for decryption, not (yet) used + */ +void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_RC4_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/replaygain.h b/arm/raspi/third_party/ffmpeg/libavutil/replaygain.h new file mode 100644 index 00000000..b49bf1a3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/replaygain.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_REPLAYGAIN_H +#define AVUTIL_REPLAYGAIN_H + +#include + +/** + * ReplayGain information (see + * http://wiki.hydrogenaudio.org/index.php?title=ReplayGain_1.0_specification). + * The size of this struct is a part of the public ABI. + */ +typedef struct AVReplayGain { + /** + * Track replay gain in microbels (divide by 100000 to get the value in dB). + * Should be set to INT32_MIN when unknown. + */ + int32_t track_gain; + /** + * Peak track amplitude, with 100000 representing full scale (but values + * may overflow). 0 when unknown. + */ + uint32_t track_peak; + /** + * Same as track_gain, but for the whole album. + */ + int32_t album_gain; + /** + * Same as track_peak, but for the whole album, + */ + uint32_t album_peak; +} AVReplayGain; + +#endif /* AVUTIL_REPLAYGAIN_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/reverse.c b/arm/raspi/third_party/ffmpeg/libavutil/reverse.c new file mode 100644 index 00000000..105eb03d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/reverse.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const uint8_t ff_reverse[256] = { +0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, +0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, +0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, +0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, +0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, +0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, +0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, +0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, +0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, +0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, +0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, +0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, +0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, +0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, +0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, +0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/reverse.h b/arm/raspi/third_party/ffmpeg/libavutil/reverse.h new file mode 100644 index 00000000..4eb61239 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/reverse.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_REVERSE_H +#define AVUTIL_REVERSE_H + +#include + +extern const uint8_t ff_reverse[256]; + +#endif /* AVUTIL_REVERSE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ripemd.c b/arm/raspi/third_party/ffmpeg/libavutil/ripemd.c new file mode 100644 index 00000000..e170c69f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ripemd.c @@ -0,0 +1,559 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" +#include "attributes.h" +#include "bswap.h" +#include "error.h" +#include "intreadwrite.h" +#include "macros.h" +#include "ripemd.h" +#include "mem.h" + +/** hash context */ +typedef struct AVRIPEMD { + uint8_t digest_len; ///< digest length in 32-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating + uint32_t state[10]; ///< current hash value + /** function used to update hash for 512-bit input block */ + void (*transform)(uint32_t *state, const uint8_t buffer[64]); +} AVRIPEMD; + +const int av_ripemd_size = sizeof(AVRIPEMD); + +struct AVRIPEMD *av_ripemd_alloc(void) +{ + return av_mallocz(sizeof(struct AVRIPEMD)); +} + +static const uint32_t KA[4] = { + 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e +}; + +static const uint32_t KB[4] = { + 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9 +}; + +static const int ROTA[80] = { + 11, 14, 15, 12, 5, 8, 7 , 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7 , 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +}; + +static const int ROTB[80] = { + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +}; + +static const int WA[80] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +}; + +static const int WB[80] = { + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +}; + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +#define ROUND128_0_TO_15(a,b,c,d,e,f,g,h) \ + a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]); \ + e = rol(e + ((((f ^ g) & h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]); \ + n++ + +#define ROUND128_16_TO_31(a,b,c,d,e,f,g,h) \ + a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]); \ + e = rol(e + (((~g | f) ^ h) + block[WB[n]] + KB[1]), ROTB[n]); \ + n++ + +#define ROUND128_32_TO_47(a,b,c,d,e,f,g,h) \ + a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]); \ + e = rol(e + ((((g ^ h) & f) ^ h) + block[WB[n]] + KB[2]), ROTB[n]); \ + n++ + +#define ROUND128_48_TO_63(a,b,c,d,e,f,g,h) \ + a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]); \ + e = rol(e + (( f ^ g ^ h) + block[WB[n]]), ROTB[n]); \ + n++ + +#define R128_0 \ + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); \ + ROUND128_0_TO_15(d,a,b,c,h,e,f,g); \ + ROUND128_0_TO_15(c,d,a,b,g,h,e,f); \ + ROUND128_0_TO_15(b,c,d,a,f,g,h,e) + +#define R128_16 \ + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); \ + ROUND128_16_TO_31(d,a,b,c,h,e,f,g); \ + ROUND128_16_TO_31(c,d,a,b,g,h,e,f); \ + ROUND128_16_TO_31(b,c,d,a,f,g,h,e) + +#define R128_32 \ + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); \ + ROUND128_32_TO_47(d,a,b,c,h,e,f,g); \ + ROUND128_32_TO_47(c,d,a,b,g,h,e,f); \ + ROUND128_32_TO_47(b,c,d,a,f,g,h,e) + +#define R128_48 \ + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); \ + ROUND128_48_TO_63(d,a,b,c,h,e,f,g); \ + ROUND128_48_TO_63(c,d,a,b,g,h,e,f); \ + ROUND128_48_TO_63(b,c,d,a,f,g,h,e) + +static void ripemd128_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, av_unused t; + uint32_t block[16]; + int n; + + a = e = state[0]; + b = f = state[1]; + c = g = state[2]; + d = h = state[3]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 32;) { + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 48;) { + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 64;) { + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } +#else + + R128_0; R128_0; R128_0; R128_0; + + R128_16; R128_16; R128_16; R128_16; + + R128_32; R128_32; R128_32; R128_32; + + R128_48; R128_48; R128_48; R128_48; +#endif + + h += c + state[1]; + state[1] = state[2] + d + e; + state[2] = state[3] + a + f; + state[3] = state[0] + b + g; + state[0] = h; +} + +static void ripemd256_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, av_unused t; + uint32_t block[16]; + int n; + + a = state[0]; b = state[1]; c = state[2]; d = state[3]; + e = state[4]; f = state[5]; g = state[6]; h = state[7]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, a, e); + + for (; n < 32;) { + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, b, f); + + for (; n < 48;) { + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, c, g); + + for (; n < 64;) { + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, d, h); +#else + + R128_0; R128_0; R128_0; R128_0; + FFSWAP(uint32_t, a, e); + + R128_16; R128_16; R128_16; R128_16; + FFSWAP(uint32_t, b, f); + + R128_32; R128_32; R128_32; R128_32; + FFSWAP(uint32_t, c, g); + + R128_48; R128_48; R128_48; R128_48; + FFSWAP(uint32_t, d, h); +#endif + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; + state[4] += e; state[5] += f; state[6] += g; state[7] += h; +} + +#define ROTATE(x,y) \ + x = rol(x, 10); \ + y = rol(y, 10); \ + n++ + +#define ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]) + e; \ + f = rol(f + (((~i | h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]) + e; \ + f = rol(f + ((((g ^ h) & i) ^ h) + block[WB[n]] + KB[1]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]) + e; \ + f = rol(f + (((~h | g) ^ i) + block[WB[n]] + KB[2]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]) + e; \ + f = rol(f + ((((h ^ i) & g) ^ i) + block[WB[n]] + KB[3]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (((~d | c) ^ b) + block[WA[n]] + KA[3]), ROTA[n]) + e; \ + f = rol(f + (( g ^ h ^ i) + block[WB[n]]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define R160_0 \ + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_0_TO_15(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_0_TO_15(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_0_TO_15(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_0_TO_15(b,c,d,e,a,g,h,i,j,f) + +#define R160_16 \ + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_16_TO_31(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_16_TO_31(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_16_TO_31(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) + +#define R160_32 \ + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_32_TO_47(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_32_TO_47(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_32_TO_47(e,a,b,c,d,j,f,g,h,i) + +#define R160_48 \ + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_48_TO_63(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_48_TO_63(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_48_TO_63(d,e,a,b,c,i,j,f,g,h) + +#define R160_64 \ + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_64_TO_79(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_64_TO_79(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_64_TO_79(c,d,e,a,b,h,i,j,f,g) + +static void ripemd160_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; + uint32_t block[16]; + int n; + + a = f = state[0]; + b = g = state[1]; + c = h = state[2]; + d = i = state[3]; + e = j = state[4]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 32;) { + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 48;) { + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 64;) { + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 80;) { + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } +#else + + R160_0; R160_0; R160_0; + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + + R160_16; R160_16; R160_16; + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); + + R160_32; R160_32; R160_32; + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); + + R160_48; R160_48; R160_48; + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); + + R160_64; R160_64; R160_64; + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); +#endif + + i += c + state[1]; + state[1] = state[2] + d + j; + state[2] = state[3] + e + f; + state[3] = state[4] + a + g; + state[4] = state[0] + b + h; + state[0] = i; +} + +static void ripemd320_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; + uint32_t block[16]; + int n; + + a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; + f = state[5]; g = state[6]; h = state[7]; i = state[8]; j = state[9]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, b, g); + + for (; n < 32;) { + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, d, i); + + for (; n < 48;) { + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, a, f); + + for (; n < 64;) { + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, c, h); + + for (; n < 80;) { + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, e, j); +#else + + R160_0; R160_0; R160_0; + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + FFSWAP(uint32_t, a, f); + + R160_16; R160_16; R160_16; + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); + FFSWAP(uint32_t, b, g); + + R160_32; R160_32; R160_32; + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); + FFSWAP(uint32_t, c, h); + + R160_48; R160_48; R160_48; + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); + FFSWAP(uint32_t, d, i); + + R160_64; R160_64; R160_64; + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); + FFSWAP(uint32_t, e, j); +#endif + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; + state[5] += f; state[6] += g; state[7] += h; state[8] += i; state[9] += j; +} + +av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits) +{ + ctx->digest_len = bits >> 5; + switch (bits) { + case 128: // RIPEMD-128 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->transform = ripemd128_transform; + break; + case 160: // RIPEMD-160 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->transform = ripemd160_transform; + break; + case 256: // RIPEMD-256 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0x76543210; + ctx->state[5] = 0xFEDCBA98; + ctx->state[6] = 0x89ABCDEF; + ctx->state[7] = 0x01234567; + ctx->transform = ripemd256_transform; + break; + case 320: // RIPEMD-320 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->state[5] = 0x76543210; + ctx->state[6] = 0xFEDCBA98; + ctx->state[7] = 0x89ABCDEF; + ctx->state[8] = 0x01234567; + ctx->state[9] = 0x3C2D1E0F; + ctx->transform = ripemd320_transform; + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +void av_ripemd_update(AVRIPEMD* ctx, const uint8_t* data, size_t len) +{ + unsigned int j; + size_t i; + + j = ctx->count & 63; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (64 == j) { + ctx->transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if (len >= 64 - j) { + const uint8_t *end; + memcpy(&ctx->buffer[j], data, (i = 64 - j)); + ctx->transform(ctx->state, ctx->buffer); + data += i; + len -= i; + end = data + (len & ~63); + len = len % 64; + for (; data < end; data += 64) + ctx->transform(ctx->state, data); + j = 0; + } + memcpy(&ctx->buffer[j], data, len); +#endif +} + +void av_ripemd_final(AVRIPEMD* ctx, uint8_t *digest) +{ + int i; + uint64_t finalcount = av_le2ne64(ctx->count << 3); + + av_ripemd_update(ctx, "\200", 1); + while ((ctx->count & 63) != 56) + av_ripemd_update(ctx, "", 1); + av_ripemd_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WL32(digest + i*4, ctx->state[i]); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/ripemd.h b/arm/raspi/third_party/ffmpeg/libavutil/ripemd.h new file mode 100644 index 00000000..9df9f905 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/ripemd.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_ripemd + * Public header for RIPEMD hash function implementation. + */ + +#ifndef AVUTIL_RIPEMD_H +#define AVUTIL_RIPEMD_H + +#include +#include + +#include "attributes.h" + +/** + * @defgroup lavu_ripemd RIPEMD + * @ingroup lavu_hash + * RIPEMD hash function implementation. + * + * @{ + */ + +extern const int av_ripemd_size; + +struct AVRIPEMD; + +/** + * Allocate an AVRIPEMD context. + */ +struct AVRIPEMD *av_ripemd_alloc(void); + +/** + * Initialize RIPEMD hashing. + * + * @param context pointer to the function context (of size av_ripemd_size) + * @param bits number of bits in digest (128, 160, 256 or 320 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_ripemd_init(struct AVRIPEMD* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, size_t len); + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_ripemd_final(struct AVRIPEMD* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_RIPEMD_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/riscv/Makefile new file mode 100644 index 00000000..1597154b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/Makefile @@ -0,0 +1,5 @@ +OBJS += riscv/float_dsp_init.o \ + riscv/fixed_dsp_init.o \ + riscv/cpu.o +RVV-OBJS += riscv/float_dsp_rvv.o \ + riscv/fixed_dsp_rvv.o diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/asm.S b/arm/raspi/third_party/ffmpeg/libavutil/riscv/asm.S new file mode 100644 index 00000000..6ca74f26 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/asm.S @@ -0,0 +1,169 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * Loosely based on earlier work copyrighted by Måns Rullgård, 2008. + * + * 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 + */ + +#if defined (__riscv_float_abi_soft) +#define NOHWF +#define NOHWD +#define HWF # +#define HWD # +#elif defined (__riscv_float_abi_single) +#define NOHWF # +#define NOHWD +#define HWF +#define HWD # +#else +#define NOHWF # +#define NOHWD # +#define HWF +#define HWD +#endif + + .macro func sym, ext= + .text + .align 2 + + .option push + .ifnb \ext + .option arch, +\ext + .endif + + .global \sym + .hidden \sym + .type \sym, %function + \sym: + + .macro endfunc + .size \sym, . - \sym + .option pop + .previous + .purgem endfunc + .endm + .endm + + .macro const sym, align=3, relocate=0 + .if \relocate + .pushsection .data.rel.ro + .else + .pushsection .rodata + .endif + .align \align + \sym: + + .macro endconst + .size \sym, . - \sym + .popsection + .purgem endconst + .endm + .endm + +#if !defined (__riscv_zba) + /* SH{1,2,3}ADD definitions for pre-Zba assemblers */ + .macro shnadd n, rd, rs1, rs2 + .insn r OP, 2 * \n, 16, \rd, \rs1, \rs2 + .endm + + .macro sh1add rd, rs1, rs2 + shnadd 1, \rd, \rs1, \rs2 + .endm + + .macro sh2add rd, rs1, rs2 + shnadd 2, \rd, \rs1, \rs2 + .endm + + .macro sh3add rd, rs1, rs2 + shnadd 3, \rd, \rs1, \rs2 + .endm +#endif + + /* Convenience macro to load a Vector type (vtype) as immediate */ + .macro lvtypei rd, e, m=m1, tp=tu, mp=mu + + .ifc \e,e8 + .equ ei, 0 + .else + .ifc \e,e16 + .equ ei, 8 + .else + .ifc \e,e32 + .equ ei, 16 + .else + .ifc \e,e64 + .equ ei, 24 + .else + .error "Unknown element type" + .endif + .endif + .endif + .endif + + .ifc \m,m1 + .equ mi, 0 + .else + .ifc \m,m2 + .equ mi, 1 + .else + .ifc \m,m4 + .equ mi, 2 + .else + .ifc \m,m8 + .equ mi, 3 + .else + .ifc \m,mf8 + .equ mi, 5 + .else + .ifc \m,mf4 + .equ mi, 6 + .else + .ifc \m,mf2 + .equ mi, 7 + .else + .error "Unknown multiplier" + .equ mi, 3 + .endif + .endif + .endif + .endif + .endif + .endif + .endif + + .ifc \tp,tu + .equ tpi, 0 + .else + .ifc \tp,ta + .equ tpi, 64 + .else + .error "Unknown tail policy" + .endif + .endif + + .ifc \mp,mu + .equ mpi, 0 + .else + .ifc \mp,ma + .equ mpi, 128 + .else + .error "Unknown mask policy" + .endif + .endif + + li \rd, (ei | mi | tpi | mpi) + .endm diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/riscv/bswap.h new file mode 100644 index 00000000..de1429c0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/bswap.h @@ -0,0 +1,74 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RISCV_BSWAP_H +#define AVUTIL_RISCV_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if defined (__riscv_zbb) && (__riscv_zbb > 0) && HAVE_INLINE_ASM + +static av_always_inline av_const uintptr_t av_bswap_xlen(uintptr_t x) +{ + uintptr_t y; + + __asm__("rev8 %0, %1" : "=r" (y) : "r" (x)); + return y; +} + +#define av_bswap16 av_bswap16 + +static av_always_inline av_const uint_fast16_t av_bswap16(uint_fast16_t x) +{ + return av_bswap_xlen(x) >> (__riscv_xlen - 16); +} + +#if (__riscv_xlen == 32) +#define av_bswap32 av_bswap_xlen +#define av_bswap64 av_bswap64 + +static av_always_inline av_const uint64_t av_bswap64(uint64_t x) +{ + return (((uint64_t)av_bswap32(x)) << 32) | av_bswap32(x >> 32); +} + +#else +#define av_bswap32 av_bswap32 + +static av_always_inline av_const uint_fast32_t av_bswap32(uint_fast32_t x) +{ + return av_bswap_xlen(x) >> (__riscv_xlen - 32); +} + +#if (__riscv_xlen == 64) +#define av_bswap64 av_bswap_xlen + +#else +#define av_bswap64 av_bswap64 + +static av_always_inline av_const uint_fast64_t av_bswap64(uint_fast64_t x) +{ + return av_bswap_xlen(x) >> (__riscv_xlen - 64); +} + +#endif /* __riscv_xlen > 64 */ +#endif /* __riscv_xlen > 32 */ +#endif /* __riscv_zbb */ +#endif /* AVUTIL_RISCV_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.c new file mode 100644 index 00000000..a9263dbb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "libavutil/log.h" +#include "config.h" + +#if HAVE_GETAUXVAL +#include +#define HWCAP_RV(letter) (1ul << ((letter) - 'A')) +#endif + +int ff_get_cpu_flags_riscv(void) +{ + int ret = 0; +#if HAVE_GETAUXVAL + const unsigned long hwcap = getauxval(AT_HWCAP); + + if (hwcap & HWCAP_RV('I')) + ret |= AV_CPU_FLAG_RVI; + if (hwcap & HWCAP_RV('F')) + ret |= AV_CPU_FLAG_RVF; + if (hwcap & HWCAP_RV('D')) + ret |= AV_CPU_FLAG_RVD; + if (hwcap & HWCAP_RV('B')) + ret |= AV_CPU_FLAG_RVB_BASIC; + + /* The V extension implies all Zve* functional subsets */ + if (hwcap & HWCAP_RV('V')) + ret |= AV_CPU_FLAG_RVV_I32 | AV_CPU_FLAG_RVV_I64 + | AV_CPU_FLAG_RVV_F32 | AV_CPU_FLAG_RVV_F64; +#endif + +#ifdef __riscv_i + ret |= AV_CPU_FLAG_RVI; +#endif +#if defined (__riscv_flen) && (__riscv_flen >= 32) + ret |= AV_CPU_FLAG_RVF; +#if (__riscv_flen >= 64) + ret |= AV_CPU_FLAG_RVD; +#endif +#endif + +#ifdef __riscv_zbb + ret |= AV_CPU_FLAG_RVB_BASIC; +#endif + + /* If RV-V is enabled statically at compile-time, check the details. */ +#ifdef __riscv_vectors + ret |= AV_CPU_FLAG_RVV_I32; +#if __riscv_v_elen >= 64 + ret |= AV_CPU_FLAG_RVV_I64; +#endif +#if __riscv_v_elen_fp >= 32 + ret |= AV_CPU_FLAG_RVV_F32; +#if __riscv_v_elen_fp >= 64 + ret |= AV_CPU_FLAG_RVV_F64; +#endif +#endif +#endif + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.h new file mode 100644 index 00000000..56035f85 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/cpu.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RISCV_CPU_H +#define AVUTIL_RISCV_CPU_H + +#include "config.h" +#include +#include "libavutil/cpu.h" + +#if HAVE_RVV +/** + * Returns the vector size in bytes (always a power of two and at least 4). + * This is undefined behaviour if vectors are not implemented. + */ +static inline size_t ff_get_rv_vlenb(void) +{ + size_t vlenb; + + __asm__ ( + ".option push\n" + ".option arch, +v\n" + " csrr %0, vlenb\n" + ".option pop\n" : "=r" (vlenb)); + return vlenb; +} +#endif +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_init.c new file mode 100644 index 00000000..e2915f1f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_init.c @@ -0,0 +1,38 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/fixed_dsp.h" + +void ff_butterflies_fixed_rvv(int *v1, int *v2, int len); + +av_cold void ff_fixed_dsp_init_riscv(AVFixedDSPContext *fdsp) +{ +#if HAVE_RVV + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_RVV_I32) + fdsp->butterflies_fixed = ff_butterflies_fixed_rvv; +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_rvv.S b/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_rvv.S new file mode 100644 index 00000000..a91316e1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/fixed_dsp_rvv.S @@ -0,0 +1,39 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.S" + +// (a0) = (a0) + (a1), (a1) = (a0) - (a1) [0..a2-1] +func ff_butterflies_fixed_rvv, zve32x +1: + vsetvli t0, a2, e32, m1, ta, ma + vle32.v v16, (a0) + sub a2, a2, t0 + vle32.v v24, (a1) + vadd.vv v0, v16, v24 + vsub.vv v8, v16, v24 + vse32.v v0, (a0) + sh2add a0, t0, a0 + vse32.v v8, (a1) + sh2add a1, t0, a1 + bnez a2, 1b + + ret +endfunc diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_init.c new file mode 100644 index 00000000..e61f8878 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_init.c @@ -0,0 +1,72 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" + +void ff_vector_fmul_rvv(float *dst, const float *src0, const float *src1, + int len); +void ff_vector_fmac_scalar_rvv(float *dst, const float *src, float mul, + int len); +void ff_vector_fmul_scalar_rvv(float *dst, const float *src, float mul, + int len); +void ff_vector_fmul_window_rvv(float *dst, const float *src0, + const float *src1, const float *win, int len); +void ff_vector_fmul_add_rvv(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_reverse_rvv(float *dst, const float *src0, + const float *src1, int len); +void ff_butterflies_float_rvv(float *v1, float *v2, int len); +float ff_scalarproduct_float_rvv(const float *v1, const float *v2, int len); + +void ff_vector_dmul_rvv(double *dst, const double *src0, const double *src1, + int len); +void ff_vector_dmac_scalar_rvv(double *dst, const double *src, double mul, + int len); +void ff_vector_dmul_scalar_rvv(double *dst, const double *src, double mul, + int len); + +av_cold void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp) +{ +#if HAVE_RVV + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_RVV_F32) { + fdsp->vector_fmul = ff_vector_fmul_rvv; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_rvv; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_rvv; + fdsp->vector_fmul_window = ff_vector_fmul_window_rvv; + fdsp->vector_fmul_add = ff_vector_fmul_add_rvv; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_rvv; + fdsp->butterflies_float = ff_butterflies_float_rvv; + fdsp->scalarproduct_float = ff_scalarproduct_float_rvv; + } + + if (flags & AV_CPU_FLAG_RVV_F64) { + fdsp->vector_dmul = ff_vector_dmul_rvv; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_rvv; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_rvv; + } +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_rvv.S b/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_rvv.S new file mode 100644 index 00000000..77961b73 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/float_dsp_rvv.S @@ -0,0 +1,237 @@ +/* + * Copyright © 2022 Rémi Denis-Courmont. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.S" + +// (a0) = (a1) * (a2) [0..a3-1] +func ff_vector_fmul_rvv, zve32f +1: + vsetvli t0, a3, e32, m1, ta, ma + vle32.v v16, (a1) + sub a3, a3, t0 + vle32.v v24, (a2) + sh2add a1, t0, a1 + vfmul.vv v16, v16, v24 + sh2add a2, t0, a2 + vse32.v v16, (a0) + sh2add a0, t0, a0 + bnez a3, 1b + + ret +endfunc + +// (a0) += (a1) * fa0 [0..a2-1] +func ff_vector_fmac_scalar_rvv, zve32f +NOHWF fmv.w.x fa0, a2 +NOHWF mv a2, a3 +1: + vsetvli t0, a2, e32, m1, ta, ma + slli t1, t0, 2 + vle32.v v24, (a1) + sub a2, a2, t0 + vle32.v v16, (a0) + sh2add a1, t0, a1 + vfmacc.vf v16, fa0, v24 + vse32.v v16, (a0) + sh2add a0, t0, a0 + bnez a2, 1b + + ret +endfunc + +// (a0) = (a1) * fa0 [0..a2-1] +func ff_vector_fmul_scalar_rvv, zve32f +NOHWF fmv.w.x fa0, a2 +NOHWF mv a2, a3 +1: + vsetvli t0, a2, e32, m1, ta, ma + vle32.v v16, (a1) + sub a2, a2, t0 + vfmul.vf v16, v16, fa0 + sh2add a1, t0, a1 + vse32.v v16, (a0) + sh2add a0, t0, a0 + bnez a2, 1b + + ret +endfunc + +func ff_vector_fmul_window_rvv, zve32f + // a0: dst, a1: src0, a2: src1, a3: window, a4: length + addi t0, a4, -1 + add t1, t0, a4 + sh2add a2, t0, a2 + sh2add t0, t1, a0 + sh2add t3, t1, a3 + li t1, -4 // byte stride +1: + vsetvli t2, a4, e32, m1, ta, ma + vle32.v v16, (a1) + slli t4, t2, 2 + vlse32.v v20, (a2), t1 + sub a4, a4, t2 + vle32.v v24, (a3) + add a1, a1, t4 + vlse32.v v28, (t3), t1 + sub a2, a2, t4 + vfmul.vv v0, v16, v28 + add a3, a3, t4 + vfmul.vv v8, v16, v24 + sub t3, t3, t4 + vfnmsac.vv v0, v20, v24 + vfmacc.vv v8, v20, v28 + vse32.v v0, (a0) + add a0, a0, t4 + vsse32.v v8, (t0), t1 + sub t0, t0, t4 + bnez a4, 1b + + ret +endfunc + +// (a0) = (a1) * (a2) + (a3) [0..a4-1] +func ff_vector_fmul_add_rvv, zve32f +1: + vsetvli t0, a4, e32, m1, ta, ma + vle32.v v8, (a1) + sub a4, a4, t0 + vle32.v v16, (a2) + sh2add a1, t0, a1 + vle32.v v24, (a3) + sh2add a2, t0, a2 + vfmadd.vv v8, v16, v24 + sh2add a3, t0, a3 + vse32.v v8, (a0) + sh2add a0, t0, a0 + bnez a4, 1b + + ret +endfunc + +// (a0) = (a1) * reverse(a2) [0..a3-1] +func ff_vector_fmul_reverse_rvv, zve32f + sh2add a2, a3, a2 + li t2, -4 // byte stride + addi a2, a2, -4 +1: + vsetvli t0, a3, e32, m1, ta, ma + slli t1, t0, 2 + vle32.v v16, (a1) + sub a3, a3, t0 + vlse32.v v24, (a2), t2 + add a1, a1, t1 + vfmul.vv v16, v16, v24 + sub a2, a2, t1 + vse32.v v16, (a0) + add a0, a0, t1 + bnez a3, 1b + + ret +endfunc + +// (a0) = (a0) + (a1), (a1) = (a0) - (a1) [0..a2-1] +func ff_butterflies_float_rvv, zve32f +1: + vsetvli t0, a2, e32, m1, ta, ma + vle32.v v16, (a0) + sub a2, a2, t0 + vle32.v v24, (a1) + vfadd.vv v0, v16, v24 + vfsub.vv v8, v16, v24 + vse32.v v0, (a0) + sh2add a0, t0, a0 + vse32.v v8, (a1) + sh2add a1, t0, a1 + bnez a2, 1b + + ret +endfunc + +// a0 = (a0).(a1) [0..a2-1] +func ff_scalarproduct_float_rvv, zve32f + vsetivli zero, 1, e32, m1, ta, ma + vmv.s.x v8, zero +1: + vsetvli t0, a2, e32, m1, ta, ma + vle32.v v16, (a0) + sub a2, a2, t0 + vle32.v v24, (a1) + sh2add a0, t0, a0 + vfmul.vv v16, v16, v24 + sh2add a1, t0, a1 + vfredusum.vs v8, v16, v8 + bnez a2, 1b + + vfmv.f.s fa0, v8 +NOHWF fmv.x.w a0, fa0 + ret +endfunc + +// (a0) = (a1) * (a2) [0..a3-1] +func ff_vector_dmul_rvv, zve64d +1: + vsetvli t0, a3, e64, m1, ta, ma + vle64.v v16, (a1) + sub a3, a3, t0 + vle64.v v24, (a2) + sh3add a1, t0, a1 + vfmul.vv v16, v16, v24 + sh3add a2, t0, a2 + vse64.v v16, (a0) + sh3add a0, t0, a0 + bnez a3, 1b + + ret +endfunc + +// (a0) += (a1) * fa0 [0..a2-1] +func ff_vector_dmac_scalar_rvv, zve64d +NOHWD fmv.d.x fa0, a2 +NOHWD mv a2, a3 +1: + vsetvli t0, a2, e64, m1, ta, ma + vle64.v v24, (a1) + sub a2, a2, t0 + vle64.v v16, (a0) + sh3add a1, t0, a1 + vfmacc.vf v16, fa0, v24 + vse64.v v16, (a0) + sh3add a0, t0, a0 + bnez a2, 1b + + ret +endfunc + +// (a0) = (a1) * fa0 [0..a2-1] +func ff_vector_dmul_scalar_rvv, zve64d +NOHWD fmv.d.x fa0, a2 +NOHWD mv a2, a3 +1: + vsetvli t0, a2, e64, m1, ta, ma + vle64.v v16, (a1) + sub a2, a2, t0 + vfmul.vf v16, v16, fa0 + sh3add a1, t0, a1 + vse64.v v16, (a0) + sh3add a0, t0, a0 + bnez a2, 1b + + ret +endfunc diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/intmath.h b/arm/raspi/third_party/ffmpeg/libavutil/riscv/intmath.h new file mode 100644 index 00000000..45bce9a0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/intmath.h @@ -0,0 +1,103 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RISCV_INTMATH_H +#define AVUTIL_RISCV_INTMATH_H + +#include + +#include "config.h" +#include "libavutil/attributes.h" + +/* + * The compiler is forced to sign-extend the result anyhow, so it is faster to + * compute it explicitly and use it. + */ +#define av_clip_int8 av_clip_int8_rvi +static av_always_inline av_const int8_t av_clip_int8_rvi(int a) +{ + union { uint8_t u; int8_t s; } u = { .u = a }; + + if (a != u.s) + a = ((a >> 31) ^ 0x7F); + return a; +} + +#define av_clip_int16 av_clip_int16_rvi +static av_always_inline av_const int16_t av_clip_int16_rvi(int a) +{ + union { uint16_t u; int16_t s; } u = { .u = a }; + + if (a != u.s) + a = ((a >> 31) ^ 0x7FFF); + return a; +} + +#define av_clipl_int32 av_clipl_int32_rvi +static av_always_inline av_const int32_t av_clipl_int32_rvi(int64_t a) +{ + union { uint32_t u; int32_t s; } u = { .u = a }; + + if (a != u.s) + a = ((a >> 63) ^ 0x7FFFFFFF); + return a; +} + +#define av_clip_intp2 av_clip_intp2_rvi +static av_always_inline av_const int av_clip_intp2_rvi(int a, int p) +{ + const int shift = 31 - p; + int b = ((int)(((unsigned)a) << shift)) >> shift; + + if (a != b) + b = (a >> 31) ^ ((1 << p) - 1); + return b; +} + +#if defined (__riscv_zbb) && (__riscv_zbb > 0) && HAVE_INLINE_ASM + +#define av_popcount av_popcount_rvb +static av_always_inline av_const int av_popcount_rvb(uint32_t x) +{ + int ret; + +#if (__riscv_xlen >= 64) + __asm__ ("cpopw %0, %1\n" : "=r" (ret) : "r" (x)); +#else + __asm__ ("cpop %0, %1\n" : "=r" (ret) : "r" (x)); +#endif + return ret; +} + +#if (__riscv_xlen >= 64) +#define av_popcount64 av_popcount64_rvb +static av_always_inline av_const int av_popcount64_rvb(uint64_t x) +{ + int ret; + +#if (__riscv_xlen >= 128) + __asm__ ("cpopd %0, %1\n" : "=r" (ret) : "r" (x)); +#else + __asm__ ("cpop %0, %1\n" : "=r" (ret) : "r" (x)); +#endif + return ret; +} +#endif /* __riscv_xlen >= 64 */ +#endif /* __riscv_zbb */ + +#endif /* AVUTIL_RISCV_INTMATH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/riscv/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/riscv/timer.h new file mode 100644 index 00000000..a34157a5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/riscv/timer.h @@ -0,0 +1,53 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RISCV_TIMER_H +#define AVUTIL_RISCV_TIMER_H + +#include "config.h" + +#if HAVE_INLINE_ASM +#include + +static inline uint64_t rdcycle64(void) +{ +#if (__riscv_xlen >= 64) + uintptr_t cycles; + + __asm__ volatile ("rdcycle %0" : "=r"(cycles)); + +#else + uint64_t cycles; + uint32_t hi, lo, check; + + __asm__ volatile ( + "1: rdcycleh %0\n" + " rdcycle %1\n" + " rdcycleh %2\n" + " bne %0, %2, 1b\n" : "=r" (hi), "=r" (lo), "=r" (check)); + + cycles = (((uint64_t)hi) << 32) | lo; + +#endif + return cycles; +} + +#define AV_READ_TIME rdcycle64 + +#endif +#endif /* AVUTIL_RISCV_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.c b/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.c new file mode 100644 index 00000000..6d3ec34d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.c @@ -0,0 +1,263 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "error.h" +#include "macros.h" +#include "mem.h" +#include "samplefmt.h" + +#include +#include +#include + +typedef struct SampleFmtInfo { + char name[8]; + int bits; + int planar; + enum AVSampleFormat altform; ///< planar<->packed alternative form +} SampleFmtInfo; + +/** this table gives more information about formats */ +static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = { + [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P }, + [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P }, + [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P }, + [AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P }, + [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP }, + [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP }, + [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 }, + [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 }, + [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 }, + [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 }, + [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT }, + [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL }, +}; + +const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return NULL; + return sample_fmt_info[sample_fmt].name; +} + +enum AVSampleFormat av_get_sample_fmt(const char *name) +{ + int i; + + for (i = 0; i < AV_SAMPLE_FMT_NB; i++) + if (!strcmp(sample_fmt_info[i].name, name)) + return i; + return AV_SAMPLE_FMT_NONE; +} + +enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar == planar) + return sample_fmt; + return sample_fmt_info[sample_fmt].altform; +} + +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar) + return sample_fmt_info[sample_fmt].altform; + return sample_fmt; +} + +enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar) + return sample_fmt; + return sample_fmt_info[sample_fmt].altform; +} + +char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt) +{ + /* print header */ + if (sample_fmt < 0) + snprintf(buf, buf_size, "name " " depth"); + else if (sample_fmt < AV_SAMPLE_FMT_NB) { + SampleFmtInfo info = sample_fmt_info[sample_fmt]; + snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits); + } + + return buf; +} + +int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt) +{ + return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ? + 0 : sample_fmt_info[sample_fmt].bits >> 3; +} + +int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return 0; + return sample_fmt_info[sample_fmt].planar; +} + +int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align) +{ + int line_size; + int sample_size = av_get_bytes_per_sample(sample_fmt); + int planar = av_sample_fmt_is_planar(sample_fmt); + + /* validate parameter ranges */ + if (!sample_size || nb_samples <= 0 || nb_channels <= 0) + return AVERROR(EINVAL); + + /* auto-select alignment if not specified */ + if (!align) { + if (nb_samples > INT_MAX - 31) + return AVERROR(EINVAL); + align = 1; + nb_samples = FFALIGN(nb_samples, 32); + } + + /* check for integer overflow */ + if (nb_channels > INT_MAX / align || + (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size) + return AVERROR(EINVAL); + + line_size = planar ? FFALIGN(nb_samples * sample_size, align) : + FFALIGN(nb_samples * sample_size * nb_channels, align); + if (linesize) + *linesize = line_size; + + return planar ? line_size * nb_channels : line_size; +} + +int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, + const uint8_t *buf, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align) +{ + int ch, planar, buf_size, line_size; + + planar = av_sample_fmt_is_planar(sample_fmt); + buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples, + sample_fmt, align); + if (buf_size < 0) + return buf_size; + + if (linesize) + *linesize = line_size; + + memset(audio_data, 0, planar + ? sizeof(*audio_data) * nb_channels + : sizeof(*audio_data)); + + if (!buf) + return buf_size; + + audio_data[0] = (uint8_t *)buf; + for (ch = 1; planar && ch < nb_channels; ch++) + audio_data[ch] = audio_data[ch-1] + line_size; + + return buf_size; +} + +int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align) +{ + uint8_t *buf; + int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples, + sample_fmt, align); + if (size < 0) + return size; + + buf = av_malloc(size); + if (!buf) + return AVERROR(ENOMEM); + + size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels, + nb_samples, sample_fmt, align); + if (size < 0) { + av_free(buf); + return size; + } + + av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt); + + return size; +} + +int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align) +{ + int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1; + + *audio_data = av_calloc(nb_planes, sizeof(**audio_data)); + if (!*audio_data) + return AVERROR(ENOMEM); + ret = av_samples_alloc(*audio_data, linesize, nb_channels, + nb_samples, sample_fmt, align); + if (ret < 0) + av_freep(audio_data); + return ret; +} + +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int i; + + dst_offset *= block_align; + src_offset *= block_align; + + if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) { + for (i = 0; i < planes; i++) + memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size); + } else { + for (i = 0; i < planes; i++) + memmove(dst[i] + dst_offset, src[i] + src_offset, data_size); + } + + return 0; +} + +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 || + sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00; + int i; + + offset *= block_align; + + for (i = 0; i < planes; i++) + memset(audio_data[i] + offset, fill_char, data_size); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.h b/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.h new file mode 100644 index 00000000..6bad0e25 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/samplefmt.h @@ -0,0 +1,269 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SAMPLEFMT_H +#define AVUTIL_SAMPLEFMT_H + +#include + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_sampfmts Audio sample formats + * + * Audio sample format enumeration and related convenience functions. + * @{ + */ + +/** + * Audio sample formats + * + * - The data described by the sample format is always in native-endian order. + * Sample values can be expressed by native C types, hence the lack of a signed + * 24-bit sample format even though it is a common raw audio data format. + * + * - The floating-point formats are based on full volume being in the range + * [-1.0, 1.0]. Any values outside this range are beyond full volume level. + * + * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg + * (such as AVFrame in libavcodec) is as follows: + * + * @par + * For planar sample formats, each audio channel is in a separate data plane, + * and linesize is the buffer size, in bytes, for a single plane. All data + * planes must be the same size. For packed sample formats, only the first data + * plane is used, and samples for each channel are interleaved. In this case, + * linesize is the buffer size, in bytes, for the 1 plane. + * + */ +enum AVSampleFormat { + AV_SAMPLE_FMT_NONE = -1, + AV_SAMPLE_FMT_U8, ///< unsigned 8 bits + AV_SAMPLE_FMT_S16, ///< signed 16 bits + AV_SAMPLE_FMT_S32, ///< signed 32 bits + AV_SAMPLE_FMT_FLT, ///< float + AV_SAMPLE_FMT_DBL, ///< double + + AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar + AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar + AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar + AV_SAMPLE_FMT_FLTP, ///< float, planar + AV_SAMPLE_FMT_DBLP, ///< double, planar + AV_SAMPLE_FMT_S64, ///< signed 64 bits + AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar + + AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically +}; + +/** + * Return the name of sample_fmt, or NULL if sample_fmt is not + * recognized. + */ +const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt); + +/** + * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE + * on error. + */ +enum AVSampleFormat av_get_sample_fmt(const char *name); + +/** + * Return the planar<->packed alternative form of the given sample format, or + * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the + * requested planar/packed format, the format returned is the same as the + * input. + */ +enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar); + +/** + * Get the packed alternative form of the given sample format. + * + * If the passed sample_fmt is already in packed format, the format returned is + * the same as the input. + * + * @return the packed alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Get the planar alternative form of the given sample format. + * + * If the passed sample_fmt is already in planar format, the format returned is + * the same as the input. + * + * @return the planar alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Generate a string corresponding to the sample format with + * sample_fmt, or a header if sample_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param sample_fmt the number of the sample format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + * @return the pointer to the filled buffer or NULL if sample_fmt is + * unknown or in case of other errors + */ +char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt); + +/** + * Return number of bytes per sample. + * + * @param sample_fmt the sample format + * @return number of bytes per sample or zero if unknown for the given + * sample format + */ +int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); + +/** + * Check if the sample format is planar. + * + * @param sample_fmt the sample format to inspect + * @return 1 if the sample format is planar, 0 if it is interleaved + */ +int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); + +/** + * Get the required buffer size for the given audio parameters. + * + * @param[out] linesize calculated linesize, may be NULL + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return required buffer size, or negative error code on failure + */ +int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * @} + * + * @defgroup lavu_sampmanip Samples manipulation + * + * Functions that manipulate audio samples + * @{ + */ + +/** + * Fill plane data pointers and linesize for samples with sample + * format sample_fmt. + * + * The audio_data array is filled with the pointers to the samples data planes: + * for planar, set the start point of each channel's data within the buffer, + * for packed, set the start point of the entire buffer only. + * + * The value pointed to by linesize is set to the aligned size of each + * channel's data buffer for planar layout, or to the aligned size of the + * buffer for all channels for packed layout. + * + * The buffer in buf must be big enough to contain all the samples + * (use av_samples_get_buffer_size() to compute its minimum size), + * otherwise the audio_data pointers will point to invalid data. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize calculated linesize, may be NULL + * @param buf the pointer to a buffer containing the samples + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return minimum size in bytes required for the buffer on success, + * or a negative error code on failure + */ +int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, + const uint8_t *buf, + int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a samples buffer for nb_samples samples, and fill data pointers and + * linesize accordingly. + * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) + * Allocated data will be initialized to silence. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize aligned size for audio buffer(s), may be NULL + * @param nb_channels number of audio channels + * @param nb_samples number of samples per channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return >=0 on success or a negative error code on failure + * @todo return the size of the allocated buffer in case of success at the next bump + * @see av_samples_fill_arrays() + * @see av_samples_alloc_array_and_samples() + */ +int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a data pointers array, samples buffer for nb_samples + * samples, and fill data pointers and linesize accordingly. + * + * This is the same as av_samples_alloc(), but also allocates the data + * pointers array. + * + * @see av_samples_alloc() + */ +int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Copy samples from src to dst. + * + * @param dst destination array of pointers to data planes + * @param src source array of pointers to data planes + * @param dst_offset offset in samples at which the data will be written to dst + * @param src_offset offset in samples at which the data will be read from src + * @param nb_samples number of samples to be copied + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt); + +/** + * Fill an audio buffer with silence. + * + * @param audio_data array of pointers to data planes + * @param offset offset in samples at which to start filling + * @param nb_samples number of samples to fill + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt); + +/** + * @} + * @} + */ +#endif /* AVUTIL_SAMPLEFMT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/sh4/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/sh4/bswap.h new file mode 100644 index 00000000..48dd27f8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/sh4/bswap.h @@ -0,0 +1,48 @@ +/* + * 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 + * byte swapping routines + */ + +#ifndef AVUTIL_SH4_BSWAP_H +#define AVUTIL_SH4_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#define av_bswap16 av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + __asm__("swap.b %0,%0" : "+r"(x)); + return x; +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__("swap.b %0,%0\n" + "swap.w %0,%0\n" + "swap.b %0,%0\n" + : "+r"(x)); + return x; +} + +#endif /* AVUTIL_SH4_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/sha.c b/arm/raspi/third_party/ffmpeg/libavutil/sha.c new file mode 100644 index 00000000..0df04403 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/sha.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2009 Konstantin Shishkov + * based on public domain SHA-1 code by Steve Reid + * and on BSD-licensed SHA-2 code by Aaron D. Gifford + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "attributes.h" +#include "bswap.h" +#include "error.h" +#include "sha.h" +#include "intreadwrite.h" +#include "mem.h" + +/** hash context */ +typedef struct AVSHA { + uint8_t digest_len; ///< digest length in 32-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating + uint32_t state[8]; ///< current hash value + /** function used to update hash for 512-bit input block */ + void (*transform)(uint32_t *state, const uint8_t buffer[64]); +} AVSHA; + +const int av_sha_size = sizeof(AVSHA); + +struct AVSHA *av_sha_alloc(void) +{ + return av_mallocz(sizeof(struct AVSHA)); +} + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define blk0(i) (block[i] = AV_RB32(buffer + 4 * (i))) +#define blk(i) (block[i] = rol(block[(i)-3] ^ block[(i)-8] ^ block[(i)-14] ^ block[(i)-16], 1)) + +#define R0(v,w,x,y,z,i) z += (((w)&((x)^(y)))^(y)) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); +#define R1(v,w,x,y,z,i) z += (((w)&((x)^(y)))^(y)) + blk (i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); +#define R2(v,w,x,y,z,i) z += ( (w)^(x) ^(y)) + blk (i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); +#define R3(v,w,x,y,z,i) z += ((((w)|(x))&(y))|((w)&(x))) + blk (i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30); +#define R4(v,w,x,y,z,i) z += ( (w)^(x) ^(y)) + blk (i) + 0xCA62C1D6 + rol(v, 5); w = rol(w, 30); + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void sha1_transform(uint32_t state[5], const uint8_t buffer[64]) +{ + uint32_t block[80]; + unsigned int i, a, b, c, d, e; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; +#if CONFIG_SMALL + for (i = 0; i < 80; i++) { + int t; + if (i < 16) + t = AV_RB32(buffer + 4 * i); + else + t = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1); + block[i] = t; + t += e + rol(a, 5); + if (i < 40) { + if (i < 20) + t += ((b&(c^d))^d) + 0x5A827999; + else + t += ( b^c ^d) + 0x6ED9EBA1; + } else { + if (i < 60) + t += (((b|c)&d)|(b&c)) + 0x8F1BBCDC; + else + t += ( b^c ^d) + 0xCA62C1D6; + } + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } +#else + +#define R1_0 \ + R0(a, b, c, d, e, 0 + i); \ + R0(e, a, b, c, d, 1 + i); \ + R0(d, e, a, b, c, 2 + i); \ + R0(c, d, e, a, b, 3 + i); \ + R0(b, c, d, e, a, 4 + i); \ + i += 5 + + i = 0; + R1_0; R1_0; R1_0; + R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); + R1(d, e, a, b, c, 17); + R1(c, d, e, a, b, 18); + R1(b, c, d, e, a, 19); + +#define R1_20 \ + R2(a, b, c, d, e, 0 + i); \ + R2(e, a, b, c, d, 1 + i); \ + R2(d, e, a, b, c, 2 + i); \ + R2(c, d, e, a, b, 3 + i); \ + R2(b, c, d, e, a, 4 + i); \ + i += 5 + + i = 20; + R1_20; R1_20; R1_20; R1_20; + +#define R1_40 \ + R3(a, b, c, d, e, 0 + i); \ + R3(e, a, b, c, d, 1 + i); \ + R3(d, e, a, b, c, 2 + i); \ + R3(c, d, e, a, b, 3 + i); \ + R3(b, c, d, e, a, 4 + i); \ + i += 5 + + R1_40; R1_40; R1_40; R1_40; + +#define R1_60 \ + R4(a, b, c, d, e, 0 + i); \ + R4(e, a, b, c, d, 1 + i); \ + R4(d, e, a, b, c, 2 + i); \ + R4(c, d, e, a, b, 3 + i); \ + R4(b, c, d, e, a, 4 + i); \ + i += 5 + + R1_60; R1_60; R1_60; R1_60; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +static const uint32_t K256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + + +#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(z,y,x) ((((x) | (y)) & (z)) | ((x) & (y))) + +#define Sigma0_256(x) (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10)) +#define Sigma1_256(x) (rol((x), 26) ^ rol((x), 21) ^ rol((x), 7)) +#define sigma0_256(x) (rol((x), 25) ^ rol((x), 14) ^ ((x) >> 3)) +#define sigma1_256(x) (rol((x), 15) ^ rol((x), 13) ^ ((x) >> 10)) + +#undef blk +#define blk(i) (block[i] = block[i - 16] + sigma0_256(block[i - 15]) + \ + sigma1_256(block[i - 2]) + block[i - 7]) + +#define ROUND256(a,b,c,d,e,f,g,h) \ + T1 += (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[i]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + i++ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = blk0(i); \ + ROUND256(a,b,c,d,e,f,g,h) + +#define ROUND256_16_TO_63(a,b,c,d,e,f,g,h) \ + T1 = blk(i); \ + ROUND256(a,b,c,d,e,f,g,h) + +static void sha256_transform(uint32_t *state, const uint8_t buffer[64]) +{ + unsigned int i, a, b, c, d, e, f, g, h; + uint32_t block[64]; + uint32_t T1; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; +#if CONFIG_SMALL + for (i = 0; i < 64; i++) { + uint32_t T2; + if (i < 16) + T1 = blk0(i); + else + T1 = blk(i); + T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } +#else + + i = 0; +#define R256_0 \ + ROUND256_0_TO_15(a, b, c, d, e, f, g, h); \ + ROUND256_0_TO_15(h, a, b, c, d, e, f, g); \ + ROUND256_0_TO_15(g, h, a, b, c, d, e, f); \ + ROUND256_0_TO_15(f, g, h, a, b, c, d, e); \ + ROUND256_0_TO_15(e, f, g, h, a, b, c, d); \ + ROUND256_0_TO_15(d, e, f, g, h, a, b, c); \ + ROUND256_0_TO_15(c, d, e, f, g, h, a, b); \ + ROUND256_0_TO_15(b, c, d, e, f, g, h, a) + + R256_0; R256_0; + +#define R256_16 \ + ROUND256_16_TO_63(a, b, c, d, e, f, g, h); \ + ROUND256_16_TO_63(h, a, b, c, d, e, f, g); \ + ROUND256_16_TO_63(g, h, a, b, c, d, e, f); \ + ROUND256_16_TO_63(f, g, h, a, b, c, d, e); \ + ROUND256_16_TO_63(e, f, g, h, a, b, c, d); \ + ROUND256_16_TO_63(d, e, f, g, h, a, b, c); \ + ROUND256_16_TO_63(c, d, e, f, g, h, a, b); \ + ROUND256_16_TO_63(b, c, d, e, f, g, h, a) + + R256_16; R256_16; R256_16; + R256_16; R256_16; R256_16; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} + + +av_cold int av_sha_init(AVSHA *ctx, int bits) +{ + ctx->digest_len = bits >> 5; + switch (bits) { + case 160: // SHA-1 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->transform = sha1_transform; + break; + case 224: // SHA-224 + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + ctx->transform = sha256_transform; + break; + case 256: // SHA-256 + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + ctx->transform = sha256_transform; + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len) +{ + unsigned int j; + size_t i; + + j = ctx->count & 63; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (64 == j) { + ctx->transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if (len >= 64 - j) { + const uint8_t *end; + memcpy(&ctx->buffer[j], data, (i = 64 - j)); + ctx->transform(ctx->state, ctx->buffer); + data += i; + len -= i; + end = data + (len & ~63); + len = len % 64; + for (; data < end; data += 64) + ctx->transform(ctx->state, data); + j = 0; + } + memcpy(&ctx->buffer[j], data, len); +#endif +} + +void av_sha_final(AVSHA* ctx, uint8_t *digest) +{ + int i; + uint64_t finalcount = av_be2ne64(ctx->count << 3); + + av_sha_update(ctx, "\200", 1); + while ((ctx->count & 63) != 56) + av_sha_update(ctx, "", 1); + av_sha_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WB32(digest + i*4, ctx->state[i]); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/sha.h b/arm/raspi/third_party/ffmpeg/libavutil/sha.h new file mode 100644 index 00000000..2e1220ab --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/sha.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha + * Public header for SHA-1 & SHA-256 hash function implementations. + */ + +#ifndef AVUTIL_SHA_H +#define AVUTIL_SHA_H + +#include +#include + +#include "attributes.h" + +/** + * @defgroup lavu_sha SHA + * @ingroup lavu_hash + * SHA-1 and SHA-256 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA hash functions: + * + * - SHA-1: 160 bits + * - SHA-224: 224 bits, as a variant of SHA-2 + * - SHA-256: 256 bits, as a variant of SHA-2 + * + * @see For SHA-384, SHA-512, and variants thereof, see @ref lavu_sha512. + * + * @{ + */ + +extern const int av_sha_size; + +struct AVSHA; + +/** + * Allocate an AVSHA context. + */ +struct AVSHA *av_sha_alloc(void); + +/** + * Initialize SHA-1 or SHA-2 hashing. + * + * @param context pointer to the function context (of size av_sha_size) + * @param bits number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha_init(struct AVSHA* context, int bits); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param data input data to update hash with + * @param len input data length + */ +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len); + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha_final(struct AVSHA* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/sha512.c b/arm/raspi/third_party/ffmpeg/libavutil/sha512.c new file mode 100644 index 00000000..0574a46f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/sha512.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2009 Konstantin Shishkov + * Copyright (C) 2013 James Almer + * based on BSD-licensed SHA-2 code by Aaron D. Gifford + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "attributes.h" +#include "bswap.h" +#include "error.h" +#include "sha512.h" +#include "intreadwrite.h" +#include "mem.h" + +/** hash context */ +typedef struct AVSHA512 { + uint8_t digest_len; ///< digest length in 64-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[128]; ///< 1024-bit buffer of input values used in hash updating + uint64_t state[8]; ///< current hash value +} AVSHA512; + +const int av_sha512_size = sizeof(AVSHA512); + +struct AVSHA512 *av_sha512_alloc(void) +{ + return av_mallocz(sizeof(struct AVSHA512)); +} + +static const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#define ror(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits)))) + +#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(z,y,x) ((((x) | (y)) & (z)) | ((x) & (y))) + +#define Sigma0_512(x) (ror((x), 28) ^ ror((x), 34) ^ ror((x), 39)) +#define Sigma1_512(x) (ror((x), 14) ^ ror((x), 18) ^ ror((x), 41)) +#define sigma0_512(x) (ror((x), 1) ^ ror((x), 8) ^ ((x) >> 7)) +#define sigma1_512(x) (ror((x), 19) ^ ror((x), 61) ^ ((x) >> 6)) + +#define blk0(i) (block[i] = AV_RB64(buffer + 8 * (i))) +#define blk(i) (block[i] = block[i - 16] + sigma0_512(block[i - 15]) + \ + sigma1_512(block[i - 2]) + block[i - 7]) + +#define ROUND512(a,b,c,d,e,f,g,h) \ + T1 += (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[i]; \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + i++ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = blk0(i); \ + ROUND512(a,b,c,d,e,f,g,h) + +#define ROUND512_16_TO_80(a,b,c,d,e,f,g,h) \ + T1 = blk(i); \ + ROUND512(a,b,c,d,e,f,g,h) + +static void sha512_transform(uint64_t *state, const uint8_t buffer[128]) +{ + uint64_t a, b, c, d, e, f, g, h; + uint64_t block[80]; + uint64_t T1; + int i; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; +#if CONFIG_SMALL + for (i = 0; i < 80; i++) { + uint64_t T2; + if (i < 16) + T1 = blk0(i); + else + T1 = blk(i); + T1 += h + Sigma1_512(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } +#else + +#define R512_0 \ + ROUND512_0_TO_15(a, b, c, d, e, f, g, h); \ + ROUND512_0_TO_15(h, a, b, c, d, e, f, g); \ + ROUND512_0_TO_15(g, h, a, b, c, d, e, f); \ + ROUND512_0_TO_15(f, g, h, a, b, c, d, e); \ + ROUND512_0_TO_15(e, f, g, h, a, b, c, d); \ + ROUND512_0_TO_15(d, e, f, g, h, a, b, c); \ + ROUND512_0_TO_15(c, d, e, f, g, h, a, b); \ + ROUND512_0_TO_15(b, c, d, e, f, g, h, a) + + i = 0; + R512_0; R512_0; + +#define R512_16 \ + ROUND512_16_TO_80(a, b, c, d, e, f, g, h); \ + ROUND512_16_TO_80(h, a, b, c, d, e, f, g); \ + ROUND512_16_TO_80(g, h, a, b, c, d, e, f); \ + ROUND512_16_TO_80(f, g, h, a, b, c, d, e); \ + ROUND512_16_TO_80(e, f, g, h, a, b, c, d); \ + ROUND512_16_TO_80(d, e, f, g, h, a, b, c); \ + ROUND512_16_TO_80(c, d, e, f, g, h, a, b); \ + ROUND512_16_TO_80(b, c, d, e, f, g, h, a) + + R512_16; R512_16; R512_16; R512_16; + R512_16; R512_16; R512_16; R512_16; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} + + +av_cold int av_sha512_init(AVSHA512 *ctx, int bits) +{ + ctx->digest_len = bits >> 6; + switch (bits) { + case 224: // SHA-512/224 + ctx->state[0] = UINT64_C(0x8C3D37C819544DA2); + ctx->state[1] = UINT64_C(0x73E1996689DCD4D6); + ctx->state[2] = UINT64_C(0x1DFAB7AE32FF9C82); + ctx->state[3] = UINT64_C(0x679DD514582F9FCF); + ctx->state[4] = UINT64_C(0x0F6D2B697BD44DA8); + ctx->state[5] = UINT64_C(0x77E36F7304C48942); + ctx->state[6] = UINT64_C(0x3F9D85A86A1D36C8); + ctx->state[7] = UINT64_C(0x1112E6AD91D692A1); + break; + case 256: // SHA-512/256 + ctx->state[0] = UINT64_C(0x22312194FC2BF72C); + ctx->state[1] = UINT64_C(0x9F555FA3C84C64C2); + ctx->state[2] = UINT64_C(0x2393B86B6F53B151); + ctx->state[3] = UINT64_C(0x963877195940EABD); + ctx->state[4] = UINT64_C(0x96283EE2A88EFFE3); + ctx->state[5] = UINT64_C(0xBE5E1E2553863992); + ctx->state[6] = UINT64_C(0x2B0199FC2C85B8AA); + ctx->state[7] = UINT64_C(0x0EB72DDC81C52CA2); + break; + case 384: // SHA-384 + ctx->state[0] = UINT64_C(0xCBBB9D5DC1059ED8); + ctx->state[1] = UINT64_C(0x629A292A367CD507); + ctx->state[2] = UINT64_C(0x9159015A3070DD17); + ctx->state[3] = UINT64_C(0x152FECD8F70E5939); + ctx->state[4] = UINT64_C(0x67332667FFC00B31); + ctx->state[5] = UINT64_C(0x8EB44A8768581511); + ctx->state[6] = UINT64_C(0xDB0C2E0D64F98FA7); + ctx->state[7] = UINT64_C(0x47B5481DBEFA4FA4); + break; + case 512: // SHA-512 + ctx->state[0] = UINT64_C(0x6A09E667F3BCC908); + ctx->state[1] = UINT64_C(0xBB67AE8584CAA73B); + ctx->state[2] = UINT64_C(0x3C6EF372FE94F82B); + ctx->state[3] = UINT64_C(0xA54FF53A5F1D36F1); + ctx->state[4] = UINT64_C(0x510E527FADE682D1); + ctx->state[5] = UINT64_C(0x9B05688C2B3E6C1F); + ctx->state[6] = UINT64_C(0x1F83D9ABFB41BD6B); + ctx->state[7] = UINT64_C(0x5BE0CD19137E2179); + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +void av_sha512_update(AVSHA512* ctx, const uint8_t* data, size_t len) +{ + unsigned int j; + size_t i; + + j = ctx->count & 127; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (128 == j) { + sha512_transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if (len >= 128 - j) { + const uint8_t *end; + memcpy(&ctx->buffer[j], data, (i = 128 - j)); + sha512_transform(ctx->state, ctx->buffer); + data += i; + len -= i; + end = data + (len & ~127); + len = len % 128; + for (; data < end; data += 128) + sha512_transform(ctx->state, data); + j = 0; + } + memcpy(&ctx->buffer[j], data, len); +#endif +} + +void av_sha512_final(AVSHA512* ctx, uint8_t *digest) +{ + uint64_t i = 0; + uint64_t finalcount = av_be2ne64(ctx->count << 3); + + av_sha512_update(ctx, "\200", 1); + while ((ctx->count & 127) != 112) + av_sha512_update(ctx, "", 1); + av_sha512_update(ctx, (uint8_t *)&i, 8); + av_sha512_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WB64(digest + i*8, ctx->state[i]); + if (ctx->digest_len & 1) /* SHA512/224 is 28 bytes, and is not divisible by 8. */ + AV_WB32(digest + i*8, ctx->state[i] >> 32); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/sha512.h b/arm/raspi/third_party/ffmpeg/libavutil/sha512.h new file mode 100644 index 00000000..a4a3f23d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/sha512.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha512 + * Public header for SHA-512 implementation. + */ + +#ifndef AVUTIL_SHA512_H +#define AVUTIL_SHA512_H + +#include +#include + +#include "attributes.h" + +/** + * @defgroup lavu_sha512 SHA-512 + * @ingroup lavu_hash + * SHA-512 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA-2 hash functions: + * + * - SHA-512/224: 224 bits + * - SHA-512/256: 256 bits + * - SHA-384: 384 bits + * - SHA-512: 512 bits + * + * @see For SHA-1, SHA-256, and variants thereof, see @ref lavu_sha. + * + * @{ + */ + +extern const int av_sha512_size; + +struct AVSHA512; + +/** + * Allocate an AVSHA512 context. + */ +struct AVSHA512 *av_sha512_alloc(void); + +/** + * Initialize SHA-2 512 hashing. + * + * @param context pointer to the function context (of size av_sha512_size) + * @param bits number of bits in digest (224, 256, 384 or 512 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha512_init(struct AVSHA512* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +void av_sha512_update(struct AVSHA512* context, const uint8_t* data, size_t len); + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha512_final(struct AVSHA512* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA512_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/slicethread.c b/arm/raspi/third_party/ffmpeg/libavutil/slicethread.c new file mode 100644 index 00000000..115b0997 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/slicethread.c @@ -0,0 +1,259 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "cpu.h" +#include "internal.h" +#include "slicethread.h" +#include "mem.h" +#include "thread.h" +#include "avassert.h" + +#define MAX_AUTO_THREADS 16 + +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS + +typedef struct WorkerContext { + AVSliceThread *ctx; + pthread_mutex_t mutex; + pthread_cond_t cond; + pthread_t thread; + int done; +} WorkerContext; + +struct AVSliceThread { + WorkerContext *workers; + int nb_threads; + int nb_active_threads; + int nb_jobs; + + atomic_uint first_job; + atomic_uint current_job; + pthread_mutex_t done_mutex; + pthread_cond_t done_cond; + int done; + int finished; + + void *priv; + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads); + void (*main_func)(void *priv); +}; + +static int run_jobs(AVSliceThread *ctx) +{ + unsigned nb_jobs = ctx->nb_jobs; + unsigned nb_active_threads = ctx->nb_active_threads; + unsigned first_job = atomic_fetch_add_explicit(&ctx->first_job, 1, memory_order_acq_rel); + unsigned current_job = first_job; + + do { + ctx->worker_func(ctx->priv, current_job, first_job, nb_jobs, nb_active_threads); + } while ((current_job = atomic_fetch_add_explicit(&ctx->current_job, 1, memory_order_acq_rel)) < nb_jobs); + + return current_job == nb_jobs + nb_active_threads - 1; +} + +static void *attribute_align_arg thread_worker(void *v) +{ + WorkerContext *w = v; + AVSliceThread *ctx = w->ctx; + + pthread_mutex_lock(&w->mutex); + pthread_cond_signal(&w->cond); + + while (1) { + w->done = 1; + while (w->done) + pthread_cond_wait(&w->cond, &w->mutex); + + if (ctx->finished) { + pthread_mutex_unlock(&w->mutex); + return NULL; + } + + if (run_jobs(ctx)) { + pthread_mutex_lock(&ctx->done_mutex); + ctx->done = 1; + pthread_cond_signal(&ctx->done_cond); + pthread_mutex_unlock(&ctx->done_mutex); + } + } +} + +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads) +{ + AVSliceThread *ctx; + int nb_workers, i; + + av_assert0(nb_threads >= 0); + if (!nb_threads) { + int nb_cpus = av_cpu_count(); + if (nb_cpus > 1) + nb_threads = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); + else + nb_threads = 1; + } + + nb_workers = nb_threads; + if (!main_func) + nb_workers--; + + *pctx = ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return AVERROR(ENOMEM); + + if (nb_workers && !(ctx->workers = av_calloc(nb_workers, sizeof(*ctx->workers)))) { + av_freep(pctx); + return AVERROR(ENOMEM); + } + + ctx->priv = priv; + ctx->worker_func = worker_func; + ctx->main_func = main_func; + ctx->nb_threads = nb_threads; + ctx->nb_active_threads = 0; + ctx->nb_jobs = 0; + ctx->finished = 0; + + atomic_init(&ctx->first_job, 0); + atomic_init(&ctx->current_job, 0); + pthread_mutex_init(&ctx->done_mutex, NULL); + pthread_cond_init(&ctx->done_cond, NULL); + ctx->done = 0; + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + int ret; + w->ctx = ctx; + pthread_mutex_init(&w->mutex, NULL); + pthread_cond_init(&w->cond, NULL); + pthread_mutex_lock(&w->mutex); + w->done = 0; + + if (ret = pthread_create(&w->thread, NULL, thread_worker, w)) { + ctx->nb_threads = main_func ? i : i + 1; + pthread_mutex_unlock(&w->mutex); + pthread_cond_destroy(&w->cond); + pthread_mutex_destroy(&w->mutex); + avpriv_slicethread_free(pctx); + return AVERROR(ret); + } + + while (!w->done) + pthread_cond_wait(&w->cond, &w->mutex); + pthread_mutex_unlock(&w->mutex); + } + + return nb_threads; +} + +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main) +{ + int nb_workers, i, is_last = 0; + + av_assert0(nb_jobs > 0); + ctx->nb_jobs = nb_jobs; + ctx->nb_active_threads = FFMIN(nb_jobs, ctx->nb_threads); + atomic_store_explicit(&ctx->first_job, 0, memory_order_relaxed); + atomic_store_explicit(&ctx->current_job, ctx->nb_active_threads, memory_order_relaxed); + nb_workers = ctx->nb_active_threads; + if (!ctx->main_func || !execute_main) + nb_workers--; + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_mutex_lock(&w->mutex); + w->done = 0; + pthread_cond_signal(&w->cond); + pthread_mutex_unlock(&w->mutex); + } + + if (ctx->main_func && execute_main) + ctx->main_func(ctx->priv); + else + is_last = run_jobs(ctx); + + if (!is_last) { + pthread_mutex_lock(&ctx->done_mutex); + while (!ctx->done) + pthread_cond_wait(&ctx->done_cond, &ctx->done_mutex); + ctx->done = 0; + pthread_mutex_unlock(&ctx->done_mutex); + } +} + +void avpriv_slicethread_free(AVSliceThread **pctx) +{ + AVSliceThread *ctx; + int nb_workers, i; + + if (!pctx || !*pctx) + return; + + ctx = *pctx; + nb_workers = ctx->nb_threads; + if (!ctx->main_func) + nb_workers--; + + ctx->finished = 1; + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_mutex_lock(&w->mutex); + w->done = 0; + pthread_cond_signal(&w->cond); + pthread_mutex_unlock(&w->mutex); + } + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_join(w->thread, NULL); + pthread_cond_destroy(&w->cond); + pthread_mutex_destroy(&w->mutex); + } + + pthread_cond_destroy(&ctx->done_cond); + pthread_mutex_destroy(&ctx->done_mutex); + av_freep(&ctx->workers); + av_freep(pctx); +} + +#else /* HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS32THREADS */ + +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads) +{ + *pctx = NULL; + return AVERROR(ENOSYS); +} + +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main) +{ + av_assert0(0); +} + +void avpriv_slicethread_free(AVSliceThread **pctx) +{ + av_assert0(!pctx || !*pctx); +} + +#endif /* HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS32THREADS */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/slicethread.h b/arm/raspi/third_party/ffmpeg/libavutil/slicethread.h new file mode 100644 index 00000000..f6f6f302 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/slicethread.h @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SLICETHREAD_H +#define AVUTIL_SLICETHREAD_H + +typedef struct AVSliceThread AVSliceThread; + +/** + * Create slice threading context. + * @param pctx slice threading context returned here + * @param priv private pointer to be passed to callback function + * @param worker_func callback function to be executed + * @param main_func special callback function, called from main thread, may be NULL + * @param nb_threads number of threads, 0 for automatic, must be >= 0 + * @return return number of threads or negative AVERROR on failure + */ +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads); + +/** + * Execute slice threading. + * @param ctx slice threading context + * @param nb_jobs number of jobs, must be > 0 + * @param execute_main also execute main_func + */ +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main); + +/** + * Destroy slice threading context. + * @param pctx pointer to context + */ +void avpriv_slicethread_free(AVSliceThread **pctx); + +#endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/softfloat.h b/arm/raspi/third_party/ffmpeg/libavutil/softfloat.h new file mode 100644 index 00000000..a651406f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/softfloat.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SOFTFLOAT_H +#define AVUTIL_SOFTFLOAT_H + +#include +#include "common.h" + +#include "avassert.h" +#include "softfloat_tables.h" + +#define MIN_EXP -149 +#define MAX_EXP 126 +#define ONE_BITS 29 + +typedef struct SoftFloat{ + int32_t mant; + int32_t exp; +}SoftFloat; + +static const SoftFloat FLOAT_0 = { 0, MIN_EXP}; ///< 0.0 +static const SoftFloat FLOAT_05 = { 0x20000000, 0}; ///< 0.5 +static const SoftFloat FLOAT_1 = { 0x20000000, 1}; ///< 1.0 +static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16}; ///< A small value +static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1}; ///< 1.584893192 (10^.2) +static const SoftFloat FLOAT_100000 = { 0x30D40000, 17}; ///< 100000 +static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0}; ///< 0.999999 +static const SoftFloat FLOAT_MIN = { 0x20000000, MIN_EXP}; + + +/** + * Convert a SoftFloat to a double precision float. + */ +static inline av_const double av_sf2double(SoftFloat v) { + v.exp -= ONE_BITS +1; + return ldexp(v.mant, v.exp); +} + +static av_const SoftFloat av_normalize_sf(SoftFloat a){ + if(a.mant){ +#if 1 + while((a.mant + 0x1FFFFFFFU)<0x3FFFFFFFU){ + a.mant += a.mant; + a.exp -= 1; + } +#else + int s=ONE_BITS - av_log2(FFABS(a.mant)); + a.exp -= s; + a.mant <<= s; +#endif + if(a.exp < MIN_EXP){ + a.exp = MIN_EXP; + a.mant= 0; + } + }else{ + a.exp= MIN_EXP; + } + return a; +} + +static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ +#if 1 + if((int32_t)(a.mant + 0x40000000U) <= 0){ + a.exp++; + a.mant>>=1; + } + av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000); + av_assert2(a.exp <= MAX_EXP); + return a; +#elif 1 + int t= a.mant + 0x40000000 < 0; + return (SoftFloat){ a.mant>>t, a.exp+t}; +#else + int t= (a.mant + 0x3FFFFFFFU)>>31; + return (SoftFloat){a.mant>>t, a.exp+t}; +#endif +} + +/** + * @return Will not be more denormalized than a*b. So if either input is + * normalized, then the output will not be worse then the other input. + * If both are normalized, then the output will be normalized. + */ +static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){ + a.exp += b.exp; + av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS); + a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; + a = av_normalize1_sf((SoftFloat){a.mant, a.exp - 1}); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; +} + +/** + * b has to be normalized and not zero. + * @return Will not be more denormalized than a. + */ +static inline av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){ + int64_t temp = (int64_t)a.mant * (1<<(ONE_BITS+1)); + temp /= b.mant; + a.exp -= b.exp; + a.mant = temp; + while (a.mant != temp) { + temp /= 2; + a.exp--; + a.mant = temp; + } + a = av_normalize1_sf(a); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; +} + +/** + * Compares two SoftFloats. + * @returns < 0 if the first is less + * > 0 if the first is greater + * 0 if they are equal + */ +static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){ + int t= a.exp - b.exp; + if (t <-31) return - b.mant ; + else if (t < 0) return (a.mant >> (-t)) - b.mant ; + else if (t < 32) return a.mant - (b.mant >> t); + else return a.mant ; +} + +/** + * Compares two SoftFloats. + * @returns 1 if a is greater than b, 0 otherwise + */ +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) +{ + int t= a.exp - b.exp; + if (t <-31) return 0 > b.mant ; + else if (t < 0) return (a.mant >> (-t)) > b.mant ; + else if (t < 32) return a.mant > (b.mant >> t); + else return a.mant > 0 ; +} + +/** + * @returns the sum of 2 SoftFloats. + */ +static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){ + int t= a.exp - b.exp; + if (t <-31) return b; + else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){ b.mant + (a.mant >> (-t)), b.exp})); + else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){ a.mant + (b.mant >> t ), a.exp})); + else return a; +} + +/** + * @returns the difference of 2 SoftFloats. + */ +static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){ + return av_add_sf(a, (SoftFloat){ -b.mant, b.exp}); +} + +//FIXME log, exp, pow + +/** + * Converts a mantisse and exponent to a SoftFloat. + * This converts a fixed point value v with frac_bits fractional bits to a + * SoftFloat. + * @returns a SoftFloat with value v * 2^-frac_bits + */ +static inline av_const SoftFloat av_int2sf(int v, int frac_bits){ + int exp_offset = 0; + if(v <= INT_MIN + 1){ + exp_offset = 1; + v>>=1; + } + return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset})); +} + +/** + * Converts a SoftFloat to an integer. + * Rounding is to -inf. + */ +static inline av_const int av_sf2int(SoftFloat v, int frac_bits){ + v.exp += frac_bits - (ONE_BITS + 1); + if(v.exp >= 0) return v.mant << v.exp ; + else return v.mant >>(-v.exp); +} + +/** + * Rounding-to-nearest used. + */ +static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val) +{ + int tabIndex, rem; + + if (val.mant == 0) + val.exp = MIN_EXP; + else if (val.mant < 0) + abort(); + else + { + tabIndex = (val.mant - 0x20000000) >> 20; + + rem = val.mant & 0xFFFFF; + val.mant = (int)(((int64_t)av_sqrttbl_sf[tabIndex] * (0x100000 - rem) + + (int64_t)av_sqrttbl_sf[tabIndex + 1] * rem + + 0x80000) >> 20); + val.mant = (int)(((int64_t)av_sqr_exp_multbl_sf[val.exp & 1] * val.mant + + 0x10000000) >> 29); + + if (val.mant < 0x40000000) + val.exp -= 2; + else + val.mant >>= 1; + + val.exp = (val.exp >> 1) + 1; + } + + return val; +} + +/** + * Rounding-to-nearest used. + */ +static av_unused void av_sincos_sf(int a, int *s, int *c) +{ + int idx, sign; + int sv, cv; + int st, ct; + + idx = a >> 26; + sign = (int32_t)((unsigned)idx << 27) >> 31; + cv = av_costbl_1_sf[idx & 0xf]; + cv = (cv ^ sign) - sign; + + idx -= 8; + sign = (int32_t)((unsigned)idx << 27) >> 31; + sv = av_costbl_1_sf[idx & 0xf]; + sv = (sv ^ sign) - sign; + + idx = a >> 21; + ct = av_costbl_2_sf[idx & 0x1f]; + st = av_sintbl_2_sf[idx & 0x1f]; + + idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30); + + sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); + + cv = idx; + + idx = a >> 16; + ct = av_costbl_3_sf[idx & 0x1f]; + st = av_sintbl_3_sf[idx & 0x1f]; + + idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30); + + sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); + cv = idx; + + idx = a >> 11; + + ct = (int)(((int64_t)av_costbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) + + (int64_t)av_costbl_4_sf[(idx & 0x1f)+1]*(a & 0x7ff) + + 0x400) >> 11); + st = (int)(((int64_t)av_sintbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) + + (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) + + 0x400) >> 11); + + *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30); + + *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); +} + +#endif /* AVUTIL_SOFTFLOAT_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/softfloat_ieee754.h b/arm/raspi/third_party/ffmpeg/libavutil/softfloat_ieee754.h new file mode 100644 index 00000000..3398aa18 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/softfloat_ieee754.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Umair Khan + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SOFTFLOAT_IEEE754_H +#define AVUTIL_SOFTFLOAT_IEEE754_H + +#include + +#define EXP_BIAS 127 +#define MANT_BITS 23 + +typedef struct SoftFloat_IEEE754 { + int32_t sign; + uint64_t mant; + int32_t exp; +} SoftFloat_IEEE754; + +static const SoftFloat_IEEE754 FLOAT_0 = {0, 0, -126}; +static const SoftFloat_IEEE754 FLOAT_1 = {0, 0, 0}; + +/** Normalize the softfloat as defined by IEEE 754 single-recision floating + * point specification + */ +static inline SoftFloat_IEEE754 av_normalize_sf_ieee754(SoftFloat_IEEE754 sf) { + while( sf.mant >= 0x1000000UL ) { + sf.exp++; + sf.mant >>= 1; + } + sf.mant &= 0x007fffffUL; + return sf; +} + +/** Convert integer to softfloat. + * @return softfloat with value n * 2^e + */ +static inline SoftFloat_IEEE754 av_int2sf_ieee754(int64_t n, int e) { + int sign = 0; + + if (n < 0) { + sign = 1; + n *= -1; + } + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, n << MANT_BITS, 0 + e}); +} + +/** Make a softfloat out of the bitstream. Assumes the bits are in the form as defined + * by the IEEE 754 spec. + */ +static inline SoftFloat_IEEE754 av_bits2sf_ieee754(uint32_t n) { + return ((SoftFloat_IEEE754) { (n & 0x80000000UL) >> 31, (n & 0x7FFFFFUL), (int8_t)((n & 0x7F800000UL) >> 23)}); +} + +/** Convert the softfloat to integer + */ +static inline int av_sf2int_ieee754(SoftFloat_IEEE754 a) { + if(a.exp >= 0) return a.mant << a.exp ; + else return a.mant >>(-a.exp); +} + +/** Divide a by b. b should not be zero. + * @return normalized result + */ +static inline SoftFloat_IEEE754 av_div_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + int32_t mant, exp, sign; + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + sign = a.sign ^ b.sign; + mant = ((((uint64_t) (a.mant | 0x00800000UL)) << MANT_BITS) / (b.mant| 0x00800000UL)); + exp = a.exp - b.exp; + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); +} + +/** Multiply a with b + * #return normalized result + */ +static inline SoftFloat_IEEE754 av_mul_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + int32_t sign, mant, exp; + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + sign = a.sign ^ b.sign; + mant = (((uint64_t)(a.mant|0x00800000UL) * (uint64_t)(b.mant|0x00800000UL))>>MANT_BITS); + exp = a.exp + b.exp; + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); +} + +/** Compare a with b strictly + * @returns 1 if the a and b are equal, 0 otherwise. + */ +static inline int av_cmp_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + if (a.sign != b.sign) return 0; + if (a.mant != b.mant) return 0; + if (a.exp != b.exp ) return 0; + return 1; +} + +#endif /*AVUTIL_SOFTFLOAT_IEEE754_H*/ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/softfloat_tables.h b/arm/raspi/third_party/ffmpeg/libavutil/softfloat_tables.h new file mode 100644 index 00000000..461f2b22 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/softfloat_tables.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * 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. Neither the name of the MIPS Technologies, Inc., nor the names of is + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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. + * + * Author: Stanislav Ocovaj (stanislav.ocovaj imgtec com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVUTIL_SOFTFLOAT_TABLES_H +#define AVUTIL_SOFTFLOAT_TABLES_H + +#include + +static const int32_t av_sqrttbl_sf[512+1] = { /* sqrt(x), 0.5<=x<1 */ + 0x2d413ccd,0x2d4c8bb3,0x2d57d7c6,0x2d63210a, + 0x2d6e677f,0x2d79ab2a,0x2d84ec0b,0x2d902a23, + 0x2d9b6578,0x2da69e08,0x2db1d3d6,0x2dbd06e6, + 0x2dc83738,0x2dd364ce,0x2dde8fac,0x2de9b7d2, + 0x2df4dd43,0x2e000000,0x2e0b200c,0x2e163d68, + 0x2e215816,0x2e2c701a,0x2e378573,0x2e429824, + 0x2e4da830,0x2e58b598,0x2e63c05d,0x2e6ec883, + 0x2e79ce0a,0x2e84d0f5,0x2e8fd144,0x2e9acefb, + 0x2ea5ca1b,0x2eb0c2a7,0x2ebbb89e,0x2ec6ac04, + 0x2ed19cda,0x2edc8b23,0x2ee776df,0x2ef26012, + 0x2efd46bb,0x2f082add,0x2f130c7b,0x2f1deb95, + 0x2f28c82e,0x2f33a246,0x2f3e79e1,0x2f494eff, + 0x2f5421a3,0x2f5ef1ce,0x2f69bf81,0x2f748abe, + 0x2f7f5388,0x2f8a19e0,0x2f94ddc7,0x2f9f9f3e, + 0x2faa5e48,0x2fb51ae8,0x2fbfd51c,0x2fca8ce9, + 0x2fd5424e,0x2fdff54e,0x2feaa5eb,0x2ff55426, + 0x30000000,0x300aa97b,0x3015509a,0x301ff55c, + 0x302a97c5,0x303537d5,0x303fd58e,0x304a70f2, + 0x30550a01,0x305fa0be,0x306a352a,0x3074c747, + 0x307f5716,0x3089e499,0x30946fd2,0x309ef8c0, + 0x30a97f67,0x30b403c7,0x30be85e2,0x30c905bb, + 0x30d38351,0x30ddfea6,0x30e877bc,0x30f2ee96, + 0x30fd6332,0x3107d594,0x311245bc,0x311cb3ad, + 0x31271f67,0x313188ec,0x313bf03d,0x3146555c, + 0x3150b84a,0x315b1909,0x31657798,0x316fd3fc, + 0x317a2e34,0x31848642,0x318edc28,0x31992fe5, + 0x31a3817d,0x31add0f0,0x31b81e40,0x31c2696e, + 0x31ccb27b,0x31d6f969,0x31e13e38,0x31eb80eb, + 0x31f5c182,0x32000000,0x320a3c65,0x321476b1, + 0x321eaee8,0x3228e50a,0x32331917,0x323d4b13, + 0x32477afc,0x3251a8d6,0x325bd4a2,0x3265fe5f, + 0x32702611,0x327a4bb8,0x32846f55,0x328e90e9, + 0x3298b076,0x32a2cdfd,0x32ace97e,0x32b702fd, + 0x32c11a79,0x32cb2ff3,0x32d5436d,0x32df54e9, + 0x32e96466,0x32f371e8,0x32fd7d6d,0x330786f9, + 0x33118e8c,0x331b9426,0x332597cb,0x332f9979, + 0x33399933,0x334396fa,0x334d92cf,0x33578cb2, + 0x336184a6,0x336b7aab,0x33756ec3,0x337f60ed, + 0x3389512d,0x33933f83,0x339d2bef,0x33a71672, + 0x33b0ff10,0x33bae5c7,0x33c4ca99,0x33cead88, + 0x33d88e95,0x33e26dbf,0x33ec4b09,0x33f62673, + 0x34000000,0x3409d7af,0x3413ad82,0x341d817a, + 0x34275397,0x343123db,0x343af248,0x3444bedd, + 0x344e899d,0x34585288,0x3462199f,0x346bdee3, + 0x3475a254,0x347f63f5,0x348923c6,0x3492e1c9, + 0x349c9dfe,0x34a65865,0x34b01101,0x34b9c7d2, + 0x34c37cda,0x34cd3018,0x34d6e18f,0x34e0913f, + 0x34ea3f29,0x34f3eb4d,0x34fd95ae,0x35073e4c, + 0x3510e528,0x351a8a43,0x35242d9d,0x352dcf39, + 0x35376f16,0x35410d36,0x354aa99a,0x35544442, + 0x355ddd2f,0x35677463,0x357109df,0x357a9da2, + 0x35842fb0,0x358dc007,0x35974ea9,0x35a0db98, + 0x35aa66d3,0x35b3f05c,0x35bd7833,0x35c6fe5a, + 0x35d082d3,0x35da059c,0x35e386b7,0x35ed0626, + 0x35f683e8,0x36000000,0x36097a6e,0x3612f331, + 0x361c6a4d,0x3625dfc1,0x362f538f,0x3638c5b7, + 0x36423639,0x364ba518,0x36551252,0x365e7deb, + 0x3667e7e2,0x36715039,0x367ab6f0,0x36841c07, + 0x368d7f81,0x3696e15d,0x36a0419d,0x36a9a040, + 0x36b2fd49,0x36bc58b8,0x36c5b28e,0x36cf0acb, + 0x36d86170,0x36e1b680,0x36eb09f8,0x36f45bdc, + 0x36fdac2b,0x3706fae7,0x37104810,0x371993a7, + 0x3722ddad,0x372c2622,0x37356d08,0x373eb25f, + 0x3747f629,0x37513865,0x375a7914,0x3763b838, + 0x376cf5d0,0x377631e0,0x377f6c64,0x3788a561, + 0x3791dcd6,0x379b12c4,0x37a4472c,0x37ad7a0e, + 0x37b6ab6a,0x37bfdb44,0x37c90999,0x37d2366d, + 0x37db61be,0x37e48b8e,0x37edb3de,0x37f6daae, + 0x38000000,0x380923d3,0x3812462a,0x381b6703, + 0x38248660,0x382da442,0x3836c0aa,0x383fdb97, + 0x3848f50c,0x38520d09,0x385b238d,0x3864389b, + 0x386d4c33,0x38765e55,0x387f6f01,0x38887e3b, + 0x38918c00,0x389a9853,0x38a3a334,0x38acaca3, + 0x38b5b4a3,0x38bebb32,0x38c7c051,0x38d0c402, + 0x38d9c645,0x38e2c71b,0x38ebc685,0x38f4c482, + 0x38fdc114,0x3906bc3c,0x390fb5fa,0x3918ae4f, + 0x3921a53a,0x392a9abe,0x39338edb,0x393c8192, + 0x394572e2,0x394e62ce,0x39575155,0x39603e77, + 0x39692a36,0x39721494,0x397afd8f,0x3983e527, + 0x398ccb60,0x3995b039,0x399e93b2,0x39a775cc, + 0x39b05689,0x39b935e8,0x39c213e9,0x39caf08e, + 0x39d3cbd9,0x39dca5c7,0x39e57e5b,0x39ee5596, + 0x39f72b77,0x3a000000,0x3a08d331,0x3a11a50a, + 0x3a1a758d,0x3a2344ba,0x3a2c1291,0x3a34df13, + 0x3a3daa41,0x3a46741b,0x3a4f3ca3,0x3a5803d7, + 0x3a60c9ba,0x3a698e4b,0x3a72518b,0x3a7b137c, + 0x3a83d41d,0x3a8c936f,0x3a955173,0x3a9e0e29, + 0x3aa6c992,0x3aaf83ae,0x3ab83c7e,0x3ac0f403, + 0x3ac9aa3c,0x3ad25f2c,0x3adb12d1,0x3ae3c52d, + 0x3aec7642,0x3af5260e,0x3afdd492,0x3b0681d0, + 0x3b0f2dc6,0x3b17d878,0x3b2081e4,0x3b292a0c, + 0x3b31d0f0,0x3b3a7690,0x3b431aec,0x3b4bbe06, + 0x3b545fdf,0x3b5d0077,0x3b659fcd,0x3b6e3de4, + 0x3b76daba,0x3b7f7651,0x3b8810aa,0x3b90a9c4, + 0x3b9941a1,0x3ba1d842,0x3baa6da5,0x3bb301cd, + 0x3bbb94b9,0x3bc4266a,0x3bccb6e2,0x3bd5461f, + 0x3bddd423,0x3be660ee,0x3beeec81,0x3bf776dc, + 0x3c000000,0x3c0887ed,0x3c110ea4,0x3c199426, + 0x3c221872,0x3c2a9b8a,0x3c331d6e,0x3c3b9e1d, + 0x3c441d9a,0x3c4c9be5,0x3c5518fd,0x3c5d94e3, + 0x3c660f98,0x3c6e891d,0x3c770172,0x3c7f7898, + 0x3c87ee8e,0x3c906356,0x3c98d6ef,0x3ca1495b, + 0x3ca9ba9a,0x3cb22aac,0x3cba9992,0x3cc3074c, + 0x3ccb73dc,0x3cd3df41,0x3cdc497b,0x3ce4b28c, + 0x3ced1a73,0x3cf58132,0x3cfde6c8,0x3d064b37, + 0x3d0eae7f,0x3d17109f,0x3d1f719a,0x3d27d16e, + 0x3d30301d,0x3d388da8,0x3d40ea0d,0x3d49454f, + 0x3d519f6d,0x3d59f867,0x3d625040,0x3d6aa6f6, + 0x3d72fc8b,0x3d7b50fe,0x3d83a451,0x3d8bf683, + 0x3d944796,0x3d9c9788,0x3da4e65c,0x3dad3412, + 0x3db580a9,0x3dbdcc24,0x3dc61680,0x3dce5fc0, + 0x3dd6a7e4,0x3ddeeeed,0x3de734d9,0x3def79ab, + 0x3df7bd62,0x3e000000,0x3e084184,0x3e1081ee, + 0x3e18c140,0x3e20ff7a,0x3e293c9c,0x3e3178a7, + 0x3e39b39a,0x3e41ed77,0x3e4a263d,0x3e525def, + 0x3e5a948b,0x3e62ca12,0x3e6afe85,0x3e7331e4, + 0x3e7b642f,0x3e839567,0x3e8bc58c,0x3e93f49f, + 0x3e9c22a1,0x3ea44f91,0x3eac7b6f,0x3eb4a63e, + 0x3ebccffb,0x3ec4f8aa,0x3ecd2049,0x3ed546d9, + 0x3edd6c5a,0x3ee590cd,0x3eedb433,0x3ef5d68c, + 0x3efdf7d7,0x3f061816,0x3f0e3749,0x3f165570, + 0x3f1e728c,0x3f268e9d,0x3f2ea9a4,0x3f36c3a0, + 0x3f3edc93,0x3f46f47c,0x3f4f0b5d,0x3f572135, + 0x3f5f3606,0x3f6749cf,0x3f6f5c90,0x3f776e4a, + 0x3f7f7efe,0x3f878eab,0x3f8f9d53,0x3f97aaf6, + 0x3f9fb793,0x3fa7c32c,0x3fafcdc1,0x3fb7d752, + 0x3fbfdfe0,0x3fc7e76b,0x3fcfedf3,0x3fd7f378, + 0x3fdff7fc,0x3fe7fb7f,0x3feffe00,0x3ff7ff80, + 0x3fffffff, +}; + +static const int32_t av_sqr_exp_multbl_sf[2] = { + 0x20000000,0x2d413ccd, +}; + +static const int32_t av_costbl_1_sf[16] = { + 0x40000000,0x3ec52fa0,0x3b20d79e,0x3536cc52, + 0x2d413ccd,0x238e7673,0x187de2a7,0x0c7c5c1e, + 0x00000000,0xf383a3e3,0xe7821d5a,0xdc71898e, + 0xd2bec334,0xcac933af,0xc4df2863,0xc13ad061, +}; + +static const int32_t av_costbl_2_sf[32] = { + 0x40000000,0x3fffb10b,0x3ffec42d,0x3ffd3969, + 0x3ffb10c1,0x3ff84a3c,0x3ff4e5e0,0x3ff0e3b6, + 0x3fec43c7,0x3fe7061f,0x3fe12acb,0x3fdab1d9, + 0x3fd39b5a,0x3fcbe75e,0x3fc395f9,0x3fbaa740, + 0x3fb11b48,0x3fa6f228,0x3f9c2bfb,0x3f90c8da, + 0x3f84c8e2,0x3f782c30,0x3f6af2e3,0x3f5d1d1d, + 0x3f4eaafe,0x3f3f9cab,0x3f2ff24a,0x3f1fabff, + 0x3f0ec9f5,0x3efd4c54,0x3eeb3347,0x3ed87efc, +}; + +static const int32_t av_sintbl_2_sf[32] = { + 0x00000000,0x006487c4,0x00c90e90,0x012d936c, + 0x0192155f,0x01f69373,0x025b0caf,0x02bf801a, + 0x0323ecbe,0x038851a2,0x03ecadcf,0x0451004d, + 0x04b54825,0x0519845e,0x057db403,0x05e1d61b, + 0x0645e9af,0x06a9edc9,0x070de172,0x0771c3b3, + 0x07d59396,0x08395024,0x089cf867,0x09008b6a, + 0x09640837,0x09c76dd8,0x0a2abb59,0x0a8defc3, + 0x0af10a22,0x0b540982,0x0bb6ecef,0x0c19b374, +}; + +static const int32_t av_costbl_3_sf[32] = { + 0x40000000,0x3fffffec,0x3fffffb1,0x3fffff4e, + 0x3ffffec4,0x3ffffe13,0x3ffffd39,0x3ffffc39, + 0x3ffffb11,0x3ffff9c1,0x3ffff84a,0x3ffff6ac, + 0x3ffff4e6,0x3ffff2f8,0x3ffff0e3,0x3fffeea7, + 0x3fffec43,0x3fffe9b7,0x3fffe705,0x3fffe42a, + 0x3fffe128,0x3fffddff,0x3fffdaae,0x3fffd736, + 0x3fffd396,0x3fffcfcf,0x3fffcbe0,0x3fffc7ca, + 0x3fffc38c,0x3fffbf27,0x3fffba9b,0x3fffb5e7, +}; + +static const int32_t av_sintbl_3_sf[32] = { + 0x00000000,0x0003243f,0x0006487f,0x00096cbe, + 0x000c90fe,0x000fb53d,0x0012d97c,0x0015fdbb, + 0x001921fb,0x001c463a,0x001f6a79,0x00228eb8, + 0x0025b2f7,0x0028d736,0x002bfb74,0x002f1fb3, + 0x003243f1,0x00356830,0x00388c6e,0x003bb0ac, + 0x003ed4ea,0x0041f928,0x00451d66,0x004841a3, + 0x004b65e1,0x004e8a1e,0x0051ae5b,0x0054d297, + 0x0057f6d4,0x005b1b10,0x005e3f4c,0x00616388, +}; + +static const int32_t av_costbl_4_sf[33] = { + 0x40000000,0x40000000,0x40000000,0x40000000, + 0x40000000,0x40000000,0x3fffffff,0x3fffffff, + 0x3fffffff,0x3ffffffe,0x3ffffffe,0x3ffffffe, + 0x3ffffffd,0x3ffffffd,0x3ffffffc,0x3ffffffc, + 0x3ffffffb,0x3ffffffa,0x3ffffffa,0x3ffffff9, + 0x3ffffff8,0x3ffffff7,0x3ffffff7,0x3ffffff6, + 0x3ffffff5,0x3ffffff4,0x3ffffff3,0x3ffffff2, + 0x3ffffff1,0x3ffffff0,0x3fffffef,0x3fffffed, + 0x3fffffec, +}; + +static const int32_t av_sintbl_4_sf[33] = { + 0x00000000,0x00001922,0x00003244,0x00004b66, + 0x00006488,0x00007daa,0x000096cc,0x0000afee, + 0x0000c910,0x0000e232,0x0000fb54,0x00011476, + 0x00012d98,0x000146ba,0x00015fdc,0x000178fe, + 0x00019220,0x0001ab42,0x0001c464,0x0001dd86, + 0x0001f6a8,0x00020fca,0x000228ec,0x0002420e, + 0x00025b30,0x00027452,0x00028d74,0x0002a696, + 0x0002bfb7,0x0002d8d9,0x0002f1fb,0x00030b1d, + 0x0003243f, +}; +#endif /* AVUTIL_SOFTFLOAT_TABLES_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/spherical.c b/arm/raspi/third_party/ffmpeg/libavutil/spherical.c new file mode 100644 index 00000000..ed66344a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/spherical.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avstring.h" +#include "mem.h" +#include "spherical.h" + +AVSphericalMapping *av_spherical_alloc(size_t *size) +{ + AVSphericalMapping *spherical = av_mallocz(sizeof(AVSphericalMapping)); + if (!spherical) + return NULL; + + if (size) + *size = sizeof(*spherical); + + return spherical; +} + +void av_spherical_tile_bounds(const AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom) +{ + /* conversion from 0.32 coordinates to pixels */ + uint64_t orig_width = (uint64_t) width * UINT32_MAX / + (UINT32_MAX - map->bound_right - map->bound_left); + uint64_t orig_height = (uint64_t) height * UINT32_MAX / + (UINT32_MAX - map->bound_bottom - map->bound_top); + + /* add a (UINT32_MAX - 1) to round up integer division */ + *left = (orig_width * map->bound_left + UINT32_MAX - 1) / UINT32_MAX; + *top = (orig_height * map->bound_top + UINT32_MAX - 1) / UINT32_MAX; + *right = orig_width - width - *left; + *bottom = orig_height - height - *top; +} + +static const char *const spherical_projection_names[] = { + [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", + [AV_SPHERICAL_CUBEMAP] = "cubemap", + [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +}; + +const char *av_spherical_projection_name(enum AVSphericalProjection projection) +{ + if ((unsigned)projection >= FF_ARRAY_ELEMS(spherical_projection_names)) + return "unknown"; + + return spherical_projection_names[projection]; +} + +int av_spherical_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(spherical_projection_names); i++) { + if (av_strstart(name, spherical_projection_names[i], NULL)) + return i; + } + + return -1; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/spherical.h b/arm/raspi/third_party/ffmpeg/libavutil/spherical.h new file mode 100644 index 00000000..828ac836 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/spherical.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_video_spherical + * Spherical video + */ + +#ifndef AVUTIL_SPHERICAL_H +#define AVUTIL_SPHERICAL_H + +#include +#include + +/** + * @defgroup lavu_video_spherical Spherical video mapping + * @ingroup lavu_video + * + * A spherical video file contains surfaces that need to be mapped onto a + * sphere. Depending on how the frame was converted, a different distortion + * transformation or surface recomposition function needs to be applied before + * the video should be mapped and displayed. + * @{ + */ + +/** + * Projection of the video surface(s) on a sphere. + */ +enum AVSphericalProjection { + /** + * Video represents a sphere mapped on a flat surface using + * equirectangular projection. + */ + AV_SPHERICAL_EQUIRECTANGULAR, + + /** + * Video frame is split into 6 faces of a cube, and arranged on a + * 3x2 layout. Faces are oriented upwards for the front, left, right, + * and back faces. The up face is oriented so the top of the face is + * forwards and the down face is oriented so the top of the face is + * to the back. + */ + AV_SPHERICAL_CUBEMAP, + + /** + * Video represents a portion of a sphere mapped on a flat surface + * using equirectangular projection. The @ref bounding fields indicate + * the position of the current video in a larger surface. + */ + AV_SPHERICAL_EQUIRECTANGULAR_TILE, +}; + +/** + * This structure describes how to handle spherical videos, outlining + * information about projection, initial layout, and any other view modifier. + * + * @note The struct must be allocated with av_spherical_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVSphericalMapping { + /** + * Projection type. + */ + enum AVSphericalProjection projection; + + /** + * @name Initial orientation + * @{ + * There fields describe additional rotations applied to the sphere after + * the video frame is mapped onto it. The sphere is rotated around the + * viewer, who remains stationary. The order of transformation is always + * yaw, followed by pitch, and finally by roll. + * + * The coordinate system matches the one defined in OpenGL, where the + * forward vector (z) is coming out of screen, and it is equivalent to + * a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll). + * + * A positive yaw rotates the portion of the sphere in front of the viewer + * toward their right. A positive pitch rotates the portion of the sphere + * in front of the viewer upwards. A positive roll tilts the portion of + * the sphere in front of the viewer to the viewer's right. + * + * These values are exported as 16.16 fixed point. + * + * See this equirectangular projection as example: + * + * @code{.unparsed} + * Yaw + * -180 0 180 + * 90 +-------------+-------------+ 180 + * | | | up + * P | | | y| forward + * i | ^ | | /z + * t 0 +-------------X-------------+ 0 Roll | / + * c | | | | / + * h | | | 0|/_____right + * | | | x + * -90 +-------------+-------------+ -180 + * + * X - the default camera center + * ^ - the default up vector + * @endcode + */ + int32_t yaw; ///< Rotation around the up vector [-180, 180]. + int32_t pitch; ///< Rotation around the right vector [-90, 90]. + int32_t roll; ///< Rotation around the forward vector [-180, 180]. + /** + * @} + */ + + /** + * @name Bounding rectangle + * @anchor bounding + * @{ + * These fields indicate the location of the current tile, and where + * it should be mapped relative to the original surface. They are + * exported as 0.32 fixed point, and can be converted to classic + * pixel values with av_spherical_bounds(). + * + * @code{.unparsed} + * +----------------+----------+ + * | |bound_top | + * | +--------+ | + * | bound_left |tile | | + * +<---------->| |<--->+bound_right + * | +--------+ | + * | | | + * | bound_bottom| | + * +----------------+----------+ + * @endcode + * + * If needed, the original video surface dimensions can be derived + * by adding the current stream or frame size to the related bounds, + * like in the following example: + * + * @code{c} + * original_width = tile->width + bound_left + bound_right; + * original_height = tile->height + bound_top + bound_bottom; + * @endcode + * + * @note These values are valid only for the tiled equirectangular + * projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE), + * and should be ignored in all other cases. + */ + uint32_t bound_left; ///< Distance from the left edge + uint32_t bound_top; ///< Distance from the top edge + uint32_t bound_right; ///< Distance from the right edge + uint32_t bound_bottom; ///< Distance from the bottom edge + /** + * @} + */ + + /** + * Number of pixels to pad from the edge of each cube face. + * + * @note This value is valid for only for the cubemap projection type + * (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other + * cases. + */ + uint32_t padding; +} AVSphericalMapping; + +/** + * Allocate a AVSphericalVideo structure and initialize its fields to default + * values. + * + * @return the newly allocated struct or NULL on failure + */ +AVSphericalMapping *av_spherical_alloc(size_t *size); + +/** + * Convert the @ref bounding fields from an AVSphericalVideo + * from 0.32 fixed point to pixels. + * + * @param map The AVSphericalVideo map to read bound values from. + * @param width Width of the current frame or stream. + * @param height Height of the current frame or stream. + * @param left Pixels from the left edge. + * @param top Pixels from the top edge. + * @param right Pixels from the right edge. + * @param bottom Pixels from the bottom edge. + */ +void av_spherical_tile_bounds(const AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom); + +/** + * Provide a human-readable name of a given AVSphericalProjection. + * + * @param projection The input AVSphericalProjection. + * + * @return The name of the AVSphericalProjection, or "unknown". + */ +const char *av_spherical_projection_name(enum AVSphericalProjection projection); + +/** + * Get the AVSphericalProjection form a human-readable name. + * + * @param name The input string. + * + * @return The AVSphericalProjection value, or -1 if not found. + */ +int av_spherical_from_name(const char *name); +/** + * @} + */ + +#endif /* AVUTIL_SPHERICAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.c b/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.c new file mode 100644 index 00000000..9c29ab01 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avstring.h" +#include "frame.h" +#include "macros.h" +#include "mem.h" +#include "stereo3d.h" + +AVStereo3D *av_stereo3d_alloc(void) +{ + return av_mallocz(sizeof(AVStereo3D)); +} + +AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_STEREO3D, + sizeof(AVStereo3D)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVStereo3D)); + + return (AVStereo3D *)side_data->data; +} + +static const char * const stereo3d_type_names[] = { + [AV_STEREO3D_2D] = "2D", + [AV_STEREO3D_SIDEBYSIDE] = "side by side", + [AV_STEREO3D_TOPBOTTOM] = "top and bottom", + [AV_STEREO3D_FRAMESEQUENCE] = "frame alternate", + [AV_STEREO3D_CHECKERBOARD] = "checkerboard", + [AV_STEREO3D_SIDEBYSIDE_QUINCUNX] = "side by side (quincunx subsampling)", + [AV_STEREO3D_LINES] = "interleaved lines", + [AV_STEREO3D_COLUMNS] = "interleaved columns", +}; + +const char *av_stereo3d_type_name(unsigned int type) +{ + if (type >= FF_ARRAY_ELEMS(stereo3d_type_names)) + return "unknown"; + + return stereo3d_type_names[type]; +} + +int av_stereo3d_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_type_names); i++) { + if (av_strstart(name, stereo3d_type_names[i], NULL)) + return i; + } + + return -1; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.h b/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.h new file mode 100644 index 00000000..3aab959b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/stereo3d.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_video_stereo3d + * Stereoscopic video + */ + +#ifndef AVUTIL_STEREO3D_H +#define AVUTIL_STEREO3D_H + +#include + +#include "frame.h" + +/** + * @defgroup lavu_video_stereo3d Stereo3D types and functions + * @ingroup lavu_video + * + * A stereoscopic video file consists in multiple views embedded in a single + * frame, usually describing two views of a scene. This file describes all + * possible codec-independent view arrangements. + * + * @{ + */ + +/** + * List of possible 3D Types + */ +enum AVStereo3DType { + /** + * Video is not stereoscopic (and metadata has to be there). + */ + AV_STEREO3D_2D, + + /** + * Views are next to each other. + * + * @code{.unparsed} + * LLLLRRRR + * LLLLRRRR + * LLLLRRRR + * ... + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE, + + /** + * Views are on top of each other. + * + * @code{.unparsed} + * LLLLLLLL + * LLLLLLLL + * RRRRRRRR + * RRRRRRRR + * @endcode + */ + AV_STEREO3D_TOPBOTTOM, + + /** + * Views are alternated temporally. + * + * @code{.unparsed} + * frame0 frame1 frame2 ... + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * ... ... ... + * @endcode + */ + AV_STEREO3D_FRAMESEQUENCE, + + /** + * Views are packed in a checkerboard-like structure per pixel. + * + * @code{.unparsed} + * LRLRLRLR + * RLRLRLRL + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_CHECKERBOARD, + + /** + * Views are next to each other, but when upscaling + * apply a checkerboard pattern. + * + * @code{.unparsed} + * LLLLRRRR L L L L R R R R + * LLLLRRRR => L L L L R R R R + * LLLLRRRR L L L L R R R R + * LLLLRRRR L L L L R R R R + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE_QUINCUNX, + + /** + * Views are packed per line, as if interlaced. + * + * @code{.unparsed} + * LLLLLLLL + * RRRRRRRR + * LLLLLLLL + * ... + * @endcode + */ + AV_STEREO3D_LINES, + + /** + * Views are packed per column. + * + * @code{.unparsed} + * LRLRLRLR + * LRLRLRLR + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_COLUMNS, +}; + +/** + * List of possible view types. + */ +enum AVStereo3DView { + /** + * Frame contains two packed views. + */ + AV_STEREO3D_VIEW_PACKED, + + /** + * Frame contains only the left view. + */ + AV_STEREO3D_VIEW_LEFT, + + /** + * Frame contains only the right view. + */ + AV_STEREO3D_VIEW_RIGHT, +}; + +/** + * Inverted views, Right/Bottom represents the left view. + */ +#define AV_STEREO3D_FLAG_INVERT (1 << 0) + +/** + * Stereo 3D type: this structure describes how two videos are packed + * within a single video surface, with additional information as needed. + * + * @note The struct must be allocated with av_stereo3d_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVStereo3D { + /** + * How views are packed within the video. + */ + enum AVStereo3DType type; + + /** + * Additional information about the frame packing. + */ + int flags; + + /** + * Determines which views are packed. + */ + enum AVStereo3DView view; +} AVStereo3D; + +/** + * Allocate an AVStereo3D structure and set its fields to default values. + * The resulting struct can be freed using av_freep(). + * + * @return An AVStereo3D filled with default values or NULL on failure. + */ +AVStereo3D *av_stereo3d_alloc(void); + +/** + * Allocate a complete AVFrameSideData and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVStereo3D structure to be filled by caller. + */ +AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame); + +/** + * Provide a human-readable name of a given stereo3d type. + * + * @param type The input stereo3d type value. + * + * @return The name of the stereo3d value, or "unknown". + */ +const char *av_stereo3d_type_name(unsigned int type); + +/** + * Get the AVStereo3DType form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DType value, or -1 if not found. + */ +int av_stereo3d_from_name(const char *name); + +/** + * @} + */ + +#endif /* AVUTIL_STEREO3D_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tablegen.h b/arm/raspi/third_party/ffmpeg/libavutil/tablegen.h new file mode 100644 index 00000000..02acdd61 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tablegen.h @@ -0,0 +1,55 @@ +/* + * 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 + * Compatibility libm for table generation files + */ + +#ifndef AVUTIL_TABLEGEN_H +#define AVUTIL_TABLEGEN_H + +#include + +// we lack some functions on all host platforms, and we don't care about +// performance and/or strict ISO C semantics as it's performed at build time +static inline double ff_cbrt(double x) +{ + return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0); +} +#define cbrt ff_cbrt + +static inline double ff_rint(double x) +{ + return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); +} +#define rint ff_rint + +static inline long long ff_llrint(double x) +{ + return rint(x); +} +#define llrint ff_llrint + +static inline long ff_lrint(double x) +{ + return rint(x); +} +#define lrint ff_lrint + +#endif /* AVUTIL_TABLEGEN_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tea.c b/arm/raspi/third_party/ffmpeg/libavutil/tea.c new file mode 100644 index 00000000..93a37953 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tea.c @@ -0,0 +1,121 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "intreadwrite.h" +#include "mem.h" +#include "tea.h" + +typedef struct AVTEA { + uint32_t key[16]; + int rounds; +} AVTEA; + +struct AVTEA *av_tea_alloc(void) +{ + return av_mallocz(sizeof(struct AVTEA)); +} + +const int av_tea_size = sizeof(AVTEA); + +void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RB32(key + (i << 2)); + + ctx->rounds = rounds; +} + +static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; + int rounds = ctx->rounds; + uint32_t k0, k1, k2, k3; + k0 = ctx->key[0]; + k1 = ctx->key[1]; + k2 = ctx->key[2]; + k3 = ctx->key[3]; + + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + if (decrypt) { + int i; + uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); + + for (i = 0; i < rounds / 2; i++) { + v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); + v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); + sum -= delta; + } + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + } else { + int i; + uint32_t sum = 0, delta = 0x9E3779B9U; + + for (i = 0; i < rounds / 2; i++) { + sum += delta; + v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); + v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); + } + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); +} + +void av_tea_crypt(AVTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + int i; + + if (decrypt) { + while (count--) { + tea_crypt_ecb(ctx, dst, src, decrypt, iv); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + tea_crypt_ecb(ctx, dst, dst, decrypt, NULL); + memcpy(iv, dst, 8); + } else { + tea_crypt_ecb(ctx, dst, src, decrypt, NULL); + } + src += 8; + dst += 8; + } + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tea.h b/arm/raspi/third_party/ffmpeg/libavutil/tea.h new file mode 100644 index 00000000..dd929bda --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tea.h @@ -0,0 +1,71 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TEA_H +#define AVUTIL_TEA_H + +#include + +/** + * @file + * @brief Public header for libavutil TEA algorithm + * @defgroup lavu_tea TEA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_tea_size; + +struct AVTEA; + +/** + * Allocate an AVTEA context + * To free the struct: av_free(ptr) + */ +struct AVTEA *av_tea_alloc(void); + +/** + * Initialize an AVTEA context. + * + * @param ctx an AVTEA context + * @param key a key of 16 bytes used for encryption/decryption + * @param rounds the number of rounds in TEA (64 is the "standard") + */ +void av_tea_init(struct AVTEA *ctx, const uint8_t key[16], int rounds); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_tea_crypt(struct AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_TEA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/.gitignore b/arm/raspi/third_party/ffmpeg/libavutil/tests/.gitignore new file mode 100644 index 00000000..87895912 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/.gitignore @@ -0,0 +1,53 @@ +/adler32 +/aes +/aes_ctr +/atomic +/audio_fifo +/avstring +/base64 +/blowfish +/bprint +/camellia +/cast5 +/channel_layout +/color_utils +/cpu +/cpu_init +/crc +/des +/dict +/display +/error +/encryption_info +/eval +/fifo +/file +/hash +/hmac +/hwdevice +/imgutils +/integer +/lfg +/lls +/log +/lzo +/md5 +/murmur3 +/opt +/parseutils +/pca +/pixdesc +/pixelutils +/pixfmt_best +/random_seed +/rational +/ripemd +/sha +/sha512 +/softfloat +/tea +/tree +/twofish +/utf8 +/uuid +/xtea diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/adler32.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/adler32.c new file mode 100644 index 00000000..356e1a97 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/adler32.c @@ -0,0 +1,54 @@ +/* + * 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 + */ + +// LCOV_EXCL_START + +#include "libavutil/timer.h" + +#include + +#include "libavutil/log.h" +#include "libavutil/adler32.h" + +#define LEN 7001 + +int main(int argc, char **argv) +{ + int i; + uint8_t data[LEN]; + AVAdler checksum; + + av_log_set_level(AV_LOG_DEBUG); + + for (i = 0; i < LEN; i++) + data[i] = ((i * i) >> 3) + 123 * i; + + if (argc > 1 && !strcmp(argv[1], "-t")) { + for (i = 0; i < 1000; i++) { + START_TIMER; + checksum = av_adler32_update(1, data, LEN); + STOP_TIMER("adler"); + } + } else { + checksum = av_adler32_update(1, data, LEN); + } + + av_log(NULL, AV_LOG_DEBUG, "%X (expected 50E6E508)\n", checksum); + return checksum == 0x50e6e508 ? 0 : 1; +} +// LCOV_EXCL_STOP diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/aes.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/aes.c new file mode 100644 index 00000000..c7f842c1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/aes.c @@ -0,0 +1,122 @@ +/* + * 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 + */ + +// LCOV_EXCL_START + +#include "libavutil/timer.h" + +#include + +#include "libavutil/aes.h" +#include "libavutil/lfg.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" + +int main(int argc, char **argv) +{ + int i, j; + struct AVAES *b; + static const uint8_t rkey[2][16] = { + { 0 }, + { 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, + 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 } + }; + static const uint8_t rpt[2][16] = { + { 0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad, + 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3 }, + { 0 } + }; + static const uint8_t rct[2][16] = { + { 0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7, + 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf }, + { 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, + 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 } + }; + uint8_t pt[32]; + uint8_t temp[32]; + uint8_t iv[2][16]; + int err = 0; + + b = av_aes_alloc(); + if (!b) + return 1; + + av_log_set_level(AV_LOG_DEBUG); + + for (i = 0; i < 2; i++) { + av_aes_init(b, rkey[i], 128, 1); + av_aes_crypt(b, temp, rct[i], 1, NULL, 1); + for (j = 0; j < 16; j++) { + if (rpt[i][j] != temp[j]) { + av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", + j, rpt[i][j], temp[j]); + err = 1; + } + } + } + av_free(b); + + if (argc > 1 && !strcmp(argv[1], "-t")) { + struct AVAES *ae, *ad; + AVLFG prng; + + ae = av_aes_alloc(); + ad = av_aes_alloc(); + + if (!ae || !ad) { + av_free(ae); + av_free(ad); + return 1; + } + + av_aes_init(ae, (const uint8_t*)"PI=3.141592654..", 128, 0); + av_aes_init(ad, (const uint8_t*)"PI=3.141592654..", 128, 1); + av_lfg_init(&prng, 1); + + for (i = 0; i < 10000; i++) { + for (j = 0; j < 32; j++) + pt[j] = av_lfg_get(&prng); + for (j = 0; j < 16; j++) + iv[0][j] = iv[1][j] = av_lfg_get(&prng); + { + START_TIMER; + av_aes_crypt(ae, temp, pt, 2, iv[0], 0); + if (!(i & (i - 1))) + av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", + temp[0], temp[5], temp[10], temp[15]); + av_aes_crypt(ad, temp, temp, 2, iv[1], 1); + av_aes_crypt(ae, temp, pt, 2, NULL, 0); + if (!(i & (i - 1))) + av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", + temp[0], temp[5], temp[10], temp[15]); + av_aes_crypt(ad, temp, temp, 2, NULL, 1); + STOP_TIMER("aes"); + } + for (j = 0; j < 16; j++) { + if (pt[j] != temp[j]) { + av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", + i, j, pt[j], temp[j]); + } + } + } + av_free(ae); + av_free(ad); + } + return err; +} +// LCOV_EXCL_STOP diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/aes_ctr.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/aes_ctr.c new file mode 100644 index 00000000..486dae33 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/aes_ctr.c @@ -0,0 +1,67 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/log.h" +#include "libavutil/mem_internal.h" +#include "libavutil/aes_ctr.h" + +static const DECLARE_ALIGNED(8, uint8_t, plain)[] = { + 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d +}; +static DECLARE_ALIGNED(8, uint8_t, tmp)[11]; + +int main (void) +{ + int ret = 1; + struct AVAESCTR *ae, *ad; + const uint8_t *iv; + + ae = av_aes_ctr_alloc(); + ad = av_aes_ctr_alloc(); + + if (!ae || !ad) + goto ERROR; + + if (av_aes_ctr_init(ae, (const uint8_t*)"0123456789abcdef") < 0) + goto ERROR; + + if (av_aes_ctr_init(ad, (const uint8_t*)"0123456789abcdef") < 0) + goto ERROR; + + av_aes_ctr_set_random_iv(ae); + iv = av_aes_ctr_get_iv(ae); + av_aes_ctr_set_full_iv(ad, iv); + + av_aes_ctr_crypt(ae, tmp, plain, sizeof(tmp)); + av_aes_ctr_crypt(ad, tmp, tmp, sizeof(tmp)); + + if (memcmp(tmp, plain, sizeof(tmp)) != 0){ + av_log(NULL, AV_LOG_ERROR, "test failed\n"); + goto ERROR; + } + + av_log(NULL, AV_LOG_INFO, "test passed\n"); + ret = 0; + +ERROR: + av_aes_ctr_free(ae); + av_aes_ctr_free(ad); + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/audio_fifo.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/audio_fifo.c new file mode 100644 index 00000000..c9d6bfc7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/audio_fifo.c @@ -0,0 +1,201 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "config.h" + +#include +#include +#include +#include "libavutil/mem.h" +#include "libavutil/audio_fifo.c" + +#define MAX_CHANNELS 32 + + +typedef struct TestStruct { + const enum AVSampleFormat format; + const int nb_ch; + void const *data_planes[MAX_CHANNELS]; + const int nb_samples_pch; +} TestStruct; + +static const uint8_t data_U8 [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; +static const int16_t data_S16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; +static const float data_FLT[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0}; + +static const TestStruct test_struct[] = { + {.format = AV_SAMPLE_FMT_U8 , .nb_ch = 1, .data_planes = {data_U8 , }, .nb_samples_pch = 12}, + {.format = AV_SAMPLE_FMT_U8P , .nb_ch = 2, .data_planes = {data_U8 , data_U8 +6, }, .nb_samples_pch = 6 }, + {.format = AV_SAMPLE_FMT_S16 , .nb_ch = 1, .data_planes = {data_S16, }, .nb_samples_pch = 12}, + {.format = AV_SAMPLE_FMT_S16P , .nb_ch = 2, .data_planes = {data_S16, data_S16+6, }, .nb_samples_pch = 6 }, + {.format = AV_SAMPLE_FMT_FLT , .nb_ch = 1, .data_planes = {data_FLT, }, .nb_samples_pch = 12}, + {.format = AV_SAMPLE_FMT_FLTP , .nb_ch = 2, .data_planes = {data_FLT, data_FLT+6, }, .nb_samples_pch = 6 } +}; + +static void free_data_planes(AVAudioFifo *afifo, void **output_data) +{ + int i; + for (i = 0; i < afifo->nb_buffers; ++i){ + av_freep(&output_data[i]); + } + av_freep(&output_data); +} + +static void ERROR(const char *str) +{ + fprintf(stderr, "%s\n", str); + exit(1); +} + +static void print_audio_bytes(const TestStruct *test_sample, void **data_planes, int nb_samples) +{ + int p, b, f; + int byte_offset = av_get_bytes_per_sample(test_sample->format); + int buffers = av_sample_fmt_is_planar(test_sample->format) + ? test_sample->nb_ch : 1; + int line_size = (buffers > 1) ? nb_samples * byte_offset + : nb_samples * byte_offset * test_sample->nb_ch; + for (p = 0; p < buffers; ++p){ + for(b = 0; b < line_size; b+=byte_offset){ + for (f = 0; f < byte_offset; f++){ + int order = !HAVE_BIGENDIAN ? (byte_offset - f - 1) : f; + printf("%02x", *((uint8_t*)data_planes[p] + b + order)); + } + putchar(' '); + } + putchar('\n'); + } +} + +static int read_samples_from_audio_fifo(AVAudioFifo* afifo, void ***output, int nb_samples) +{ + int i; + int samples = FFMIN(nb_samples, afifo->nb_samples); + int tot_elements = !av_sample_fmt_is_planar(afifo->sample_fmt) + ? samples : afifo->channels * samples; + void **data_planes = av_malloc_array(afifo->nb_buffers, sizeof(void*)); + if (!data_planes) + ERROR("failed to allocate memory!"); + if (*output) + free_data_planes(afifo, *output); + *output = data_planes; + + for (i = 0; i < afifo->nb_buffers; ++i){ + data_planes[i] = av_malloc_array(tot_elements, afifo->sample_size); + if (!data_planes[i]) + ERROR("failed to allocate memory!"); + } + + return av_audio_fifo_read(afifo, *output, nb_samples); +} + +static int write_samples_to_audio_fifo(AVAudioFifo* afifo, const TestStruct *test_sample, + int nb_samples, int offset) +{ + int offset_size, i; + void *data_planes[MAX_CHANNELS]; + + if(nb_samples > test_sample->nb_samples_pch - offset){ + return 0; + } + if(offset >= test_sample->nb_samples_pch){ + return 0; + } + offset_size = offset * afifo->sample_size; + + for (i = 0; i < afifo->nb_buffers ; ++i){ + data_planes[i] = (uint8_t*)test_sample->data_planes[i] + offset_size; + } + + return av_audio_fifo_write(afifo, data_planes, nb_samples); +} + +static void test_function(const TestStruct *test_sample) +{ + int ret, i; + void **output_data = NULL; + AVAudioFifo *afifo = av_audio_fifo_alloc(test_sample->format, test_sample->nb_ch, + test_sample->nb_samples_pch); + if (!afifo) { + ERROR("ERROR: av_audio_fifo_alloc returned NULL!"); + } + ret = write_samples_to_audio_fifo(afifo, test_sample, test_sample->nb_samples_pch, 0); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_write failed!"); + } + printf("written: %d\n", ret); + + ret = write_samples_to_audio_fifo(afifo, test_sample, test_sample->nb_samples_pch, 0); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_write failed!"); + } + printf("written: %d\n", ret); + printf("remaining samples in audio_fifo: %d\n\n", av_audio_fifo_size(afifo)); + + ret = read_samples_from_audio_fifo(afifo, &output_data, test_sample->nb_samples_pch); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_read failed!"); + } + printf("read: %d\n", ret); + print_audio_bytes(test_sample, output_data, ret); + printf("remaining samples in audio_fifo: %d\n\n", av_audio_fifo_size(afifo)); + + /* test av_audio_fifo_peek */ + ret = av_audio_fifo_peek(afifo, output_data, afifo->nb_samples); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_peek failed!"); + } + printf("peek:\n"); + print_audio_bytes(test_sample, output_data, ret); + printf("\n"); + + /* test av_audio_fifo_peek_at */ + printf("peek_at:\n"); + for (i = 0; i < afifo->nb_samples; ++i){ + ret = av_audio_fifo_peek_at(afifo, output_data, 1, i); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_peek_at failed!"); + } + printf("%d:\n", i); + print_audio_bytes(test_sample, output_data, ret); + } + printf("\n"); + + /* test av_audio_fifo_drain */ + ret = av_audio_fifo_drain(afifo, afifo->nb_samples); + if (ret < 0){ + ERROR("ERROR: av_audio_fifo_drain failed!"); + } + if (afifo->nb_samples){ + ERROR("drain failed to flush all samples in audio_fifo!"); + } + + /* deallocate */ + free_data_planes(afifo, output_data); + av_audio_fifo_free(afifo); +} + +int main(void) +{ + int t, tests = sizeof(test_struct)/sizeof(test_struct[0]); + + for (t = 0; t < tests; ++t){ + printf("\nTEST: %d\n\n", t+1); + test_function(&test_struct[t]); + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/avstring.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/avstring.c new file mode 100644 index 00000000..37a2cf18 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/avstring.c @@ -0,0 +1,129 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/mem.h" +#include "libavutil/avstring.h" + +int main(void) +{ + int i; + char *fullpath, *ptr; + static const char * const strings[] = { + "''", + "", + ":", + "\\", + "'", + " '' :", + " '' '' :", + "foo '' :", + "'foo'", + "foo ", + " ' foo ' ", + "foo\\", + "foo': blah:blah", + "foo\\: blah:blah", + "foo\'", + "'foo : ' :blahblah", + "\\ :blah", + " foo", + " foo ", + " foo \\ ", + "foo ':blah", + " foo bar : blahblah", + "\\f\\o\\o", + "'foo : \\ \\ ' : blahblah", + "'\\fo\\o:': blahblah", + "\\'fo\\o\\:': foo ' :blahblah" + }; + const char *haystack = "Education consists mainly in what we have unlearned."; + const char * const needle[] = {"learned.", "unlearned.", "Unlearned"}; + + printf("Testing av_get_token()\n"); + for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) { + const char *p = strings[i]; + char *q; + printf("|%s|", p); + q = av_get_token(&p, ":"); + printf(" -> |%s|", q); + printf(" + |%s|\n", p); + av_free(q); + } + + printf("Testing av_append_path_component()\n"); + #define TEST_APPEND_PATH_COMPONENT(path, component, expected) \ + fullpath = av_append_path_component((path), (component)); \ + printf("%s = %s\n", fullpath ? fullpath : "(null)", expected); \ + av_free(fullpath); + TEST_APPEND_PATH_COMPONENT(NULL, NULL, "(null)") + TEST_APPEND_PATH_COMPONENT("path", NULL, "path"); + TEST_APPEND_PATH_COMPONENT(NULL, "comp", "comp"); + TEST_APPEND_PATH_COMPONENT("path", "comp", "path/comp"); + TEST_APPEND_PATH_COMPONENT("path/", "comp", "path/comp"); + TEST_APPEND_PATH_COMPONENT("path", "/comp", "path/comp"); + TEST_APPEND_PATH_COMPONENT("path/", "/comp", "path/comp"); + TEST_APPEND_PATH_COMPONENT("path/path2/", "/comp/comp2", "path/path2/comp/comp2"); + + /*Testing av_strnstr()*/ + #define TEST_STRNSTR(haystack, needle, hay_length, expected) \ + ptr = av_strnstr(haystack, needle, hay_length); \ + if (ptr != expected){ \ + printf("expected: %p, received %p\n", expected, ptr); \ + } + TEST_STRNSTR(haystack, needle [0], strlen(haystack), haystack+44); + TEST_STRNSTR(haystack, needle [1], strlen(haystack), haystack+42); + TEST_STRNSTR(haystack, needle [2], strlen(haystack), NULL ); + TEST_STRNSTR(haystack, strings[1], strlen(haystack), haystack ); + + /*Testing av_strireplace()*/ + #define TEST_STRIREPLACE(haystack, needle, expected) \ + ptr = av_strireplace(haystack, needle, "instead"); \ + if (ptr == NULL) { \ + printf("error, received null pointer!\n"); \ + } else { \ + if (strcmp(ptr, expected) != 0) \ + printf( "expected: %s, received: %s\n", expected, ptr); \ + av_free(ptr); \ + } + + TEST_STRIREPLACE(haystack, needle [0], "Education consists mainly in what we have uninstead"); + TEST_STRIREPLACE(haystack, needle [1], "Education consists mainly in what we have instead"); + TEST_STRIREPLACE(haystack, needle [2], "Education consists mainly in what we have instead."); + TEST_STRIREPLACE(haystack, needle [1], "Education consists mainly in what we have instead"); + +#if FF_API_D2STR +FF_DISABLE_DEPRECATION_WARNINGS + /*Testing av_d2str()*/ + #define TEST_D2STR(value, expected) \ + if((ptr = av_d2str(value)) == NULL){ \ + printf("error, received null pointer!\n"); \ + } else { \ + if(strcmp(ptr, expected) != 0) \ + printf( "expected: %s, received: %s\n", expected, ptr); \ + av_free(ptr); \ + } + TEST_D2STR(0 , "0.000000"); + TEST_D2STR(-1.2333234, "-1.233323"); + TEST_D2STR(-1.2333237, "-1.233324"); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/base64.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/base64.c new file mode 100644 index 00000000..400e01ce --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/base64.c @@ -0,0 +1,130 @@ +/* + * 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 + */ + +// LCOV_EXCL_START + +#include "libavutil/timer.h" + +#include +#include + +#include "libavutil/common.h" +#include "libavutil/base64.h" + +#define MAX_DATA_SIZE 1024 +#define MAX_ENCODED_SIZE 2048 + +static int test_encode_decode(const uint8_t *data, unsigned int data_size, + const char *encoded_ref) +{ + char encoded[MAX_ENCODED_SIZE]; + uint8_t data2[MAX_DATA_SIZE]; + int data2_size, max_data2_size = MAX_DATA_SIZE; + + if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) { + printf("Failed: cannot encode the input data\n"); + return 1; + } + if (encoded_ref && strcmp(encoded, encoded_ref)) { + printf("Failed: encoded string differs from reference\n" + "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref); + return 1; + } + + if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) != data_size) { + printf("Failed: cannot decode the encoded string\n" + "Encoded:\n%s\n", encoded); + return 1; + } + if ((data2_size = av_base64_decode(data2, encoded, data_size)) != data_size) { + printf("Failed: cannot decode with minimal buffer\n" + "Encoded:\n%s\n", encoded); + return 1; + } + if (memcmp(data2, data, data_size)) { + printf("Failed: encoded/decoded data differs from original data\n"); + return 1; + } + if (av_base64_decode(NULL, encoded, 0) != 0) { + printf("Failed: decode to NULL buffer\n"); + return 1; + } + if (strlen(encoded)) { + char *end = strchr(encoded, '='); + if (!end) + end = encoded + strlen(encoded) - 1; + *end = '%'; + if (av_base64_decode(NULL, encoded, 0) >= 0) { + printf("Failed: error detection\n"); + return 1; + } + } + + printf("Passed!\n"); + return 0; +} + +int main(int argc, char ** argv) +{ + int i, error_count = 0; + struct test { + const uint8_t *data; + const char *encoded_ref; + } tests[] = { + { "", ""}, + { "1", "MQ=="}, + { "22", "MjI="}, + { "333", "MzMz"}, + { "4444", "NDQ0NA=="}, + { "55555", "NTU1NTU="}, + { "666666", "NjY2NjY2"}, + { "abc:def", "YWJjOmRlZg=="}, + }; + char in[1024], out[2048]; + + printf("Encoding/decoding tests\n"); + for (i = 0; i < FF_ARRAY_ELEMS(tests); i++) + error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref); + + if (argc>1 && !strcmp(argv[1], "-t")) { + memset(in, 123, sizeof(in)); + for(i=0; i<10000; i++){ + START_TIMER + av_base64_encode(out, sizeof(out), in, sizeof(in)); + STOP_TIMER("encode") + } + for(i=0; i<10000; i++){ + START_TIMER + av_base64_decode(in, out, sizeof(in)); + STOP_TIMER("decode") + } + + for(i=0; i<10000; i++){ + START_TIMER + av_base64_decode(NULL, out, 0); + STOP_TIMER("syntax check") + } + } + + if (error_count) + printf("Error Count: %d.\n", error_count); + + return !!error_count; +} + +// LCOV_EXCL_STOP diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/blowfish.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/blowfish.c new file mode 100644 index 00000000..f4c9ced9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/blowfish.c @@ -0,0 +1,194 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "libavutil/mem.h" +#include "libavutil/blowfish.h" + +#define NUM_VARIABLE_KEY_TESTS 34 + +/* plaintext bytes -- left halves */ +static const uint32_t plaintext_l[NUM_VARIABLE_KEY_TESTS] = { + 0x00000000, 0xFFFFFFFF, 0x10000000, 0x11111111, 0x11111111, + 0x01234567, 0x00000000, 0x01234567, 0x01A1D6D0, 0x5CD54CA8, + 0x0248D438, 0x51454B58, 0x42FD4430, 0x059B5E08, 0x0756D8E0, + 0x762514B8, 0x3BDD1190, 0x26955F68, 0x164D5E40, 0x6B056E18, + 0x004BD6EF, 0x480D3900, 0x437540C8, 0x072D43A0, 0x02FE5577, + 0x1D9D5C50, 0x30553228, 0x01234567, 0x01234567, 0x01234567, + 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF +}; + +/* plaintext bytes -- right halves */ +static const uint32_t plaintext_r[NUM_VARIABLE_KEY_TESTS] = { + 0x00000000, 0xFFFFFFFF, 0x00000001, 0x11111111, 0x11111111, + 0x89ABCDEF, 0x00000000, 0x89ABCDEF, 0x39776742, 0x3DEF57DA, + 0x06F67172, 0x2DDF440A, 0x59577FA2, 0x51CF143A, 0x774761D2, + 0x29BF486A, 0x49372802, 0x35AF609A, 0x4F275232, 0x759F5CCA, + 0x09176062, 0x6EE762F2, 0x698F3CFA, 0x77075292, 0x8117F12A, + 0x18F728C2, 0x6D6F295A, 0x89ABCDEF, 0x89ABCDEF, 0x89ABCDEF, + 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF +}; + +/* key bytes for variable key tests */ +static const uint8_t variable_key[NUM_VARIABLE_KEY_TESTS][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 }, + { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E }, + { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86 }, + { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E }, + { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6 }, + { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE }, + { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6 }, + { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE }, + { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16 }, + { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F }, + { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46 }, + { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E }, + { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76 }, + { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07 }, + { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F }, + { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7 }, + { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF }, + { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6 }, + { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } +}; + +/* ciphertext bytes -- left halves */ +static const uint32_t ciphertext_l[NUM_VARIABLE_KEY_TESTS] = { + 0x4EF99745, 0x51866FD5, 0x7D856F9A, 0x2466DD87, 0x61F9C380, + 0x7D0CC630, 0x4EF99745, 0x0ACEAB0F, 0x59C68245, 0xB1B8CC0B, + 0x1730E577, 0xA25E7856, 0x353882B1, 0x48F4D088, 0x432193B7, + 0x13F04154, 0x2EEDDA93, 0xD887E039, 0x5F99D04F, 0x4A057A3B, + 0x452031C1, 0x7555AE39, 0x53C55F9C, 0x7A8E7BFA, 0xCF9C5D7A, + 0xD1ABB290, 0x55CB3774, 0xFA34EC48, 0xA7907951, 0xC39E072D, + 0x014933E0, 0xF21E9A77, 0x24594688, 0x6B5C5A9C +}; + +/* ciphertext bytes -- right halves */ +static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = { + 0x6198DD78, 0xB85ECB8A, 0x613063F2, 0x8B963C9D, 0x2281B096, + 0xAFDA1EC7, 0x6198DD78, 0xC6A0A28D, 0xEB05282B, 0x250F09A0, + 0x8BEA1DA4, 0xCF2651EB, 0x09CE8F1A, 0x4C379918, 0x8951FC98, + 0xD69D1AE5, 0xFFD39C79, 0x3C2DA6E3, 0x5B163969, 0x24D3977B, + 0xE4FADA8E, 0xF59B87BD, 0xB49FC019, 0x937E89A3, 0x4986ADB5, + 0x658BC778, 0xD13EF201, 0x47B268B2, 0x08EA3CAE, 0x9FAC631D, + 0xCDAFF6E4, 0xB71C49BC, 0x5754369A, 0x5D9E0A5A +}; + +/* plaintext bytes */ +static const uint8_t plaintext[8] = "BLOWFISH"; + +static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH"; + +/* ciphertext bytes */ +static const uint8_t ciphertext[8] = { + 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 +}; + +static const uint8_t ciphertext2[16] = { + 0x53, 0x00, 0x40, 0x06, 0x63, 0xf2, 0x1d, 0x99, + 0x3b, 0x9b, 0x27, 0x64, 0x46, 0xfd, 0x20, 0xc1, +}; + +#define IV "blowfish" + +static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + const uint8_t *ref, int len, uint8_t *iv, int dir, + const char *test) +{ + av_blowfish_crypt(ctx, dst, src, len, iv, dir); + if (memcmp(dst, ref, 8*len)) { + int i; + printf("%s failed\ngot ", test); + for (i = 0; i < 8*len; i++) + printf("%02x ", dst[i]); + printf("\nexpected "); + for (i = 0; i < 8*len; i++) + printf("%02x ", ref[i]); + printf("\n"); + exit(1); + } +} + +int main(void) +{ + uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS]; + uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS]; + uint8_t tmp[16], iv[8]; + int i; + AVBlowfish *ctx = av_blowfish_alloc(); + if (!ctx) + return 1; + + av_blowfish_init(ctx, "abcdefghijklmnopqrstuvwxyz", 26); + + test_blowfish(ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption"); + test_blowfish(ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption"); + test_blowfish(ctx, tmp, tmp, ciphertext, 1, NULL, 0, "Inplace encryption"); + test_blowfish(ctx, tmp, tmp, plaintext, 1, NULL, 1, "Inplace decryption"); + memcpy(iv, IV, 8); + test_blowfish(ctx, tmp, plaintext2, ciphertext2, 2, iv, 0, "CBC encryption"); + memcpy(iv, IV, 8); + test_blowfish(ctx, tmp, ciphertext2, plaintext2, 2, iv, 1, "CBC decryption"); + memcpy(iv, IV, 8); + test_blowfish(ctx, tmp, tmp, ciphertext2, 2, iv, 0, "Inplace CBC encryption"); + memcpy(iv, IV, 8); + test_blowfish(ctx, tmp, tmp, plaintext2, 2, iv, 1, "Inplace CBC decryption"); + + memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS); + memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS); + + for (i = 0; i < NUM_VARIABLE_KEY_TESTS; i++) { + av_blowfish_init(ctx, variable_key[i], 8); + + av_blowfish_crypt_ecb(ctx, &tmptext_l[i], &tmptext_r[i], 0); + if (tmptext_l[i] != ciphertext_l[i] || tmptext_r[i] != ciphertext_r[i]) { + printf("Test encryption failed.\n"); + return 2; + } + + av_blowfish_crypt_ecb(ctx, &tmptext_l[i], &tmptext_r[i], 1); + if (tmptext_l[i] != plaintext_l[i] || tmptext_r[i] != plaintext_r[i]) { + printf("Test decryption failed.\n"); + return 3; + } + } + printf("Test encryption/decryption success.\n"); + av_free(ctx); + + return 0; +} + diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/bprint.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/bprint.c new file mode 100644 index 00000000..d7f9abf2 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/bprint.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" +#include "libavutil/bprint.c" + +#undef printf + +static void bprint_pascal(AVBPrint *b, unsigned size) +{ + unsigned i, j; + unsigned p[42]; + + av_assert0(size < FF_ARRAY_ELEMS(p)); + + p[0] = 1; + av_bprintf(b, "%8d\n", 1); + for (i = 1; i <= size; i++) { + p[i] = 1; + for (j = i - 1; j > 0; j--) + p[j] = p[j] + p[j - 1]; + for (j = 0; j <= i; j++) + av_bprintf(b, "%8d", p[j]); + av_bprintf(b, "\n"); + } +} + +int main(void) +{ + AVBPrint b; + char buf[256]; + struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 }; + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_UNLIMITED); + bprint_pascal(&b, 5); + printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); + printf("%s\n", b.str); + av_bprint_finalize(&b, NULL); + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_UNLIMITED); + bprint_pascal(&b, 25); + printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); + av_bprint_finalize(&b, NULL); + + av_bprint_init(&b, 0, 2048); + bprint_pascal(&b, 25); + printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); + av_bprint_finalize(&b, NULL); + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_AUTOMATIC); + bprint_pascal(&b, 5); + printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_AUTOMATIC); + bprint_pascal(&b, 25); + printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len); + /* Note that the size of the automatic buffer is arch-dependent. */ + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_COUNT_ONLY); + bprint_pascal(&b, 25); + printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len); + + av_bprint_init_for_buffer(&b, buf, sizeof(buf)); + bprint_pascal(&b, 25); + printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len); + + av_bprint_init(&b, 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_strftime(&b, "%Y-%m-%d", &testtime); + printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str); + av_bprint_finalize(&b, NULL); + + av_bprint_init(&b, 0, 8); + av_bprint_strftime(&b, "%Y-%m-%d", &testtime); + printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/camellia.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/camellia.c new file mode 100644 index 00000000..9fdd6cd7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/camellia.c @@ -0,0 +1,79 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/camellia.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" + +int main(int argc, char *argv[]) +{ + const uint8_t Key[3][32] = { + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff} + }; + const uint8_t rct[3][16] = { + {0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43}, + {0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9,0x96, 0xf8, 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9}, + {0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09} + }; + const uint8_t rpt[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; + const int kbits[3] = {128, 192, 256}; + int i, j, err = 0; + uint8_t temp[32], iv[16]; + struct AVCAMELLIA *cs; + cs = av_camellia_alloc(); + if (!cs) + return 1; + for (j = 0; j < 3; j++) { + av_camellia_init(cs, Key[j], kbits[j]); + av_camellia_crypt(cs, temp, rpt, 1, NULL, 0); + for (i = 0; i < 16; i++) { + if (rct[j][i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]); + err = 1; + } + } + av_camellia_crypt(cs, temp, rct[j], 1, NULL, 1); + for (i = 0; i < 16; i++) { + if (rpt[i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]); + err = 1; + } + } + } + av_camellia_init(cs, Key[0], 128); + memcpy(iv, "HALLO123HALLO123", 16); + av_camellia_crypt(cs, temp, rpt, 2, iv, 0); + memcpy(iv, "HALLO123HALLO123", 16); + av_camellia_crypt(cs, temp, temp, 2, iv, 1); + for (i = 0; i < 32; i++) { + if (rpt[i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]); + err = 1; + } + } + av_free(cs); + return err; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/cast5.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/cast5.c new file mode 100644 index 00000000..1ba3075e --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/cast5.c @@ -0,0 +1,107 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/cast5.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" + +int main(int argc, char** argv) +{ + + static const uint8_t Key[3][16] = { + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a}, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45}, + {0x01, 0x23, 0x45, 0x67, 0x12} + }; + static const uint8_t rpt[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; + static const uint8_t rct[3][8] = { + {0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2}, + {0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b}, + {0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e} + }; + static const uint8_t rct2[2][16] = { + {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6, 0xb3, 0x43, 0x6f, 0xb8, 0x9d, 0x6d, 0xca, 0x92}, + {0xb2, 0xc9, 0x5e, 0xb0, 0x0c, 0x31, 0xad, 0x71, 0x80, 0xac, 0x05, 0xb8, 0xe8, 0x3d, 0x69, 0x6e} + }; + static const uint8_t iv[8] = {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6}; + static uint8_t rpt2[2][16]; + int i, j, err = 0; + static const int key_bits[3] = {128, 80, 40}; + uint8_t temp[8]; + struct AVCAST5 *cs; + cs = av_cast5_alloc(); + if (!cs) + return 1; + for (j = 0; j < 3; j++){ + + av_cast5_init(cs, Key[j], key_bits[j]); + av_cast5_crypt(cs, temp, rpt, 1, 0); + for (i = 0;i < 8; i++){ + if (rct[j][i] != temp[i]){ + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]); + err = 1; + } + } + + av_cast5_crypt(cs, temp, rct[j], 1, 1); + for (i =0; i < 8; i++) { + if (rpt[i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]); + err = 1; + } + } + } + memcpy(rpt2[0], Key[0], 16); + memcpy(rpt2[1], Key[0], 16); + for (i = 0; i < 1000000; i++){ + av_cast5_init(cs, rpt2[1], 128); + av_cast5_crypt(cs, rpt2[0], rpt2[0], 2, 0); + av_cast5_init(cs, rpt2[0], 128); + av_cast5_crypt(cs, rpt2[1], rpt2[1], 2, 0); + } + for (j = 0; j < 2; j++) { + for (i = 0; i < 16; i++) { + if (rct2[j][i] != rpt2[j][i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[j][i], rpt2[j][i]); + err = 1; + } + } + } + for (j = 0; j < 3; j++) { + + av_cast5_init(cs, Key[j], key_bits[j]); + memcpy(temp, iv, 8); + av_cast5_crypt2(cs, rpt2[0], rct2[0], 2, temp, 0); + memcpy(temp, iv, 8); + av_cast5_crypt2(cs, rpt2[0], rpt2[0], 2, temp, 1); + for (i = 0; i < 16; i++) { + if (rct2[0][i] != rpt2[0][i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[0][i], rpt2[0][i]); + err = 1; + } + } + } + av_free(cs); + return err; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/channel_layout.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/channel_layout.c new file mode 100644 index 00000000..5516db09 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/channel_layout.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2021 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/channel_layout.c" + +#define CHANNEL_NAME(x) \ + av_bprint_clear(&bp); \ + av_channel_name_bprint(&bp, x); + +#define CHANNEL_DESCRIPTION(x) \ + av_bprint_clear(&bp); \ + av_channel_description_bprint(&bp, x); + +#define CHANNEL_LAYOUT_FROM_MASK(x) \ + av_channel_layout_uninit(&layout); \ + av_bprint_clear(&bp); \ + if (!av_channel_layout_from_mask(&layout, x) && \ + av_channel_layout_check(&layout)) \ + av_channel_layout_describe_bprint(&layout, &bp); \ + else \ + av_bprintf(&bp, "fail"); + +#define CHANNEL_LAYOUT_FROM_STRING(x) \ + av_channel_layout_uninit(&layout); \ + av_bprint_clear(&bp); \ + if (!av_channel_layout_from_string(&layout, x) && \ + av_channel_layout_check(&layout)) \ + av_channel_layout_describe_bprint(&layout, &bp); \ + else \ + av_bprintf(&bp, "fail"); + +#define CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(x) \ + ret = av_channel_layout_channel_from_index(&layout, x); \ + if (ret < 0) \ + ret = -1 + +#define CHANNEL_LAYOUT_SUBSET(x) \ + mask = av_channel_layout_subset(&layout, x) + +#define CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(x) \ + ret = av_channel_layout_index_from_channel(&layout, x); \ + if (ret < 0) \ + ret = -1 + +#define CHANNEL_LAYOUT_CHANNEL_FROM_STRING(x) \ + ret = av_channel_layout_channel_from_string(&layout, x); \ + if (ret < 0) \ + ret = -1 + +#define CHANNEL_LAYOUT_INDEX_FROM_STRING(x) \ + ret = av_channel_layout_index_from_string(&layout, x); \ + if (ret < 0) \ + ret = -1 + +int main(void) +{ + const AVChannelLayout *playout; + AVChannelLayout layout = { 0 }; + AVBPrint bp; + void *iter = NULL; + uint64_t mask; + int ret; + + av_bprint_init(&bp, 64, AV_BPRINT_SIZE_AUTOMATIC); + + printf("Testing av_channel_layout_standard\n"); + while (playout = av_channel_layout_standard(&iter)) { + av_channel_layout_describe_bprint(playout, &bp); + printf("%-14s ", bp.str); + av_bprint_clear(&bp); + for (int i = 0; i < 63; i++) { + int idx = av_channel_layout_index_from_channel(playout, i); + if (idx >= 0) { + if (idx) + av_bprintf(&bp, "+"); + av_channel_name_bprint(&bp, i); + } + } + printf("%s\n", bp.str); + av_bprint_clear(&bp); + } + + printf("\nTesting av_channel_name\n"); + CHANNEL_NAME(AV_CHAN_FRONT_LEFT); + printf("With AV_CHAN_FRONT_LEFT: %27s\n", bp.str); + CHANNEL_NAME(AV_CHAN_FRONT_RIGHT); + printf("With AV_CHAN_FRONT_RIGHT: %26s\n", bp.str); + CHANNEL_NAME(63); + printf("With 63: %43s\n", bp.str); + CHANNEL_NAME(AV_CHAN_AMBISONIC_BASE); + printf("With AV_CHAN_AMBISONIC_BASE: %23s\n", bp.str); + CHANNEL_NAME(AV_CHAN_AMBISONIC_END); + printf("With AV_CHAN_AMBISONIC_END: %24s\n", bp.str); + + printf("Testing av_channel_description\n"); + CHANNEL_DESCRIPTION(AV_CHAN_FRONT_LEFT); + printf("With AV_CHAN_FRONT_LEFT: %27s\n", bp.str); + CHANNEL_DESCRIPTION(AV_CHAN_FRONT_RIGHT); + printf("With AV_CHAN_FRONT_RIGHT: %26s\n", bp.str); + CHANNEL_DESCRIPTION(63); + printf("With 63: %43s\n", bp.str); + CHANNEL_DESCRIPTION(AV_CHAN_AMBISONIC_BASE); + printf("With AV_CHAN_AMBISONIC_BASE: %23s\n", bp.str); + CHANNEL_DESCRIPTION(AV_CHAN_AMBISONIC_END); + printf("With AV_CHAN_AMBISONIC_END: %24s\n", bp.str); + + printf("\nTesting av_channel_from_string\n"); + printf("With \"FL\": %41d\n", av_channel_from_string("FL")); + printf("With \"FR\": %41d\n", av_channel_from_string("FR")); + printf("With \"USR63\": %38d\n", av_channel_from_string("USR63")); + printf("With \"AMBI0\": %38d\n", av_channel_from_string("AMBI0")); + printf("With \"AMBI1023\": %35d\n", av_channel_from_string("AMBI1023")); + + printf("\n==Native layouts==\n"); + + printf("\nTesting av_channel_layout_from_string\n"); + CHANNEL_LAYOUT_FROM_STRING("0x3f"); + printf("With \"0x3f\": %39s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("63"); + printf("With \"63\": %41s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("6c"); + printf("With \"6c\": %41s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("6C"); + printf("With \"6C\": %41s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("6 channels"); + printf("With \"6 channels\": %33s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("6 channels (FL+FR+FC+LFE+BL+BR)"); + printf("With \"6 channels (FL+FR+FC+LFE+BL+BR)\": %12s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("FL+FR+FC+LFE+BL+BR"); + printf("With \"FL+FR+FC+LFE+BL+BR\": %25s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("5.1"); + printf("With \"5.1\": %40s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("FL+FR+USR63"); + printf("With \"FL+FR+USR63\": %32s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("FL+FR+FC+LFE+SL+SR"); + printf("With \"FL+FR+FC+LFE+SL+SR\": %25s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("5.1(side)"); + printf("With \"5.1(side)\": %34s\n", bp.str); + + printf("\nTesting av_channel_layout_from_mask\n"); + CHANNEL_LAYOUT_FROM_MASK(AV_CH_LAYOUT_5POINT1); + printf("With AV_CH_LAYOUT_5POINT1: %25s\n", bp.str); + + printf("\nTesting av_channel_layout_channel_from_index\n"); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(0); + printf("On 5.1(side) layout with 0: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(1); + printf("On 5.1(side) layout with 1: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(2); + printf("On 5.1(side) layout with 2: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(3); + printf("On 5.1(side) layout with 3: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(4); + printf("On 5.1(side) layout with 4: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(5); + printf("On 5.1(side) layout with 5: %24d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(6); + printf("On 5.1(side) layout with 6: %24d\n", ret); + + printf("\nTesting av_channel_layout_index_from_channel\n"); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_LEFT); + printf("On 5.1(side) layout with AV_CHAN_FRONT_LEFT: %7d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_RIGHT); + printf("On 5.1(side) layout with AV_CHAN_FRONT_RIGHT: %6d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_CENTER); + printf("On 5.1(side) layout with AV_CHAN_FRONT_CENTER: %5d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_LOW_FREQUENCY); + printf("On 5.1(side) layout with AV_CHAN_LOW_FREQUENCY: %4d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_SIDE_LEFT); + printf("On 5.1(side) layout with AV_CHAN_SIDE_LEFT: %8d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_SIDE_RIGHT); + printf("On 5.1(side) layout with AV_CHAN_SIDE_RIGHT: %7d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_BACK_CENTER); + printf("On 5.1(side) layout with AV_CHAN_BACK_CENTER: %6d\n", ret); + + printf("\nTesting av_channel_layout_channel_from_string\n"); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FL"); + printf("On 5.1(side) layout with \"FL\": %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FR"); + printf("On 5.1(side) layout with \"FR\": %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FC"); + printf("On 5.1(side) layout with \"FC\": %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("LFE"); + printf("On 5.1(side) layout with \"LFE\": %20d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("SL"); + printf("On 5.1(side) layout with \"SL\": %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("SR"); + printf("On 5.1(side) layout with \"SR\": %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("BC"); + printf("On 5.1(side) layout with \"BC\": %21d\n", ret); + + printf("\nTesting av_channel_layout_index_from_string\n"); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FL"); + printf("On 5.1(side) layout with \"FL\": %21d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FR"); + printf("On 5.1(side) layout with \"FR\": %21d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FC"); + printf("On 5.1(side) layout with \"FC\": %21d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("LFE"); + printf("On 5.1(side) layout with \"LFE\": %20d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("SL"); + printf("On 5.1(side) layout with \"SL\": %21d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("SR"); + printf("On 5.1(side) layout with \"SR\": %21d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("BC"); + printf("On 5.1(side) layout with \"BC\": %21d\n", ret); + + printf("\nTesting av_channel_layout_subset\n"); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_STEREO); + printf("On 5.1(side) layout with AV_CH_LAYOUT_STEREO: 0x%"PRIx64"\n", mask); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_2POINT1); + printf("On 5.1(side) layout with AV_CH_LAYOUT_2POINT1: 0x%"PRIx64"\n", mask); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_4POINT1); + printf("On 5.1(side) layout with AV_CH_LAYOUT_4POINT1: 0x%"PRIx64"\n", mask); + + printf("\n==Custom layouts==\n"); + + printf("\nTesting av_channel_layout_from_string\n"); + CHANNEL_LAYOUT_FROM_STRING("FL+FR+FC+BL+BR+LFE"); + printf("With \"FL+FR+FC+BL+BR+LFE\": %34s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("2 channels (FR+FL)"); + printf("With \"2 channels (FR+FL)\": %34s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("ambisonic 1+FR+FL"); + printf("With \"ambisonic 1+FR+FL\": %35s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("ambisonic 2+FC@Foo"); + printf("With \"ambisonic 2+FC@Foo\": %34s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("FL@Foo+FR@Bar"); + printf("With \"FL@Foo+FR@Bar\": %39s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("FR+FL@Foo+USR63@Foo"); + printf("With \"FR+FL@Foo+USR63@Foo\": %33s\n", bp.str); + + printf("\nTesting av_channel_layout_index_from_string\n"); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FR"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FR\": %18d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FL"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FL\": %18d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("USR63"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"USR63\": %15d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"Foo\": %17d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"@Foo\": %16d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FR@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FR@Foo\": %14d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("FL@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FL@Foo\": %14d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("USR63@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"USR63@Foo\": %11d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_STRING("BC"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"BC\": %18d\n", ret); + + printf("\nTesting av_channel_layout_channel_from_string\n"); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FR"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FR\": %18d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FL"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FL\": %18d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("USR63"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"USR63\": %15d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"Foo\": %17d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"@Foo\": %16d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FR@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FR@Foo\": %14d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("FL@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"FL@Foo\": %14d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("USR63@Foo"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"USR63@Foo\": %11d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_STRING("BC"); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with \"BC\": %18d\n", ret); + + printf("\nTesting av_channel_layout_index_from_channel\n"); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_RIGHT); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with AV_CHAN_FRONT_RIGHT: %3d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_LEFT); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with AV_CHAN_FRONT_LEFT: %4d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(63); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with 63: %20d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_BACK_CENTER); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with AV_CHAN_BACK_CENTER: %3d\n", ret); + + printf("\nTesting av_channel_layout_channel_from_index\n"); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(0); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with 0: %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(1); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with 1: %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(2); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with 2: %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(3); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with 3: %21d\n", ret); + + printf("\nTesting av_channel_layout_subset\n"); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_STEREO); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with AV_CH_LAYOUT_STEREO: 0x%"PRIx64"\n", mask); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_QUAD); + printf("On \"FR+FL@Foo+USR63@Foo\" layout with AV_CH_LAYOUT_QUAD: 0x%"PRIx64"\n", mask); + + printf("\n==Ambisonic layouts==\n"); + + printf("\nTesting av_channel_layout_from_string\n"); + CHANNEL_LAYOUT_FROM_STRING("ambisonic 1"); + printf("With \"ambisonic 1\": %41s\n", bp.str); + CHANNEL_LAYOUT_FROM_STRING("ambisonic 2+stereo"); + printf("With \"ambisonic 2+stereo\": %34s\n", bp.str); + + printf("\nTesting av_channel_layout_index_from_channel\n"); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_AMBISONIC_BASE); + printf("On \"ambisonic 2+stereo\" layout with AV_CHAN_AMBISONIC_BASE: %d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_LEFT); + printf("On \"ambisonic 2+stereo\" layout with AV_CHAN_FRONT_LEFT: %5d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_FRONT_RIGHT); + printf("On \"ambisonic 2+stereo\" layout with AV_CHAN_FRONT_RIGHT: %4d\n", ret); + CHANNEL_LAYOUT_INDEX_FROM_CHANNEL(AV_CHAN_BACK_CENTER); + printf("On \"ambisonic 2+stereo\" layout with AV_CHAN_BACK_CENTER: %4d\n", ret); + + printf("\nTesting av_channel_layout_channel_from_index\n"); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(0); + printf("On \"ambisonic 2+stereo\" layout with 0: %22d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(9); + printf("On \"ambisonic 2+stereo\" layout with 9: %22d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(10); + printf("On \"ambisonic 2+stereo\" layout with 10: %21d\n", ret); + CHANNEL_LAYOUT_CHANNEL_FROM_INDEX(11); + printf("On \"ambisonic 2+stereo\" layout with 11: %21d\n", ret); + + printf("\nTesting av_channel_layout_subset\n"); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_STEREO); + printf("On \"ambisonic 2+stereo\" layout with AV_CH_LAYOUT_STEREO: 0x%"PRIx64"\n", mask); + CHANNEL_LAYOUT_SUBSET(AV_CH_LAYOUT_QUAD); + printf("On \"ambisonic 2+stereo\" layout with AV_CH_LAYOUT_QUAD: 0x%"PRIx64"\n", mask); + + av_channel_layout_uninit(&layout); + av_bprint_finalize(&bp, NULL); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/color_utils.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/color_utils.c new file mode 100644 index 00000000..4bdc5503 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/color_utils.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Kevin Wheatley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "libavutil/color_utils.c" +#include "libavutil/macros.h" + +int main(int argc, char *argv[]) +{ + int i, j; + static const double test_data[] = { + -0.1, -0.018053968510807, -0.01, -0.00449, 0.0, 0.00316227760, 0.005, + 0.009, 0.015, 0.1, 1.0, 52.37, 125.098765, 1999.11123, 6945.443, + 15123.4567, 19845.88923, 98678.4231, 99999.899998 + }; + + for(i = 0; i < AVCOL_TRC_NB; i++) { + avpriv_trc_function func = avpriv_get_trc_function_from_trc(i); + for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) { + if(func != NULL) { + double result = func(test_data[j]); + printf("AVColorTransferCharacteristic=%d calling func(%f) expected=%f\n", + i, test_data[j], result); + } + } + } + +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu.c new file mode 100644 index 00000000..dadadb31 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu.c @@ -0,0 +1,156 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" + +#include "libavutil/cpu.h" +#include "libavutil/avstring.h" + +#if HAVE_UNISTD_H +#include +#endif +#if !HAVE_GETOPT +#include "compat/getopt.c" +#endif + +static const struct { + int flag; + const char *name; +} cpu_flag_tab[] = { +#if ARCH_AARCH64 + { AV_CPU_FLAG_ARMV8, "armv8" }, + { AV_CPU_FLAG_NEON, "neon" }, + { AV_CPU_FLAG_VFP, "vfp" }, +#elif ARCH_ARM + { AV_CPU_FLAG_ARMV5TE, "armv5te" }, + { AV_CPU_FLAG_ARMV6, "armv6" }, + { AV_CPU_FLAG_ARMV6T2, "armv6t2" }, + { AV_CPU_FLAG_VFP, "vfp" }, + { AV_CPU_FLAG_VFP_VM, "vfp_vm" }, + { AV_CPU_FLAG_VFPV3, "vfpv3" }, + { AV_CPU_FLAG_NEON, "neon" }, + { AV_CPU_FLAG_SETEND, "setend" }, +#elif ARCH_PPC + { AV_CPU_FLAG_ALTIVEC, "altivec" }, +#elif ARCH_MIPS + { AV_CPU_FLAG_MMI, "mmi" }, + { AV_CPU_FLAG_MSA, "msa" }, +#elif ARCH_X86 + { AV_CPU_FLAG_MMX, "mmx" }, + { AV_CPU_FLAG_MMXEXT, "mmxext" }, + { AV_CPU_FLAG_SSE, "sse" }, + { AV_CPU_FLAG_SSE2, "sse2" }, + { AV_CPU_FLAG_SSE2SLOW, "sse2slow" }, + { AV_CPU_FLAG_SSE3, "sse3" }, + { AV_CPU_FLAG_SSE3SLOW, "sse3slow" }, + { AV_CPU_FLAG_SSSE3, "ssse3" }, + { AV_CPU_FLAG_ATOM, "atom" }, + { AV_CPU_FLAG_SSE4, "sse4.1" }, + { AV_CPU_FLAG_SSE42, "sse4.2" }, + { AV_CPU_FLAG_AVX, "avx" }, + { AV_CPU_FLAG_AVXSLOW, "avxslow" }, + { AV_CPU_FLAG_XOP, "xop" }, + { AV_CPU_FLAG_FMA3, "fma3" }, + { AV_CPU_FLAG_FMA4, "fma4" }, + { AV_CPU_FLAG_3DNOW, "3dnow" }, + { AV_CPU_FLAG_3DNOWEXT, "3dnowext" }, + { AV_CPU_FLAG_CMOV, "cmov" }, + { AV_CPU_FLAG_AVX2, "avx2" }, + { AV_CPU_FLAG_BMI1, "bmi1" }, + { AV_CPU_FLAG_BMI2, "bmi2" }, + { AV_CPU_FLAG_AESNI, "aesni" }, + { AV_CPU_FLAG_AVX512, "avx512" }, + { AV_CPU_FLAG_AVX512ICL, "avx512icl" }, + { AV_CPU_FLAG_SLOW_GATHER, "slowgather" }, +#elif ARCH_LOONGARCH + { AV_CPU_FLAG_LSX, "lsx" }, + { AV_CPU_FLAG_LASX, "lasx" }, +#endif + { 0 } +}; + +static void print_cpu_flags(int cpu_flags, const char *type) +{ + int i; + + printf("cpu_flags(%s) = 0x%08X\n", type, cpu_flags); + printf("cpu_flags_str(%s) =", type); + for (i = 0; cpu_flag_tab[i].flag; i++) + if (cpu_flags & cpu_flag_tab[i].flag) + printf(" %s", cpu_flag_tab[i].name); + printf("\n"); +} + + +int main(int argc, char **argv) +{ + int cpu_flags_raw = av_get_cpu_flags(); + int cpu_flags_eff; + int cpu_count = av_cpu_count(); + char threads[5] = "auto"; + int i; + + for(i = 0; cpu_flag_tab[i].flag; i++) { + unsigned tmp = 0; + if (av_parse_cpu_caps(&tmp, cpu_flag_tab[i].name) < 0) { + fprintf(stderr, "Table missing %s\n", cpu_flag_tab[i].name); + return 4; + } + } + + if (cpu_flags_raw < 0) + return 1; + + for (;;) { + int c = getopt(argc, argv, "c:t:"); + if (c == -1) + break; + switch (c) { + case 'c': + { + unsigned flags = av_get_cpu_flags(); + if (av_parse_cpu_caps(&flags, optarg) < 0) + return 2; + + av_force_cpu_flags(flags); + break; + } + case 't': + { + int len = av_strlcpy(threads, optarg, sizeof(threads)); + if (len >= sizeof(threads)) { + fprintf(stderr, "Invalid thread count '%s'\n", optarg); + return 2; + } + } + } + } + + cpu_flags_eff = av_get_cpu_flags(); + + if (cpu_flags_eff < 0) + return 3; + + print_cpu_flags(cpu_flags_raw, "raw"); + print_cpu_flags(cpu_flags_eff, "effective"); + printf("threads = %s (cpu_count = %d)\n", threads, cpu_count); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu_init.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu_init.c new file mode 100644 index 00000000..a379e47b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/cpu_init.c @@ -0,0 +1,65 @@ +/* + * 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 + */ + +/* + * This test program tests whether the one-time initialization in + * av_get_cpu_flags() has data races. + */ + +#include +#include + +#include "libavutil/cpu.h" +#include "libavutil/thread.h" + +static void *thread_main(void *arg) +{ + int *flags = arg; + + *flags = av_get_cpu_flags(); + return NULL; +} + +int main(void) +{ + int cpu_flags1; + int cpu_flags2; + int ret; + pthread_t thread1; + pthread_t thread2; + + if ((ret = pthread_create(&thread1, NULL, thread_main, &cpu_flags1))) { + fprintf(stderr, "pthread_create failed: %s.\n", strerror(ret)); + return 1; + } + if ((ret = pthread_create(&thread2, NULL, thread_main, &cpu_flags2))) { + fprintf(stderr, "pthread_create failed: %s.\n", strerror(ret)); + return 1; + } + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + if (cpu_flags1 < 0) + return 2; + if (cpu_flags2 < 0) + return 2; + if (cpu_flags1 != cpu_flags2) + return 3; + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/crc.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/crc.c new file mode 100644 index 00000000..413aada8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/crc.c @@ -0,0 +1,47 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/crc.h" + +int main(void) +{ + uint8_t buf[1999]; + int i; + static const unsigned p[7][3] = { + { AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04 }, + { AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0 }, + { AV_CRC_24_IEEE , 0x864CFB , 0xB704CE }, + { AV_CRC_16_ANSI_LE, 0xA001 , 0xBFD8 }, + { AV_CRC_16_ANSI , 0x8005 , 0x1FBB }, + { AV_CRC_8_ATM , 0x07 , 0xE3 }, + { AV_CRC_8_EBU , 0x1D , 0xD6 }, + }; + const AVCRC *ctx; + + for (i = 0; i < sizeof(buf); i++) + buf[i] = i + i * i; + + for (i = 0; i < 7; i++) { + ctx = av_crc_get_table(p[i][0]); + printf("crc %08X = %X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf))); + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/des.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/des.c new file mode 100644 index 00000000..8fa88df6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/des.c @@ -0,0 +1,134 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/mem_internal.h" +#include "libavutil/timer.h" + +#include "libavutil/des.c" + +#include +#include +#include +#include + +#include "libavutil/time.h" + +static uint64_t rand64(void) +{ + uint64_t r = rand(); + r = (r << 32) | rand(); + return r; +} + +static const uint8_t test_key[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; +static const DECLARE_ALIGNED(8, uint8_t, plain)[] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; +static const DECLARE_ALIGNED(8, uint8_t, crypt_ref)[] = { 0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18 }; +static DECLARE_ALIGNED(8, uint8_t, tmp)[8]; +static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8]; +static const uint8_t cbc_key[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, + 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 +}; + +static int run_test(int cbc, int decrypt) +{ + AVDES d; + int delay = cbc && !decrypt ? 2 : 1; + uint64_t res; + AV_WB64(large_buffer[0], 0x4e6f772069732074ULL); + AV_WB64(large_buffer[1], 0x1234567890abcdefULL); + AV_WB64(tmp, 0x1234567890abcdefULL); + av_des_init(&d, cbc_key, 192, decrypt); + av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt); + res = AV_RB64(large_buffer[9999 + delay]); + if (cbc) { + if (decrypt) + return res == 0xc5cecf63ecec514cULL; + else + return res == 0xcb191f85d1ed8439ULL; + } else { + if (decrypt) + return res == 0x8325397644091a0aULL; + else + return res == 0xdd17e8b8b437d232ULL; + } +} + +union word_byte { + uint64_t word; + uint8_t byte[8]; +}; + +int main(void) +{ + AVDES d; + int i; + union word_byte key[3], data, ct; + uint64_t roundkeys[16]; + srand(av_gettime()); + key[0].word = AV_RB64(test_key); + data.word = AV_RB64(plain); + gen_roundkeys(roundkeys, key[0].word); + if (des_encdec(data.word, roundkeys, 0) != AV_RB64(crypt_ref)) { + printf("Test 1 failed\n"); + return 1; + } + av_des_init(&d, test_key, 64, 0); + av_des_crypt(&d, tmp, plain, 1, NULL, 0); + if (memcmp(tmp, crypt_ref, sizeof(crypt_ref))) { + printf("Public API decryption failed\n"); + return 1; + } + if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) { + printf("Partial Monte-Carlo test failed\n"); + return 1; + } + for (i = 0; i < 1000; i++) { + key[0].word = rand64(); + key[1].word = rand64(); + key[2].word = rand64(); + data.word = rand64(); + av_des_init(&d, key[0].byte, 192, 0); + av_des_crypt(&d, ct.byte, data.byte, 1, NULL, 0); + av_des_init(&d, key[0].byte, 192, 1); + av_des_crypt(&d, ct.byte, ct.byte, 1, NULL, 1); + if (ct.word != data.word) { + printf("Test 2 failed\n"); + return 1; + } + } +#ifdef GENTABLES + printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n"); + for (i = 0; i < 8; i++) { + int j; + printf(" {"); + for (j = 0; j < 64; j++) { + uint32_t v = S_boxes[i][j >> 1]; + v = j & 1 ? v >> 4 : v & 0xf; + v <<= 28 - 4 * i; + v = shuffle(v, P_shuffle, sizeof(P_shuffle)); + printf((j & 7) == 0 ? "\n " : " "); + printf("0x%08X,", v); + } + printf("\n },\n"); + } + printf("};\n"); +#endif + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/dict.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/dict.c new file mode 100644 index 00000000..bececefb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/dict.c @@ -0,0 +1,162 @@ +/* + * copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/dict.c" + +static const AVDictionaryEntry *dict_iterate(const AVDictionary *m, + const AVDictionaryEntry *prev) +{ + const AVDictionaryEntry *dict_get = av_dict_get(m, "", prev, AV_DICT_IGNORE_SUFFIX); + const AVDictionaryEntry *dict_iterate = av_dict_iterate(m, prev); + + if (dict_get != dict_iterate) { +#define GET(entry, mem) ((entry) ? (entry)->mem : "N/A") + printf("Iterating with av_dict_iterate() yields a different result " + "than iterating with av_dict_get() and AV_DICT_IGNORE_SUFFIX " + "(prev: %p, key %s; av_dict_iterate() %p, key %s, value %s; " + "av_dict_get() %p, key %s, value %s)\n", + prev, GET(prev, key), + dict_iterate, GET(dict_iterate, key), GET(dict_iterate, value), + dict_get, GET(dict_get, key), GET(dict_get, value)); +#undef GET + } + return dict_iterate; +} + +static void print_dict(const AVDictionary *m) +{ + const AVDictionaryEntry *t = NULL; + while ((t = dict_iterate(m, t))) + printf("%s %s ", t->key, t->value); + printf("\n"); +} + +static void test_separators(const AVDictionary *m, const char pair, const char val) +{ + AVDictionary *dict = NULL; + char pairs[] = {pair , '\0'}; + char vals[] = {val, '\0'}; + + char *buffer = NULL; + int ret; + + av_dict_copy(&dict, m, 0); + print_dict(dict); + av_dict_get_string(dict, &buffer, val, pair); + printf("%s\n", buffer); + av_dict_free(&dict); + ret = av_dict_parse_string(&dict, buffer, vals, pairs, 0); + printf("ret %d\n", ret); + av_freep(&buffer); + print_dict(dict); + av_dict_free(&dict); +} + +int main(void) +{ + AVDictionary *dict = NULL; + const AVDictionaryEntry *e; + char *buffer = NULL; + + printf("Testing av_dict_get_string() and av_dict_parse_string()\n"); + av_dict_get_string(dict, &buffer, '=', ','); + printf("%s\n", buffer); + av_freep(&buffer); + av_dict_set(&dict, "aaa", "aaa", 0); + av_dict_set(&dict, "b,b", "bbb", 0); + av_dict_set(&dict, "c=c", "ccc", 0); + av_dict_set(&dict, "ddd", "d,d", 0); + av_dict_set(&dict, "eee", "e=e", 0); + av_dict_set(&dict, "f,f", "f=f", 0); + av_dict_set(&dict, "g=g", "g,g", 0); + test_separators(dict, ',', '='); + av_dict_free(&dict); + av_dict_set(&dict, "aaa", "aaa", 0); + av_dict_set(&dict, "bbb", "bbb", 0); + av_dict_set(&dict, "ccc", "ccc", 0); + av_dict_set(&dict, "\\,=\'\"", "\\,=\'\"", 0); + test_separators(dict, '"', '='); + test_separators(dict, '\'', '='); + test_separators(dict, ',', '"'); + test_separators(dict, ',', '\''); + test_separators(dict, '\'', '"'); + test_separators(dict, '"', '\''); + av_dict_free(&dict); + + printf("\nTesting av_dict_set()\n"); + av_dict_set(&dict, "a", "a", 0); + av_dict_set(&dict, "b", av_strdup("b"), AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&dict, av_strdup("c"), "c", AV_DICT_DONT_STRDUP_KEY); + av_dict_set(&dict, av_strdup("d"), av_strdup("d"), AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&dict, "e", "e", AV_DICT_DONT_OVERWRITE); + av_dict_set(&dict, "e", "f", AV_DICT_DONT_OVERWRITE); + av_dict_set(&dict, "f", "f", 0); + av_dict_set(&dict, "f", NULL, 0); + av_dict_set(&dict, "ff", "f", 0); + av_dict_set(&dict, "ff", "f", AV_DICT_APPEND); + if (av_dict_get(dict, NULL, NULL, 0)) + printf("av_dict_get() does not correctly handle NULL key.\n"); + e = NULL; + while ((e = dict_iterate(dict, e))) + printf("%s %s\n", e->key, e->value); + av_dict_free(&dict); + + if (av_dict_set(&dict, NULL, "a", 0) >= 0 || + av_dict_set(&dict, NULL, "b", 0) >= 0 || + av_dict_set(&dict, NULL, NULL, AV_DICT_DONT_STRDUP_KEY) >= 0 || + av_dict_set(&dict, NULL, av_strdup("b"), AV_DICT_DONT_STRDUP_VAL) >= 0 || + av_dict_count(dict)) + printf("av_dict_set does not correctly handle NULL key\n"); + + e = NULL; + while ((e = dict_iterate(dict, e))) + printf("'%s' '%s'\n", e->key, e->value); + av_dict_free(&dict); + + + //valgrind sensible test + printf("\nTesting av_dict_set_int()\n"); + av_dict_set_int(&dict, "1", 1, AV_DICT_DONT_STRDUP_VAL); + av_dict_set_int(&dict, av_strdup("2"), 2, AV_DICT_DONT_STRDUP_KEY); + av_dict_set_int(&dict, av_strdup("3"), 3, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + av_dict_set_int(&dict, "4", 4, 0); + av_dict_set_int(&dict, "5", 5, AV_DICT_DONT_OVERWRITE); + av_dict_set_int(&dict, "5", 6, AV_DICT_DONT_OVERWRITE); + av_dict_set_int(&dict, "12", 1, 0); + av_dict_set_int(&dict, "12", 2, AV_DICT_APPEND); + e = NULL; + while ((e = dict_iterate(dict, e))) + printf("%s %s\n", e->key, e->value); + av_dict_free(&dict); + + //valgrind sensible test + printf("\nTesting av_dict_set() with existing AVDictionaryEntry.key as key\n"); + av_dict_set(&dict, "key", "old", 0); + e = av_dict_get(dict, "key", NULL, 0); + av_dict_set(&dict, e->key, "new val OK", 0); + e = av_dict_get(dict, "key", NULL, 0); + printf("%s\n", e->value); + av_dict_set(&dict, e->key, e->value, 0); + e = av_dict_get(dict, "key", NULL, 0); + printf("%s\n", e->value); + av_dict_free(&dict); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/display.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/display.c new file mode 100644 index 00000000..19b07fc1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/display.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "libavutil/display.c" + +static void print_matrix(int32_t matrix[9]) +{ + int i, j; + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3 - 1; ++j) + printf("%d ", matrix[i*3 + j]); + + printf("%d\n", matrix[i*3 + j]); + } +} + +int main(void) +{ + int32_t matrix[9]; + + // Set the matrix to 90 degrees + av_display_rotation_set(matrix, 90); + print_matrix(matrix); + printf("degrees: %f\n", av_display_rotation_get(matrix)); + + // Set the matrix to -45 degrees + av_display_rotation_set(matrix, -45); + print_matrix(matrix); + printf("degrees: %f\n", av_display_rotation_get(matrix)); + + // flip horizontal + av_display_matrix_flip(matrix, 1, 0); + print_matrix(matrix); + printf("degrees: %f\n", av_display_rotation_get(matrix)); + + // flip vertical + av_display_matrix_flip(matrix, 0, 1); + print_matrix(matrix); + printf("degrees: %f\n", av_display_rotation_get(matrix)); + + return 0; + +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/encryption_info.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/encryption_info.c new file mode 100644 index 00000000..55c668c6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/encryption_info.c @@ -0,0 +1,177 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/encryption_info.h" + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/mem.h" + +static const AVSubsampleEncryptionInfo test_subsamples[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}}; +static const size_t test_subsample_count = sizeof(test_subsamples) / sizeof(test_subsamples[0]); +static const uint8_t test_iv[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; +static const uint8_t test_key_id[] = {0x21, 0x22, 0x23, 0x24}; +static const uint8_t test_key_id_2[] = {0x31, 0x32, 0x33, 0x34}; +static const uint8_t test_system_id[] = {0x41, 0x42, 0x43}; +static const uint8_t test_data[] = {0x51, 0x52}; + +static int compare_encryption_info(const AVEncryptionInfo *a, const AVEncryptionInfo *b) { + if (!a || !b || a->scheme != b->scheme || a->crypt_byte_block != b->crypt_byte_block || + a->skip_byte_block != b->skip_byte_block || a->key_id_size != b->key_id_size || + a->iv_size != b->iv_size || a->subsample_count != b->subsample_count) + return 1; + + if (memcmp(a->key_id, b->key_id, a->key_id_size) != 0 || + memcmp(a->iv, b->iv, a->iv_size) != 0 || + memcmp(a->subsamples, b->subsamples, a->subsample_count * sizeof(a->subsamples[0]))) + return 1; + + return 0; +} + +static int compare_encryption_init_info(const AVEncryptionInitInfo *a, const AVEncryptionInitInfo *b) { + if (!a || !b || a->system_id_size != b->system_id_size || + a->num_key_ids != b->num_key_ids || a->key_id_size != b->key_id_size || + a->data_size != b->data_size) + return 1; + + if (memcmp(a->system_id, b->system_id, a->system_id_size) != 0 || + memcmp(a->data, b->data, a->data_size) != 0) + return 1; + + for (uint32_t i = 0; i < a->num_key_ids; i++) { + if (memcmp(a->key_ids[i], b->key_ids[i], a->key_id_size) != 0) + return 1; + } + + if (a->next || b->next) { + if (!a->next || !b->next) + return 1; + if (compare_encryption_init_info(a->next, b->next) != 0) + return 1; + } + + return 0; +} + +static void run_encryption_info_test(void) +{ + AVEncryptionInfo *info, *copy; + uint8_t *side_data; + size_t side_data_size; + + info = av_encryption_info_alloc(test_subsample_count, sizeof(test_key_id), sizeof(test_iv)); + av_assert0(info); + av_assert0(info->key_id); + av_assert0(info->key_id_size == sizeof(test_key_id)); + av_assert0(info->iv); + av_assert0(info->iv_size == sizeof(test_iv)); + av_assert0(info->subsamples); + av_assert0(info->subsample_count == test_subsample_count); + + info->scheme = 1234; + info->crypt_byte_block = 333; + info->skip_byte_block = 444; + memcpy(info->key_id, test_key_id, sizeof(test_key_id)); + memcpy(info->iv, test_iv, sizeof(test_iv)); + memcpy(info->subsamples, test_subsamples, sizeof(test_subsamples)); + + copy = av_encryption_info_clone(info); + av_assert0(copy); + av_assert0(copy != info); + av_assert0(compare_encryption_info(info, copy) == 0); + av_encryption_info_free(copy); + + side_data = av_encryption_info_add_side_data(info, &side_data_size); + av_assert0(side_data); + av_assert0(side_data_size > 0); + + copy = av_encryption_info_get_side_data(side_data, side_data_size); + av_assert0(copy); + av_assert0(copy != info); + av_assert0(compare_encryption_info(info, copy) == 0); + av_encryption_info_free(copy); + av_free(side_data); + + av_encryption_info_free(info); +} + +static AVEncryptionInitInfo *create_init_info(void) +{ + AVEncryptionInitInfo *info; + + info = av_encryption_init_info_alloc(sizeof(test_system_id), 2, sizeof(test_key_id), sizeof(test_data)); + av_assert0(info); + av_assert0(info->system_id); + av_assert0(info->system_id_size == sizeof(test_system_id)); + av_assert0(info->key_ids); + av_assert0(info->num_key_ids == 2); + av_assert0(info->key_id_size == sizeof(test_key_id)); + av_assert0(info->key_ids[0]); + av_assert0(info->key_ids[1]); + av_assert0(info->data); + av_assert0(info->data_size == sizeof(test_data)); + av_assert0(!info->next); + + memcpy(info->system_id, test_system_id, sizeof(test_system_id)); + memcpy(info->key_ids[0], test_key_id, sizeof(test_key_id)); + memcpy(info->key_ids[1], test_key_id_2, sizeof(test_key_id_2)); + memcpy(info->data, test_data, sizeof(test_data)); + + return info; +} + +static void run_encryption_init_info_test(void) +{ + AVEncryptionInitInfo *info, *copy; + uint8_t *side_data; + size_t side_data_size; + + info = create_init_info(); + + side_data = av_encryption_init_info_add_side_data(info, &side_data_size); + av_assert0(side_data); + av_assert0(side_data_size > 0); + copy = av_encryption_init_info_get_side_data(side_data, side_data_size); + av_assert0(copy); + av_assert0(compare_encryption_init_info(info, copy) == 0); + av_encryption_init_info_free(copy); + av_free(side_data); + + // Make the first init info different from the second to test the correct order. + memset(info->system_id, 0, info->system_id_size); + info->next = create_init_info(); + side_data = av_encryption_init_info_add_side_data(info, &side_data_size); + av_assert0(side_data); + copy = av_encryption_init_info_get_side_data(side_data, side_data_size); + av_assert0(copy); + av_assert0(compare_encryption_init_info(info, copy) == 0); + av_encryption_init_info_free(copy); + av_free(side_data); + + av_encryption_init_info_free(info); +} + +int main(int argc, char **argv) +{ + run_encryption_info_test(); + run_encryption_init_info_test(); + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/error.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/error.c new file mode 100644 index 00000000..16efc8ac --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/error.c @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/error.c" + +#undef printf + +int main(void) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) { + const struct error_entry *entry = &error_entries[i]; + printf("%d: %s [%s]\n", entry->num, av_err2str(entry->num), entry->tag); + } + + for (i = 0; i < 256; i++) { + printf("%d: %s\n", -i, av_err2str(-i)); + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/eval.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/eval.c new file mode 100644 index 00000000..b64c6d63 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/eval.c @@ -0,0 +1,184 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/timer.h" + +#include +#include +#include + +#include "libavutil/libm.h" +#include "libavutil/eval.h" + +static const double const_values[] = { + M_PI, + M_E, + 0 +}; + +static const char *const const_names[] = { + "PI", + "E", + 0 +}; + +int main(int argc, char **argv) +{ + int i; + double d; + const char *const *expr; + static const char *const exprs[] = { + "", + "1;2", + "-20", + "-PI", + "+PI", + "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", + "80G/80Gi", + "1k", + "1Gi", + "1gi", + "1GiFoo", + "1k+1k", + "1Gi*3foo", + "foo", + "foo(", + "foo()", + "foo)", + "sin", + "sin(", + "sin()", + "sin)", + "sin 10", + "sin(1,2,3)", + "sin(1 )", + "1", + "1foo", + "bar + PI + E + 100f*2 + foo", + "13k + 12f - foo(1, 2)", + "1gi", + "1Gi", + "st(0, 123)", + "st(1, 123); ld(1)", + "lte(0, 1)", + "lte(1, 1)", + "lte(1, 0)", + "lt(0, 1)", + "lt(1, 1)", + "gt(1, 0)", + "gt(2, 7)", + "gte(122, 122)", + /* compute 1+2+...+N */ + "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)", + /* compute Fib(N) */ + "st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)", + "while(0, 10)", + "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))", + "isnan(1)", + "isnan(NAN)", + "isnan(INF)", + "isinf(1)", + "isinf(NAN)", + "isinf(INF)", + "floor(NAN)", + "floor(123.123)", + "floor(-123.123)", + "trunc(123.123)", + "trunc(-123.123)", + "ceil(123.123)", + "ceil(-123.123)", + "sqrt(1764)", + "isnan(sqrt(-1))", + "not(1)", + "not(NAN)", + "not(0)", + "6.0206dB", + "-3.0103dB", + "pow(0,1.23)", + "pow(PI,1.23)", + "PI^1.23", + "pow(-1,1.23)", + "if(1, 2)", + "if(1, 1, 2)", + "if(0, 1, 2)", + "ifnot(0, 23)", + "ifnot(1, NaN) + if(0, 1)", + "ifnot(1, 1, 2)", + "ifnot(0, 1, 2)", + "taylor(1, 1)", + "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)", + "root(sin(ld(0))-1, 2)", + "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)", + "7000000B*random(0)", + "squish(2)", + "gauss(0.1)", + "hypot(4,3)", + "gcd(30,55)*print(min(9,1))", + "bitor(42, 12)", + "bitand(42, 12)", + "bitand(NAN, 1)", + "between(10, -3, 10)", + "between(-4, -2, -1)", + "between(1,2)", + "clip(0, 2, 1)", + "clip(0/0, 1, 2)", + "clip(0, 0/0, 1)", + NULL + }; + int ret; + + for (expr = exprs; *expr; expr++) { + printf("Evaluating '%s'\n", *expr); + ret = av_expr_parse_and_eval(&d, *expr, + const_names, const_values, + NULL, NULL, NULL, NULL, NULL, 0, NULL); + if (isnan(d)) + printf("'%s' -> nan\n\n", *expr); + else + printf("'%s' -> %f\n\n", *expr, d); + if (ret < 0) + printf("av_expr_parse_and_eval failed\n"); + } + + ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", + const_names, const_values, + NULL, NULL, NULL, NULL, NULL, 0, NULL); + printf("%f == 12.7\n", d); + if (ret < 0) + printf("av_expr_parse_and_eval failed\n"); + ret = av_expr_parse_and_eval(&d, "80G/80Gi", + const_names, const_values, + NULL, NULL, NULL, NULL, NULL, 0, NULL); + printf("%f == 0.931322575\n", d); + if (ret < 0) + printf("av_expr_parse_and_eval failed\n"); + + if (argc > 1 && !strcmp(argv[1], "-t")) { + for (i = 0; i < 1050; i++) { + START_TIMER; + ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", + const_names, const_values, + NULL, NULL, NULL, NULL, NULL, 0, NULL); + if (ret < 0) + printf("av_expr_parse_and_eval failed\n"); + STOP_TIMER("av_expr_parse_and_eval"); + } + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/fifo.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/fifo.c new file mode 100644 index 00000000..8cbc44c4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/fifo.c @@ -0,0 +1,197 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "libavutil/common.h" +#include "libavutil/fifo.h" +#include "libavutil/lfg.h" +#include "libavutil/random_seed.h" + +typedef struct CBState { + unsigned int read_idx; + unsigned int write_idx; + unsigned int to_process; + unsigned int offset; +} CBState; + +static int read_cb(void *opaque, void *buf, size_t *nb_elems) +{ + CBState *s = opaque; + unsigned *b = buf; + + *nb_elems = FFMIN(*nb_elems, s->to_process); + + for (unsigned i = 0; i < *nb_elems; i++) + if (b[i] != s->read_idx + s->offset + i) { + printf("Mismatch at idx %u offset %u i %u\n", + s->read_idx, s->offset, i); + return AVERROR_BUG; + } + + s->offset += *nb_elems; + s->to_process -= *nb_elems; + + return 0; +} + +static int write_cb(void *opaque, void *buf, size_t *nb_elems) +{ + CBState *s = opaque; + unsigned *b = buf; + + *nb_elems = FFMIN(*nb_elems, s->to_process); + + for (unsigned i = 0; i < *nb_elems; i++) + b[i] = s->write_idx + i; + + s->write_idx += *nb_elems; + s->to_process -= *nb_elems; + + return 0; +} + +int main(void) +{ + /* create a FIFO buffer */ + AVFifo *fifo = av_fifo_alloc2(13, sizeof(int), 0); + int i, j, n, *p; + + /* fill data */ + for (i = 0; av_fifo_can_write(fifo); i++) + av_fifo_write(fifo, &i, 1); + + /* peek_at at FIFO */ + n = av_fifo_can_read(fifo); + for (i = 0; i < n; i++) { + av_fifo_peek(fifo, &j, 1, i); + printf("%d: %d\n", i, j); + } + printf("\n"); + + /* generic peek at FIFO */ + + n = av_fifo_can_read(fifo); + p = malloc(n * av_fifo_elem_size(fifo)); + if (p == NULL) { + fprintf(stderr, "failed to allocate memory.\n"); + exit(1); + } + + (void) av_fifo_peek(fifo, p, n, 0); + + /* read data at p */ + for(i = 0; i < n; ++i) + printf("%d: %d\n", i, p[i]); + + putchar('\n'); + + /* read data */ + for (i = 0; av_fifo_can_read(fifo); i++) { + av_fifo_read(fifo, &j, 1); + printf("%d ", j); + } + printf("\n"); + + /* fill data */ + for (i = 0; av_fifo_can_write(fifo); i++) + av_fifo_write(fifo, &i, 1); + + /* peek_at at FIFO */ + n = av_fifo_can_read(fifo); + for (i = 0; i < n; i++) { + av_fifo_peek(fifo, &j, 1, i); + printf("%d: %d\n", i, j); + } + putchar('\n'); + + /* test fifo_grow */ + (void) av_fifo_grow2(fifo, 15); + + /* fill data */ + n = av_fifo_can_read(fifo); + for (i = n; av_fifo_can_write(fifo); ++i) + av_fifo_write(fifo, &i, 1); + + /* peek_at at FIFO */ + n = av_fifo_can_read(fifo); + for (i = 0; i < n; i++) { + av_fifo_peek(fifo, &j, 1, i); + printf("%d: %d\n", i, j); + } + + av_fifo_freep2(&fifo); + + /* test randomly-sized write/read/peek with a callback */ + { + CBState s = { 0 }; + uint32_t seed = av_get_random_seed(); + + AVLFG lfg; + int ret; + + av_lfg_init(&lfg, seed); + + fifo = av_fifo_alloc2(1, sizeof(unsigned), AV_FIFO_FLAG_AUTO_GROW); + + for (i = 0; i < 32; i++) { + size_t nb_elems = 16; + unsigned to_process = av_lfg_get(&lfg) % nb_elems; + + s.to_process = to_process; + + ret = av_fifo_write_from_cb(fifo, write_cb, &s, &nb_elems); + if (ret < 0 || s.to_process || nb_elems != to_process) { + printf("FIFO write fail; seed %"PRIu32"\n", seed); + return 1; + } + + nb_elems = av_fifo_can_read(fifo); + if (nb_elems > 1) { + s.offset = av_lfg_get(&lfg) % (nb_elems - 1); + nb_elems -= s.offset; + + s.to_process = av_lfg_get(&lfg) % nb_elems; + to_process = s.to_process; + + ret = av_fifo_peek_to_cb(fifo, read_cb, &s, &nb_elems, s.offset); + if (ret < 0 || s.to_process || nb_elems != to_process) { + printf("FIFO peek fail; seed %"PRIu32"\n", seed); + return 1; + } + } + + nb_elems = av_fifo_can_read(fifo); + to_process = nb_elems ? av_lfg_get(&lfg) % nb_elems : 0; + s.to_process = to_process; + s.offset = 0; + + ret = av_fifo_read_to_cb(fifo, read_cb, &s, &nb_elems); + if (ret < 0 || s.to_process || to_process != nb_elems) { + printf("FIFO read fail; seed %"PRIu32"\n", seed); + return 1; + } + s.read_idx += s.offset; + } + } + + av_fifo_freep2(&fifo); + free(p); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/file.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/file.c new file mode 100644 index 00000000..3608bccc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/file.c @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/file.c" + +#undef printf + +int main(void) +{ + uint8_t *buf; + size_t size; + if (av_file_map("file.c", &buf, &size, 0, NULL) < 0) + return 1; + + buf[0] = 's'; + printf("%s", buf); + av_file_unmap(buf, size); + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/hash.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/hash.c new file mode 100644 index 00000000..4f2ad52a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/hash.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/hash.h" + +#define SRC_BUF_SIZE 64 +#define DST_BUF_SIZE (AV_HASH_MAX_SIZE * 8) + +int main(void) +{ + struct AVHashContext *ctx = NULL; + int i, j, numhashes = 0; + static const uint8_t src[SRC_BUF_SIZE] = { 0 }; + uint8_t dst[DST_BUF_SIZE]; + + while (av_hash_names(numhashes)) + numhashes++; + + for (i = 0; i < numhashes; i++) { + if (av_hash_alloc(&ctx, av_hash_names(i)) < 0) + return 1; + + av_hash_init(ctx); + av_hash_update(ctx, src, SRC_BUF_SIZE); + memset(dst, 0, DST_BUF_SIZE); + av_hash_final_hex(ctx, dst, DST_BUF_SIZE); + printf("%s hex: %s\n", av_hash_get_name(ctx), dst); + + av_hash_init(ctx); + av_hash_update(ctx, src, SRC_BUF_SIZE); + av_hash_final_bin(ctx, dst, DST_BUF_SIZE); + printf("%s bin: ", av_hash_get_name(ctx)); + for (j = 0; j < av_hash_get_size(ctx); j++) { + printf("%#x ", dst[j]); + } + printf("\n"); + + av_hash_init(ctx); + av_hash_update(ctx, src, SRC_BUF_SIZE); + av_hash_final_b64(ctx, dst, DST_BUF_SIZE); + printf("%s b64: %s\n", av_hash_get_name(ctx), dst); + av_hash_freep(&ctx); + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/hmac.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/hmac.c new file mode 100644 index 00000000..0fa50e45 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/hmac.c @@ -0,0 +1,87 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/hmac.c" + +#include +#include + +static void test(AVHMAC *hmac, const uint8_t *key, int keylen, + const uint8_t *data, int datalen) +{ + uint8_t buf[MAX_HASHLEN]; + int out, i; + // Some of the test vectors are strings, where sizeof() includes the + // trailing null byte - remove that. + if (!key[keylen - 1]) + keylen--; + if (!data[datalen - 1]) + datalen--; + out = av_hmac_calc(hmac, data, datalen, key, keylen, buf, sizeof(buf)); + for (i = 0; i < out; i++) + printf("%02x", buf[i]); + printf("\n"); +} + +int main(void) +{ + uint8_t key1[20], key3[131], data3[50]; + AVHMAC *hmac; + enum AVHMACType i; + static const uint8_t key2[] = "Jefe"; + static const uint8_t data1[] = "Hi There"; + static const uint8_t data2[] = "what do ya want for nothing?"; + static const uint8_t data4[] = "Test Using Larger Than Block-Size Key - Hash Key First"; + static const uint8_t data5[] = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"; + static const uint8_t data6[] = "This is a test using a larger than block-size key and a larger " + "than block-size data. The key needs to be hashed before being used" + " by the HMAC algorithm."; + memset(key1, 0x0b, sizeof(key1)); + memset(key3, 0xaa, sizeof(key3)); + memset(data3, 0xdd, sizeof(data3)); + + /* MD5, SHA-1 */ + for (i = AV_HMAC_MD5; i <= AV_HMAC_SHA1; i++) { + hmac = av_hmac_alloc(i); + if (!hmac) + return 1; + // RFC 2202 test vectors + test(hmac, key1, hmac->hashlen, data1, sizeof(data1)); + test(hmac, key2, sizeof(key2), data2, sizeof(data2)); + test(hmac, key3, hmac->hashlen, data3, sizeof(data3)); + test(hmac, key3, 80, data4, sizeof(data4)); + test(hmac, key3, 80, data5, sizeof(data5)); + av_hmac_free(hmac); + } + + /* SHA-2 */ + for (i = AV_HMAC_SHA224; i <= AV_HMAC_SHA512; i++) { + hmac = av_hmac_alloc(i); + if (!hmac) + return 1; + // RFC 4231 test vectors + test(hmac, key1, sizeof(key1), data1, sizeof(data1)); + test(hmac, key2, sizeof(key2), data2, sizeof(data2)); + test(hmac, key3, 20, data3, sizeof(data3)); + test(hmac, key3, sizeof(key3), data4, sizeof(data4)); + test(hmac, key3, sizeof(key3), data6, sizeof(data6)); + av_hmac_free(hmac); + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/hwdevice.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/hwdevice.c new file mode 100644 index 00000000..7eb355c9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/hwdevice.c @@ -0,0 +1,226 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/hwcontext.h" + +static int test_derivation(AVBufferRef *src_ref, const char *src_name) +{ + enum AVHWDeviceType derived_type; + const char *derived_name; + AVBufferRef *derived_ref = NULL, *back_ref = NULL; + AVHWDeviceContext *src_dev, *derived_dev; + int err; + + src_dev = (AVHWDeviceContext*)src_ref->data; + + derived_type = AV_HWDEVICE_TYPE_NONE; + while (1) { + derived_type = av_hwdevice_iterate_types(derived_type); + if (derived_type == AV_HWDEVICE_TYPE_NONE) + break; + + derived_name = av_hwdevice_get_type_name(derived_type); + + err = av_hwdevice_ctx_create_derived(&derived_ref, derived_type, + src_ref, 0); + if (err < 0) { + fprintf(stderr, "Unable to derive %s -> %s: %d.\n", + src_name, derived_name, err); + continue; + } + + derived_dev = (AVHWDeviceContext*)derived_ref->data; + if (derived_dev->type != derived_type) { + fprintf(stderr, "Device derived as type %d has type %d.\n", + derived_type, derived_dev->type); + goto fail; + } + + if (derived_type == src_dev->type) { + if (derived_dev != src_dev) { + fprintf(stderr, "Derivation of %s from itself succeeded " + "but did not return the same device.\n", src_name); + goto fail; + } + av_buffer_unref(&derived_ref); + continue; + } + + err = av_hwdevice_ctx_create_derived(&back_ref, src_dev->type, + derived_ref, 0); + if (err < 0) { + fprintf(stderr, "Derivation %s to %s succeeded, but derivation " + "back again failed: %d.\n", + src_name, derived_name, err); + goto fail; + } + + if (back_ref->data != src_ref->data) { + fprintf(stderr, "Derivation %s to %s succeeded, but derivation " + "back again did not return the original device.\n", + src_name, derived_name); + goto fail; + } + + fprintf(stderr, "Successfully tested derivation %s -> %s.\n", + src_name, derived_name); + + av_buffer_unref(&derived_ref); + av_buffer_unref(&back_ref); + } + + return 0; + +fail: + av_buffer_unref(&derived_ref); + av_buffer_unref(&back_ref); + return -1; +} + +static int test_device(enum AVHWDeviceType type, const char *name, + const char *device, AVDictionary *opts, int flags) +{ + AVBufferRef *ref; + AVHWDeviceContext *dev; + int err; + + err = av_hwdevice_ctx_create(&ref, type, device, opts, flags); + if (err < 0) { + fprintf(stderr, "Failed to create %s device: %d.\n", name, err); + return 1; + } + + dev = (AVHWDeviceContext*)ref->data; + if (dev->type != type) { + fprintf(stderr, "Device created as type %d has type %d.\n", + type, dev->type); + av_buffer_unref(&ref); + return -1; + } + + fprintf(stderr, "Device type %s successfully created.\n", name); + + err = test_derivation(ref, name); + + av_buffer_unref(&ref); + + return err; +} + +static const struct { + enum AVHWDeviceType type; + const char *possible_devices[5]; +} test_devices[] = { + { AV_HWDEVICE_TYPE_CUDA, + { "0", "1", "2" } }, + { AV_HWDEVICE_TYPE_DRM, + { "/dev/dri/card0", "/dev/dri/card1", + "/dev/dri/renderD128", "/dev/dri/renderD129" } }, + { AV_HWDEVICE_TYPE_DXVA2, + { "0", "1", "2" } }, + { AV_HWDEVICE_TYPE_D3D11VA, + { "0", "1", "2" } }, + { AV_HWDEVICE_TYPE_OPENCL, + { "0.0", "0.1", "1.0", "1.1" } }, + { AV_HWDEVICE_TYPE_VAAPI, + { "/dev/dri/renderD128", "/dev/dri/renderD129", ":0" } }, +}; + +static int test_device_type(enum AVHWDeviceType type) +{ + enum AVHWDeviceType check; + const char *name; + int i, j, found, err; + + name = av_hwdevice_get_type_name(type); + if (!name) { + fprintf(stderr, "No name available for device type %d.\n", type); + return -1; + } + + check = av_hwdevice_find_type_by_name(name); + if (check != type) { + fprintf(stderr, "Type %d maps to name %s maps to type %d.\n", + type, name, check); + return -1; + } + + found = 0; + + err = test_device(type, name, NULL, NULL, 0); + if (err < 0) { + fprintf(stderr, "Test failed for %s with default options.\n", name); + return -1; + } + if (err == 0) { + fprintf(stderr, "Test passed for %s with default options.\n", name); + ++found; + } + + for (i = 0; i < FF_ARRAY_ELEMS(test_devices); i++) { + if (test_devices[i].type != type) + continue; + + for (j = 0; test_devices[i].possible_devices[j]; j++) { + err = test_device(type, name, + test_devices[i].possible_devices[j], + NULL, 0); + if (err < 0) { + fprintf(stderr, "Test failed for %s with device %s.\n", + name, test_devices[i].possible_devices[j]); + return -1; + } + if (err == 0) { + fprintf(stderr, "Test passed for %s with device %s.\n", + name, test_devices[i].possible_devices[j]); + ++found; + } + } + } + + return !found; +} + +int main(void) +{ + enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; + int pass, fail, skip, err; + + pass = fail = skip = 0; + while (1) { + type = av_hwdevice_iterate_types(type); + if (type == AV_HWDEVICE_TYPE_NONE) + break; + + err = test_device_type(type); + if (err == 0) + ++pass; + else if (err < 0) + ++fail; + else + ++skip; + } + + fprintf(stderr, "Attempted to test %d device types: " + "%d passed, %d failed, %d skipped.\n", + pass + fail + skip, pass, fail, skip); + + return fail > 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/imgutils.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/imgutils.c new file mode 100644 index 00000000..748bd6c9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/imgutils.c @@ -0,0 +1,74 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/imgutils.c" + +#undef printf + +int main(void) +{ + const AVPixFmtDescriptor *desc = NULL; + int64_t x, y; + + for (y = -1; y= 0); + } + printf("\n"); + } + printf("\n"); + + while (desc = av_pix_fmt_desc_next(desc)) { + uint8_t *data[4]; + size_t sizes[4]; + ptrdiff_t linesizes1[4], offsets[3] = { 0 }; + int i, total_size, w = 64, h = 48, linesizes[4]; + enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(desc); + + if (av_image_fill_linesizes(linesizes, pix_fmt, w) < 0) + continue; + for (i = 0; i < 4; i++) + linesizes1[i] = linesizes[i]; + if (av_image_fill_plane_sizes(sizes, pix_fmt, h, linesizes1) < 0) + continue; + total_size = av_image_fill_pointers(data, pix_fmt, h, (void *)1, linesizes); + if (total_size < 0) + continue; + printf("%-16s", desc->name); + for (i = 0; i < 4 && data[i]; i++); + printf("planes: %d", i); + // Test the output of av_image_fill_linesizes() + printf(", linesizes:"); + for (i = 0; i < 4; i++) + printf(" %3d", linesizes[i]); + // Test the output of av_image_fill_plane_sizes() + printf(", plane_sizes:"); + for (i = 0; i < 4; i++) + printf(" %5"SIZE_SPECIFIER, sizes[i]); + // Test the output of av_image_fill_pointers() + for (i = 0; i < 3 && data[i + 1]; i++) + offsets[i] = data[i + 1] - data[i]; + printf(", plane_offsets:"); + for (i = 0; i < 3; i++) + printf(" %5"PTRDIFF_SPECIFIER, offsets[i]); + printf(", total_size: %d\n", total_size); + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/integer.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/integer.c new file mode 100644 index 00000000..d2c8f2a9 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/integer.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/integer.h" +#include "libavutil/intmath.h" + +int main(void){ + int64_t a,b; + + for(a=7; a<256*256*256; a+=13215){ + for(b=3; b<256*256*256; b+=27118){ + AVInteger ai= av_int2i(a); + AVInteger bi= av_int2i(b); + + av_assert0(av_i2int(ai) == a); + av_assert0(av_i2int(bi) == b); + av_assert0(av_i2int(av_add_i(ai,bi)) == a+b); + av_assert0(av_i2int(av_sub_i(ai,bi)) == a-b); + av_assert0(av_i2int(av_mul_i(ai,bi)) == a*b); + av_assert0(av_i2int(av_shr_i(ai, 9)) == a>>9); + av_assert0(av_i2int(av_shr_i(ai,-9)) == a<<9); + av_assert0(av_i2int(av_shr_i(ai, 17)) == a>>17); + av_assert0(av_i2int(av_shr_i(ai,-17)) == a<<17); + av_assert0(av_log2_i(ai) == av_log2(a)); + av_assert0(av_i2int(av_div_i(ai,bi)) == a/b); + } + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/lfg.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/lfg.c new file mode 100644 index 00000000..bf127e30 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/lfg.c @@ -0,0 +1,191 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/log.h" +#include "libavutil/timer.h" +#include "libavutil/lfg.h" + +static const double Z_TABLE[31][10] = { + {0.5000, 0.5040, 0.5080, 0.5120, 0.5160, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359}, + {0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753}, + {0.5793, 0.5832, 0.5871, 0.5910, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141}, + {0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.6480, 0.6517}, + {0.6554, 0.6591, 0.6628, 0.6664, 0.6700, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879}, + {0.6915, 0.6950, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.7190, 0.7224}, + {0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549}, + {0.7580, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852}, + {0.7881, 0.7910, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133}, + {0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.8340, 0.8365, 0.8389}, + {0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621}, + {0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.8770, 0.8790, 0.8810, 0.8830}, + {0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.8980, 0.8997, 0.9015}, + {0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177}, + {0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319}, + {0.9332, 0.9345, 0.9357, 0.9370, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441}, + {0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545}, + {0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633}, + {0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706}, + {0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.9750, 0.9756, 0.9761, 0.9767}, + {0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817}, + {0.9821, 0.9826, 0.9830, 0.9834, 0.9838, 0.9842, 0.9846, 0.9850, 0.9854, 0.9857}, + {0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.9890}, + {0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916}, + {0.9918, 0.9920, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936}, + {0.9938, 0.9940, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952}, + {0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.9960, 0.9961, 0.9962, 0.9963, 0.9964}, + {0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9970, 0.9971, 0.9972, 0.9973, 0.9974}, + {0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.9980, 0.9981}, + {0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986}, + {0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.9990, 0.9990} }; + +// Inverse cumulative distribution function +static double inv_cdf(double u) +{ + const double a[4] = { 2.50662823884, + -18.61500062529, + 41.39119773534, + -25.44106049637}; + + const double b[4] = {-8.47351093090, + 23.08336743743, + -21.06224101826, + 3.13082909833}; + + const double c[9] = {0.3374754822726147, + 0.9761690190917186, + 0.1607979714918209, + 0.0276438810333863, + 0.0038405729373609, + 0.0003951896511919, + 0.0000321767881768, + 0.0000002888167364, + 0.0000003960315187}; + + double r; + double x = u - 0.5; + + // Beasley-Springer + if (fabs(x) < 0.42) { + + double y = x * x; + r = x * (((a[3]*y+a[2])*y+a[1])*y+a[0]) / + ((((b[3]*y+b[2])*y+b[1])*y+b[0])*y+1.0); + } + else {// Moro + r = u; + if (x > 0.0) + r = 1.0 - u; + r = log(-log(r)); + r = c[0] + r*(c[1]+r*(c[2]+r*(c[3]+r*(c[4]+r*(c[5]+r*(c[6]+ + r*(c[7]+r*c[8]))))))); + if (x < 0.0) + r = -r; + } + + return r; +} +int main(void) +{ + int x = 0; + int i, j; + AVLFG state; + av_lfg_init(&state, 0xdeadbeef); + for (j = 0; j < 10000; j++) { + for (i = 0; i < 624; i++) { + //av_log(NULL, AV_LOG_ERROR, "%X\n", av_lfg_get(&state)); + x += av_lfg_get(&state); + } + } + av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x); + + /* BMG usage example */ + { + double mean = 1000; + double stddev = 53; + double samp_mean = 0.0, samp_stddev = 0.0, QH = 0; + double Z, p_value = -1, tot_samp = 1000; + double *PRN_arr = av_malloc_array(tot_samp, sizeof(double)); + + if (!PRN_arr) { + fprintf(stderr, "failed to allocate memory!\n"); + return 1; + } + + av_lfg_init(&state, 42); + for (i = 0; i < tot_samp; i += 2) { + double bmg_out[2]; + av_bmg_get(&state, bmg_out); + PRN_arr[i ] = bmg_out[0] * stddev + mean; + PRN_arr[i+1] = bmg_out[1] * stddev + mean; + samp_mean += PRN_arr[i] + PRN_arr[i+1]; + samp_stddev += PRN_arr[i] * PRN_arr[i] + PRN_arr[i+1] * PRN_arr[i+1]; + printf("PRN%d : %f\n" + "PRN%d : %f\n", + i, PRN_arr[i], i+1, PRN_arr[i+1]); + } + samp_mean /= tot_samp; + samp_stddev /= (tot_samp - 1); + samp_stddev -= (tot_samp * 1.0 / (tot_samp - 1))*samp_mean*samp_mean; + samp_stddev = sqrt(samp_stddev); + Z = (mean - samp_mean) / (stddev / sqrt(tot_samp)); + { + int x, y, a, b, flag = 0; + + if (Z < 0.0) { + flag = !flag; + Z = Z * -1.0; + } + + a = (int)(Z * 100); + b = ((int)Z * 100); + x = Z * 10; + y = (b > 0) ? a % b : a; + y = y % 10; + if (x > 30 || y > 9) { + av_log(NULL, AV_LOG_INFO, "error: out of bounds! tried to access" + "Z_TABLE[%d][%d]\n", x, y); + goto SKIP; + } + p_value = flag ? 1 - Z_TABLE[x][y] : Z_TABLE[x][y]; + } + +SKIP: for (i = 0; i < tot_samp; ++i) { + + if ( i < (tot_samp - 1)) { + double H_diff; + H_diff = inv_cdf((i + 2.0 - (3.0/8.0)) / (tot_samp + (1.0/4.0))); + H_diff -= inv_cdf((i + 1.0 - (3.0/8.0)) / (tot_samp + (1.0/4.0))); + + QH += ((PRN_arr[i + 1] - PRN_arr[i]) / H_diff); + } + } + QH = 1.0 - QH / ((tot_samp - 1.0) * samp_stddev); + + printf("sample mean : %f\n" + "true mean : %f\n" + "sample stddev: %f\n" + "true stddev : %f\n" + "z-score : %f\n" + "p-value : %f\n" + "QH[normality]: %f\n", + samp_mean, mean, samp_stddev, stddev, Z, p_value, QH); + + av_freep(&PRN_arr); + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/lls.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/lls.c new file mode 100644 index 00000000..4c14c0c4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/lls.c @@ -0,0 +1,55 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/internal.h" +#include "libavutil/lfg.h" +#include "libavutil/lls.h" +#include "libavutil/mem_internal.h" + +int main(void) +{ + LLSModel m; + int i, order; + AVLFG lfg; + + av_lfg_init(&lfg, 1); + avpriv_init_lls(&m, 3); + + for (i = 0; i < 100; i++) { + LOCAL_ALIGNED(32, double, var, [4]); + double eval; + + var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2; + var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + m.update_lls(&m, var); + avpriv_solve_lls(&m, 0.001, 0); + for (order = 0; order < 3; order++) { + eval = m.evaluate_lls(&m, var + 1, order); + printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", + var[0], order, eval, sqrt(m.variance[order] / (i + 1)), + m.coeff[order][0], m.coeff[order][1], + m.coeff[order][2]); + } + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/log.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/log.c new file mode 100644 index 00000000..8fe9461c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/log.c @@ -0,0 +1,71 @@ +/* + * log functions + * Copyright (c) 2003 Michel Bardiaux + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/log.c" + +#include + +static int call_log_format_line2(const char *fmt, char *buffer, int buffer_size, ...) +{ + va_list args; + int ret; + int print_prefix=1; + va_start(args, buffer_size); + ret = av_log_format_line2(NULL, AV_LOG_INFO, fmt, args, buffer, buffer_size, &print_prefix); + va_end(args); + return ret; +} + +int main(int argc, char **argv) +{ + int i; + av_log_set_level(AV_LOG_DEBUG); + for (use_color=0; use_color<=256; use_color = 255*use_color+1) { + av_log(NULL, AV_LOG_FATAL, "use_color: %d\n", use_color); + for (i = AV_LOG_DEBUG; i>=AV_LOG_QUIET; i-=8) { + av_log(NULL, i, " %d", i); + av_log(NULL, AV_LOG_INFO, "e "); + av_log(NULL, i + 256*123, "C%d", i); + av_log(NULL, AV_LOG_INFO, "e"); + } + av_log(NULL, AV_LOG_PANIC, "\n"); + } + { + int result; + char buffer[4]; + result = call_log_format_line2("foo", NULL, 0); + if(result != 3) { + printf("Test NULL buffer failed.\n"); + return 1; + } + result = call_log_format_line2("foo", buffer, 2); + if(result != 3 || strncmp(buffer, "f", 2)) { + printf("Test buffer too small failed.\n"); + return 1; + } + result = call_log_format_line2("foo", buffer, 4); + if(result != 3 || strncmp(buffer, "foo", 4)) { + printf("Test buffer sufficiently big failed.\n"); + return 1; + } + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/lzo.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/lzo.c new file mode 100644 index 00000000..a5655dbf --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/lzo.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/log.h" +#include "libavutil/lzo.h" +#include "libavutil/mem.h" + +#define MAXSZ (10*1024*1024) + +/* Define one of these to 1 if you wish to benchmark liblzo + * instead of our native implementation. */ +#define BENCHMARK_LIBLZO_SAFE 0 +#define BENCHMARK_LIBLZO_UNSAFE 0 + +int main(int argc, char *argv[]) { + FILE *in = fopen(argv[1], "rb"); + int comp_level = argc > 2 ? atoi(argv[2]) : 0; + uint8_t *orig = av_malloc(MAXSZ + 16); + uint8_t *comp = av_malloc(2*MAXSZ + 16); + uint8_t *decomp = av_malloc(MAXSZ + 16); + size_t s = fread(orig, 1, MAXSZ, in); + lzo_uint clen = 0; + long tmp[LZO1X_MEM_COMPRESS]; + int inlen, outlen; + int i; + av_log_set_level(AV_LOG_DEBUG); + if (comp_level == 0) { + lzo1x_1_compress(orig, s, comp, &clen, tmp); + } else if (comp_level == 11) { + lzo1x_1_11_compress(orig, s, comp, &clen, tmp); + } else if (comp_level == 12) { + lzo1x_1_12_compress(orig, s, comp, &clen, tmp); + } else if (comp_level == 15) { + lzo1x_1_15_compress(orig, s, comp, &clen, tmp); + } else + lzo1x_999_compress(orig, s, comp, &clen, tmp); + for (i = 0; i < 300; i++) { + inlen = clen; outlen = MAXSZ; +#if BENCHMARK_LIBLZO_SAFE + if (lzo1x_decompress_safe(comp, inlen, decomp, &outlen, NULL)) +#elif BENCHMARK_LIBLZO_UNSAFE + if (lzo1x_decompress(comp, inlen, decomp, &outlen, NULL)) +#else + if (av_lzo1x_decode(decomp, &outlen, comp, &inlen)) +#endif + av_log(NULL, AV_LOG_ERROR, "decompression error\n"); + } + if (memcmp(orig, decomp, s)) + av_log(NULL, AV_LOG_ERROR, "decompression incorrect\n"); + else + av_log(NULL, AV_LOG_ERROR, "decompression OK\n"); + fclose(in); + av_free(orig); + av_free(comp); + av_free(decomp); + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/md5.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/md5.c new file mode 100644 index 00000000..0ac8f283 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/md5.c @@ -0,0 +1,55 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/md5.h" + +static void print_md5(uint8_t *md5) +{ + int i; + for (i = 0; i < 16; i++) + printf("%02x", md5[i]); + printf("\n"); +} + +int main(void) +{ + uint8_t md5val[16]; + int i; + + uint8_t in[1000]; + + for (i = 0; i < 1000; i++) + in[i] = i * i; + av_md5_sum(md5val, in, 1000); + print_md5(md5val); + av_md5_sum(md5val, in, 63); + print_md5(md5val); + av_md5_sum(md5val, in, 64); + print_md5(md5val); + av_md5_sum(md5val, in, 65); + print_md5(md5val); + for (i = 0; i < 1000; i++) + in[i] = i % 127; + av_md5_sum(md5val, in, 999); + print_md5(md5val); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/murmur3.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/murmur3.c new file mode 100644 index 00000000..b8d6b1fe --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/murmur3.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" +#include "libavutil/murmur3.h" + +int main(void) +{ + int i; + uint8_t hash_result[16] = {0}; + struct AVMurMur3 *ctx = av_murmur3_alloc(); +#if 1 + uint8_t in[256] = {0}; + uint8_t *hashes = av_mallocz(256 * 16); + for (i = 0; i < 256; i++) + { + in[i] = i; + av_murmur3_init_seeded(ctx, 256 - i); + // Note: this actually tests hashing 0 bytes + av_murmur3_update(ctx, in, i); + av_murmur3_final(ctx, hashes + 16 * i); + } + av_murmur3_init_seeded(ctx, 0); + av_murmur3_update(ctx, hashes, 256 * 16); + av_murmur3_final(ctx, hash_result); + av_free(hashes); + av_freep(&ctx); + printf("result: 0x%"PRIx64" 0x%"PRIx64"\n", AV_RL64(hash_result), AV_RL64(hash_result + 8)); + // official reference value is 32 bit + return AV_RL32(hash_result) != 0x6384ba69; +#else + uint8_t *in = av_mallocz(512*1024); + av_murmur3_init(ctx); + for (i = 0; i < 40*1024; i++) + av_murmur3_update(ctx, in, 512*1024); + av_murmur3_final(ctx, hash_result); + av_free(in); + return hash_result[0]; +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/opt.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/opt.c new file mode 100644 index 00000000..5799e45c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/opt.c @@ -0,0 +1,359 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/common.h" +#include "libavutil/channel_layout.h" +#include "libavutil/error.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" +#include "libavutil/rational.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +typedef struct TestContext { + const AVClass *class; + int num; + int toggle; + char *string; + int flags; + AVRational rational; + AVRational video_rate; + int w, h; + enum AVPixelFormat pix_fmt; + enum AVSampleFormat sample_fmt; + int64_t duration; + uint8_t color[4]; + AVChannelLayout channel_layout; + void *binary; + int binary_size; + void *binary1; + int binary_size1; + void *binary2; + int binary_size2; + int64_t num64; + float flt; + double dbl; + char *escape; + int bool1; + int bool2; + int bool3; + AVDictionary *dict1; + AVDictionary *dict2; +} TestContext; + +#define OFFSET(x) offsetof(TestContext, x) + +#define TEST_FLAG_COOL 01 +#define TEST_FLAG_LAME 02 +#define TEST_FLAG_MU 04 + +static const AVOption test_options[]= { + {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, 1 }, + {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, 1 }, + {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, 10, 1 }, + {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, { .str = "default" }, CHAR_MIN, CHAR_MAX, 1 }, + {"escape", "set escape str", OFFSET(escape), AV_OPT_TYPE_STRING, { .str = "\\=," }, CHAR_MIN, CHAR_MAX, 1 }, + {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, { .i64 = 1 }, 0, INT_MAX, 1, "flags" }, + {"cool", "set cool flag", 0, AV_OPT_TYPE_CONST, { .i64 = TEST_FLAG_COOL }, INT_MIN, INT_MAX, 1, "flags" }, + {"lame", "set lame flag", 0, AV_OPT_TYPE_CONST, { .i64 = TEST_FLAG_LAME }, INT_MIN, INT_MAX, 1, "flags" }, + {"mu", "set mu flag", 0, AV_OPT_TYPE_CONST, { .i64 = TEST_FLAG_MU }, INT_MIN, INT_MAX, 1, "flags" }, + {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, { .str="200x300" }, 0, 0, 1 }, + {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, { .i64 = AV_PIX_FMT_0BGR }, -1, INT_MAX, 1 }, + {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, { .i64 = AV_SAMPLE_FMT_S16 }, -1, INT_MAX, 1 }, + {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 0, INT_MAX, 1 }, + {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 1000 }, 0, INT64_MAX, 1 }, + {"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, { .str = "pink" }, 0, 0, 1 }, + {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHLAYOUT, { .str = "hexagonal" }, 0, 0, 1 }, + {"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, { .str="62696e00" }, 0, 0, 1 }, + {"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, { .str=NULL }, 0, 0, 1 }, + {"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, { .str="" }, 0, 0, 1 }, + {"num64", "set num 64bit", OFFSET(num64), AV_OPT_TYPE_INT64, { .i64 = 1 }, 0, 100, 1 }, + {"flt", "set float", OFFSET(flt), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 / 3 }, 0, 100, 1 }, + {"dbl", "set double", OFFSET(dbl), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 / 3 }, 0, 100, 1 }, + {"bool1", "set boolean value", OFFSET(bool1), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, 1 }, + {"bool2", "set boolean value", OFFSET(bool2), AV_OPT_TYPE_BOOL, { .i64 = 1 }, -1, 1, 1 }, + {"bool3", "set boolean value", OFFSET(bool3), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, 1 }, + {"dict1", "set dictionary value", OFFSET(dict1), AV_OPT_TYPE_DICT, { .str = NULL}, 0, 0, 1 }, + {"dict2", "set dictionary value", OFFSET(dict2), AV_OPT_TYPE_DICT, { .str = "happy=':-)'"}, 0, 0, 1 }, + { NULL }, +}; + +static const char *test_get_name(void *ctx) +{ + return "test"; +} + +static const AVClass test_class = { + .class_name = "TestContext", + .item_name = test_get_name, + .option = test_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void log_callback_help(void *ptr, int level, const char *fmt, va_list vl) +{ + vfprintf(stdout, fmt, vl); +} + +int main(void) +{ + int i; + + av_log_set_level(AV_LOG_DEBUG); + av_log_set_callback(log_callback_help); + + printf("Testing default values\n"); + { + TestContext test_ctx = { 0 }; + test_ctx.class = &test_class; + av_opt_set_defaults(&test_ctx); + + printf("num=%d\n", test_ctx.num); + printf("toggle=%d\n", test_ctx.toggle); + printf("string=%s\n", test_ctx.string); + printf("escape=%s\n", test_ctx.escape); + printf("flags=%d\n", test_ctx.flags); + printf("rational=%d/%d\n", test_ctx.rational.num, test_ctx.rational.den); + printf("video_rate=%d/%d\n", test_ctx.video_rate.num, test_ctx.video_rate.den); + printf("width=%d height=%d\n", test_ctx.w, test_ctx.h); + printf("pix_fmt=%s\n", av_get_pix_fmt_name(test_ctx.pix_fmt)); + printf("sample_fmt=%s\n", av_get_sample_fmt_name(test_ctx.sample_fmt)); + printf("duration=%"PRId64"\n", test_ctx.duration); + printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]); + printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout.u.mask, (int64_t)AV_CH_LAYOUT_HEXAGONAL); + if (test_ctx.binary) + printf("binary=%x %x %x %x\n", ((uint8_t*)test_ctx.binary)[0], ((uint8_t*)test_ctx.binary)[1], ((uint8_t*)test_ctx.binary)[2], ((uint8_t*)test_ctx.binary)[3]); + printf("binary_size=%d\n", test_ctx.binary_size); + printf("num64=%"PRId64"\n", test_ctx.num64); + printf("flt=%.6f\n", test_ctx.flt); + printf("dbl=%.6f\n", test_ctx.dbl); + + av_opt_show2(&test_ctx, NULL, -1, 0); + + av_opt_free(&test_ctx); + } + + printf("\nTesting av_opt_is_set_to_default()\n"); + { + int ret; + TestContext test_ctx = { 0 }; + const AVOption *o = NULL; + test_ctx.class = &test_class; + + av_log_set_level(AV_LOG_QUIET); + + while (o = av_opt_next(&test_ctx, o)) { + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); + } + av_opt_set_defaults(&test_ctx); + while (o = av_opt_next(&test_ctx, o)) { + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); + } + av_opt_free(&test_ctx); + } + + printf("\nTesting av_opt_get/av_opt_set()\n"); + { + TestContext test_ctx = { 0 }; + TestContext test2_ctx = { 0 }; + const AVOption *o = NULL; + test_ctx.class = &test_class; + test2_ctx.class = &test_class; + + av_log_set_level(AV_LOG_QUIET); + + av_opt_set_defaults(&test_ctx); + + while (o = av_opt_next(&test_ctx, o)) { + char *value1 = NULL; + char *value2 = NULL; + int ret1 = AVERROR_BUG; + int ret2 = AVERROR_BUG; + int ret3 = AVERROR_BUG; + + if (o->type == AV_OPT_TYPE_CONST) + continue; + + ret1 = av_opt_get(&test_ctx, o->name, 0, (uint8_t **)&value1); + if (ret1 >= 0) { + ret2 = av_opt_set(&test2_ctx, o->name, value1, 0); + if (ret2 >= 0) + ret3 = av_opt_get(&test2_ctx, o->name, 0, (uint8_t **)&value2); + } + + printf("name: %-11s get: %-16s set: %-16s get: %-16s %s\n", o->name, + ret1 >= 0 ? value1 : av_err2str(ret1), + ret2 >= 0 ? "OK" : av_err2str(ret2), + ret3 >= 0 ? value2 : av_err2str(ret3), + ret1 >= 0 && ret2 >= 0 && ret3 >= 0 && !strcmp(value1, value2) ? "OK" : "Mismatch"); + av_free(value1); + av_free(value2); + } + av_opt_free(&test_ctx); + av_opt_free(&test2_ctx); + } + + printf("\nTest av_opt_serialize()\n"); + { + TestContext test_ctx = { 0 }; + char *buf; + test_ctx.class = &test_class; + + av_log_set_level(AV_LOG_QUIET); + + av_opt_set_defaults(&test_ctx); + if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) { + printf("%s\n", buf); + av_opt_free(&test_ctx); + memset(&test_ctx, 0, sizeof(test_ctx)); + test_ctx.class = &test_class; + av_set_options_string(&test_ctx, buf, "=", ","); + av_free(buf); + if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) { + printf("%s\n", buf); + av_free(buf); + } + } + av_opt_free(&test_ctx); + } + + printf("\nTesting av_set_options_string()\n"); + { + TestContext test_ctx = { 0 }; + static const char * const options[] = { + "", + ":", + "=", + "foo=:", + ":=foo", + "=foo", + "foo=", + "foo", + "foo=val", + "foo==val", + "toggle=:", + "string=:", + "toggle=1 : foo", + "toggle=100", + "toggle==1", + "flags=+mu-lame : num=42: toggle=0", + "num=42 : string=blahblah", + "rational=0 : rational=1/2 : rational=1/-1", + "rational=-1/0", + "size=1024x768", + "size=pal", + "size=bogus", + "pix_fmt=yuv420p", + "pix_fmt=2", + "pix_fmt=bogus", + "sample_fmt=s16", + "sample_fmt=2", + "sample_fmt=bogus", + "video_rate=pal", + "video_rate=25", + "video_rate=30000/1001", + "video_rate=30/1.001", + "video_rate=bogus", + "duration=bogus", + "duration=123.45", + "duration=1\\:23\\:45.67", + "color=blue", + "color=0x223300", + "color=0x42FF07AA", + "cl=FL+FR", + "cl=foo", + "bin=boguss", + "bin=111", + "bin=ffff", + "num64=bogus", + "num64=44", + "num64=44.4", + "num64=-1", + "num64=101", + "flt=bogus", + "flt=2", + "flt=2.2", + "flt=-1", + "flt=101", + "dbl=bogus", + "dbl=2", + "dbl=2.2", + "dbl=-1", + "dbl=101", + "bool1=true", + "bool2=auto", + "dict1='happy=\\:-):sad=\\:-('", + }; + + test_ctx.class = &test_class; + av_opt_set_defaults(&test_ctx); + + av_log_set_level(AV_LOG_QUIET); + + for (i=0; i < FF_ARRAY_ELEMS(options); i++) { + int silence_log = !strcmp(options[i], "rational=-1/0"); // inf formating differs between platforms + av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); + if (silence_log) + av_log_set_callback(NULL); + if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) + printf("Error '%s'\n", options[i]); + else + printf("OK '%s'\n", options[i]); + av_log_set_callback(log_callback_help); + } + av_opt_free(&test_ctx); + } + + printf("\nTesting av_opt_set_from_string()\n"); + { + TestContext test_ctx = { 0 }; + static const char * const options[] = { + "", + "5", + "5:hello", + "5:hello:size=pal", + "5:size=pal:hello", + ":", + "=", + " 5 : hello : size = pal ", + "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42" + }; + static const char * const shorthand[] = { "num", "string", NULL }; + + test_ctx.class = &test_class; + av_opt_set_defaults(&test_ctx); + + av_log_set_level(AV_LOG_QUIET); + + for (i=0; i < FF_ARRAY_ELEMS(options); i++) { + av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); + if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0) + printf("Error '%s'\n", options[i]); + else + printf("OK '%s'\n", options[i]); + } + av_opt_free(&test_ctx); + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/parseutils.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/parseutils.c new file mode 100644 index 00000000..a1ac8d44 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/parseutils.c @@ -0,0 +1,271 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TEST +#include "libavutil/parseutils.c" + +#include +#include + +#include "libavutil/common.h" +#include "libavutil/log.h" +#include "libavutil/rational.h" + +static uint32_t randomv = MKTAG('L','A','V','U'); + +static uint32_t av_get_random_seed_deterministic(void) +{ + return randomv = randomv * 1664525 + 1013904223; +} + +static void test_av_parse_video_rate(void) +{ + int i; + static const char *const rates[] = { + "-inf", + "inf", + "nan", + "123/0", + "-123 / 0", + "", + "/", + " 123 / 321", + "foo/foo", + "foo/1", + "1/foo", + "0/0", + "/0", + "1/", + "1", + "0", + "-123/123", + "-foo", + "123.23", + ".23", + "-.23", + "-0.234", + "-0.0000001", + " 21332.2324 ", + " -21332.2324 ", + }; + + for (i = 0; i < FF_ARRAY_ELEMS(rates); i++) { + int ret; + AVRational q = { 0, 0 }; + ret = av_parse_video_rate(&q, rates[i]); + printf("'%s' -> %d/%d %s\n", + rates[i], q.num, q.den, ret ? "ERROR" : "OK"); + } +} + +static void test_av_parse_color(void) +{ + int i; + uint8_t rgba[4]; + static const char *const color_names[] = { + "bikeshed", + "RaNdOm", + "foo", + "red", + "Red ", + "RED", + "Violet", + "Yellow", + "Red", + "0x000000", + "0x0000000", + "0xff000000", + "0x3e34ff", + "0x3e34ffaa", + "0xffXXee", + "0xfoobar", + "0xffffeeeeeeee", + "#ff0000", + "#ffXX00", + "ff0000", + "ffXX00", + "red@foo", + "random@10", + "0xff0000@1.0", + "red@", + "red@0xfff", + "red@0xf", + "red@2", + "red@0.1", + "red@-1", + "red@0.5", + "red@1.0", + "red@256", + "red@10foo", + "red@-1.0", + "red@-0.0", + }; + + av_log_set_level(AV_LOG_DEBUG); + + for (i = 0; i < FF_ARRAY_ELEMS(color_names); i++) { + if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0) + printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", + color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]); + else + printf("%s -> error\n", color_names[i]); + } +} + +static void test_av_small_strptime(void) +{ + int i; + struct tm tm = { 0 }; + struct fmt_timespec_entry { + const char *fmt, *timespec; + } fmt_timespec_entries[] = { + { "%Y-%m-%d", "2012-12-21" }, + { "%Y - %m - %d", "2012-12-21" }, + { "%Y-%m-%d %H:%M:%S", "2012-12-21 20:12:21" }, + { " %Y - %m - %d %H : %M : %S", " 2012 - 12 - 21 20 : 12 : 21" }, + { " %Y - %b - %d %H : %M : %S", " 2012 - nOV - 21 20 : 12 : 21" }, + { " %Y - %B - %d %H : %M : %S", " 2012 - nOVemBeR - 21 20 : 12 : 21" }, + { " %Y - %B%d %H : %M : %S", " 2012 - may21 20 : 12 : 21" }, + { " %Y - %B%d %H : %M : %S", " 2012 - mby21 20 : 12 : 21" }, + { " %Y - %B - %d %H : %M : %S", " 2012 - JunE - 21 20 : 12 : 21" }, + { " %Y - %B - %d %H : %M : %S", " 2012 - Jane - 21 20 : 12 : 21" }, + { " %Y - %B - %d %H : %M : %S", " 2012 - January - 21 20 : 12 : 21" }, + }; + + av_log_set_level(AV_LOG_DEBUG); + for (i = 0; i < FF_ARRAY_ELEMS(fmt_timespec_entries); i++) { + char *p; + struct fmt_timespec_entry *e = &fmt_timespec_entries[i]; + printf("fmt:'%s' spec:'%s' -> ", e->fmt, e->timespec); + p = av_small_strptime(e->timespec, e->fmt, &tm); + if (p) { + printf("%04d-%02d-%2d %02d:%02d:%02d\n", + 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + } else { + printf("error\n"); + } + } +} + +static void test_av_parse_time(void) +{ + int i; + int64_t tv; + time_t tvi; + struct tm *tm; + static char tzstr[] = "TZ=CET-1"; + static const char * const time_string[] = { + "now", + "12:35:46", + "2000-12-20 0:02:47.5z", + "2012 - 02-22 17:44:07", + "2000-12-20T010247.6", + "2000-12-12 1:35:46+05:30", + "2002-12-12 22:30:40-02", + }; + static const char * const duration_string[] = { + "2:34:56.79", + "-1:23:45.67", + "42.1729", + "-1729.42", + "12:34", + "2147483648s", + "4294967296ms", + "8589934592us", + "9223372036854775808us", + }; + + av_log_set_level(AV_LOG_DEBUG); + putenv(tzstr); + printf("(now is 2012-03-17 09:14:13.2 +0100, local time is UTC+1)\n"); + for (i = 0; i < FF_ARRAY_ELEMS(time_string); i++) { + printf("%-24s -> ", time_string[i]); + if (av_parse_time(&tv, time_string[i], 0)) { + printf("error\n"); + } else { + tvi = tv / 1000000; + tm = gmtime(&tvi); + printf("%14"PRIi64".%06d = %04d-%02d-%02dT%02d:%02d:%02dZ\n", + tv / 1000000, (int)(tv % 1000000), + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + } + } + for (i = 0; i < FF_ARRAY_ELEMS(duration_string); i++) { + printf("%-24s -> ", duration_string[i]); + if (av_parse_time(&tv, duration_string[i], 1)) { + printf("error\n"); + } else { + printf("%+21"PRIi64"\n", tv); + } + } +} + +static void test_av_get_known_color_name(void) +{ + int i; + const uint8_t *rgba; + const char *color; + + for (i = 0; i < FF_ARRAY_ELEMS(color_table); ++i) { + color = av_get_known_color_name(i, &rgba); + if (color) + printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", + color, rgba[0], rgba[1], rgba[2], rgba[3]); + else + printf("Color ID: %d not found\n", i); + } +} + +static void test_av_find_info_tag(void) +{ + static const char args[] = "?tag1=val1&tag2=val2&tag3=val3&tag41=value 41&tag42=random1"; + static const char *tags[] = {"tag1", "tag2", "tag3", "tag4", "tag41", "41", "random1"}; + char buff[16]; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(tags); ++i) { + if (av_find_info_tag(buff, sizeof(buff), tags[i], args)) + printf("%d. %s found: %s\n", i, tags[i], buff); + else + printf("%d. %s not found\n", i, tags[i]); + } +} + +int main(void) +{ + printf("Testing av_parse_video_rate()\n"); + test_av_parse_video_rate(); + + printf("\nTesting av_parse_color()\n"); + test_av_parse_color(); + + printf("\nTesting av_small_strptime()\n"); + test_av_small_strptime(); + + printf("\nTesting av_parse_time()\n"); + test_av_parse_time(); + + printf("\nTesting av_get_known_color_name()\n"); + test_av_get_known_color_name(); + + printf("\nTesting av_find_info_tag()\n"); + test_av_find_info_tag(); + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/pca.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/pca.c new file mode 100644 index 00000000..2d9eb8f5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/pca.c @@ -0,0 +1,102 @@ +/* + * principal component analysis (PCA) + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/pca.c" +#include "libavutil/lfg.h" + +#undef printf +#include +#include + +int main(void){ + PCA *pca; + int i, j, k; +#define LEN 8 + double eigenvector[LEN*LEN]; + double eigenvalue[LEN]; + AVLFG prng; + + av_lfg_init(&prng, 1); + + pca= ff_pca_init(LEN); + + for(i=0; i<9000000; i++){ + double v[2*LEN+100]; + double sum=0; + int pos = av_lfg_get(&prng) % LEN; + int v2 = av_lfg_get(&prng) % 101 - 50; + v[0] = av_lfg_get(&prng) % 101 - 50; + for(j=1; j<8; j++){ + if(j<=pos) v[j]= v[0]; + else v[j]= v2; + sum += v[j]; + } +/* for(j=0; jcount= 1; + pca->mean[i]= 0; + +// (0.5^|x|)^2 = 0.5^2|x| = 0.25^|x| + + +// pca.covariance[i + i*LEN]= pow(0.5, fabs + for(j=i; jcovariance[i + j*LEN]); + } + printf("\n"); + } + + for(i=0; icovariance[FFMIN(k,j) + FFMAX(k,j)*LEN] * eigenvector[i + k*LEN]; + } + v[j] /= eigenvalue[i]; + error += fabs(v[j] - eigenvector[i + j*LEN]); + } + printf("%f ", error); + } + printf("\n"); + + for(i=0; i + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/pixdesc.c" + +int main(void){ + int i; + int err=0; + int skip = 0; + + for (i=0; iname) { + skip ++; + continue; + } + if (skip) { + av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip); + skip = 0; + } + av_log(NULL, AV_LOG_INFO, "pix fmt %s avg_bpp:%d colortype:%d\n", desc->name, av_get_padded_bits_per_pixel(desc), get_color_type(desc)); + } + return err; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/pixelutils.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/pixelutils.c new file mode 100644 index 00000000..f5ddeb32 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/pixelutils.c @@ -0,0 +1,208 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/internal.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" +#include "libavutil/pixdesc.h" +#include "libavutil/pixelutils.c" +#include "libavutil/pixfmt.h" + +#define W1 320 +#define H1 240 +#define W2 640 +#define H2 480 + +static void check_pixfmt_descriptors(void) +{ + const AVPixFmtDescriptor *d, *last = NULL; + int i; + + for (i = AV_PIX_FMT_NONE, d = NULL; i++, d = av_pix_fmt_desc_next(d);) { + uint8_t fill[4][8 + 6 + 3] = {{ 0 }}; + uint8_t *data[4] = { fill[0], fill[1], fill[2], fill[3] }; + int linesize[4] = { 0, 0, 0, 0 }; + uint16_t tmp[2]; + + av_assert0(d->name && d->name[0]); + av_log(NULL, AV_LOG_INFO, "Checking: %s\n", d->name); + av_assert0(d->log2_chroma_w <= 3); + av_assert0(d->log2_chroma_h <= 3); + av_assert0(d->nb_components <= 4); + av_assert0(d->nb_components || (d->flags & AV_PIX_FMT_FLAG_HWACCEL)); + av_assert0(av_get_pix_fmt(d->name) == av_pix_fmt_desc_get_id(d)); + + /* The following two checks as well as the one after the loop + * would need to be changed if we changed the way the descriptors + * are stored. */ + av_assert0(i == av_pix_fmt_desc_get_id(d)); + av_assert0(!last || last + 1 == d); + + for (int j = 0; j < FF_ARRAY_ELEMS(d->comp); j++) { + const AVComponentDescriptor *c = &d->comp[j]; + if (j >= d->nb_components) { + av_assert0(!c->plane && !c->step && !c->offset && !c->shift && !c->depth); + continue; + } + if (d->flags & AV_PIX_FMT_FLAG_BITSTREAM) { + av_assert0(c->step >= c->depth); + } else { + av_assert0(8*c->step >= c->depth); + } + if (d->flags & AV_PIX_FMT_FLAG_BAYER) + continue; + av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); + av_assert0(tmp[0] == 0 && tmp[1] == 0); + tmp[0] = tmp[1] = (1ULL << c->depth) - 1; + av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); + } + last = d; + } + av_assert0(i == AV_PIX_FMT_NB); +} + +static int run_single_test(const char *test, + const uint8_t *block1, ptrdiff_t stride1, + const uint8_t *block2, ptrdiff_t stride2, + int align, int n) +{ + int out, ref; + av_pixelutils_sad_fn f_ref = sad_c[n - 1]; + av_pixelutils_sad_fn f_out = av_pixelutils_get_sad_fn(n, n, align, NULL); + + switch (align) { + case 0: block1++; block2++; break; + case 1: block2++; break; + case 2: break; + } + + out = f_out(block1, stride1, block2, stride2); + ref = f_ref(block1, stride1, block2, stride2); + printf("[%s] [%c%c] SAD [%s] %dx%d=%d ref=%d\n", + out == ref ? "OK" : "FAIL", + align ? 'A' : 'U', align == 2 ? 'A' : 'U', + test, 1<>24; \ + } \ +} while (0) + + /* Normal test with different strides */ + RANDOM_INIT(buf1, W1*H1); + RANDOM_INIT(buf2, W2*H2); + ret = run_test("random", buf1, buf2); + if (ret < 0) + goto end; + + /* Check for maximum SAD */ + memset(buf1, 0xff, W1*H1); + memset(buf2, 0x00, W2*H2); + ret = run_test("max", buf1, buf2); + if (ret < 0) + goto end; + + /* Check for minimum SAD */ + memset(buf1, 0x90, W1*H1); + memset(buf2, 0x90, W2*H2); + ret = run_test("min", buf1, buf2); + if (ret < 0) + goto end; + + /* Exact buffer sizes, to check for overreads */ + for (i = 1; i <= 5; i++) { + for (align = 0; align < 3; align++) { + int size1, size2; + + av_freep(&buf1); + av_freep(&buf2); + + size1 = size2 = 1 << (i << 1); + + switch (align) { + case 0: size1++; size2++; break; + case 1: size2++; break; + case 2: break; + } + + buf1 = av_malloc(size1); + buf2 = av_malloc(size2); + if (!buf1 || !buf2) { + fprintf(stderr, "malloc failure\n"); + ret = 1; + goto end; + } + RANDOM_INIT(buf1, size1); + RANDOM_INIT(buf2, size2); + ret = run_single_test("small", buf1, 1< + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TEST 1 +#include "libavutil/random_seed.c" + +#undef printf +#define N 256 +#define F 2 +#include + +typedef uint32_t (*random_seed_ptr_t)(void); + +int main(void) +{ + int i, j, rsf, retry; + uint32_t seeds[N]; + random_seed_ptr_t random_seed[F] = {av_get_random_seed, get_generic_seed}; + + for (rsf=0; rsf= 3) { + printf("rsf %d: FAIL at %d with %"PRIX32"\n", rsf, j, seeds[j]); + return 1; + } + } + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/rational.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/rational.c new file mode 100644 index 00000000..caec07d7 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/rational.c @@ -0,0 +1,134 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/rational.c" +#include "libavutil/integer.h" + +int main(void) +{ + AVRational a,b,r; + int i,j,k; + static const int64_t numlist[] = { + INT64_MIN, INT64_MIN+1, INT64_MAX, INT32_MIN, INT32_MAX, 1,0,-1, + 123456789, INT32_MAX-1, INT32_MAX+1LL, UINT32_MAX-1, UINT32_MAX, UINT32_MAX+1LL + }; + + for (a.num = -2; a.num <= 2; a.num++) { + for (a.den = -2; a.den <= 2; a.den++) { + for (b.num = -2; b.num <= 2; b.num++) { + for (b.den = -2; b.den <= 2; b.den++) { + int c = av_cmp_q(a,b); + double d = av_q2d(a) == av_q2d(b) ? + 0 : (av_q2d(a) - av_q2d(b)); + if (d > 0) d = 1; + else if (d < 0) d = -1; + else if (d != d) d = INT_MIN; + if (c != d) + av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num, + a.den, b.num, b.den, c,d); + r = av_sub_q(av_add_q(b,a), b); + if(b.den && (r.num*a.den != a.num*r.den || !r.num != !a.num || !r.den != !a.den)) + av_log(NULL, AV_LOG_ERROR, "%d/%d ", r.num, r.den); + } + } + } + } + + for (i = 0; i < FF_ARRAY_ELEMS(numlist); i++) { + int64_t a = numlist[i]; + + for (j = 0; j < FF_ARRAY_ELEMS(numlist); j++) { + int64_t b = numlist[j]; + if (b<=0) + continue; + for (k = 0; k < FF_ARRAY_ELEMS(numlist); k++) { + int64_t c = numlist[k]; + int64_t res; + AVInteger ai; + + if (c<=0) + continue; + res = av_rescale_rnd(a,b,c, AV_ROUND_ZERO); + + ai = av_mul_i(av_int2i(a), av_int2i(b)); + ai = av_div_i(ai, av_int2i(c)); + + if (av_cmp_i(ai, av_int2i(INT64_MAX)) > 0 && res == INT64_MIN) + continue; + if (av_cmp_i(ai, av_int2i(INT64_MIN)) < 0 && res == INT64_MIN) + continue; + if (av_cmp_i(ai, av_int2i(res)) == 0) + continue; + + // Special exception for INT64_MIN, remove this in case INT64_MIN is handled without off by 1 error + if (av_cmp_i(ai, av_int2i(res-1)) == 0 && a == INT64_MIN) + continue; + + av_log(NULL, AV_LOG_ERROR, "%"PRId64" * %"PRId64" / %"PRId64" = %"PRId64" or %"PRId64"\n", a,b,c, res, av_i2int(ai)); + } + } + } + + for (a.num = 1; a.num <= 10; a.num++) { + for (a.den = 1; a.den <= 10; a.den++) { + if (av_gcd(a.num, a.den) > 1) + continue; + for (b.num = 1; b.num <= 10; b.num++) { + for (b.den = 1; b.den <= 10; b.den++) { + int start; + if (av_gcd(b.num, b.den) > 1) + continue; + if (av_cmp_q(b, a) < 0) + continue; + for (start = 0; start < 10 ; start++) { + int acc= start; + int i; + + for (i = 0; i<100; i++) { + int exact = start + av_rescale_q(i+1, b, a); + acc = av_add_stable(a, acc, b, 1); + if (FFABS(acc - exact) > 2) { + av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %d\n", a.num, + a.den, b.num, b.den, acc, exact); + return 1; + } + } + } + } + } + } + } + + for (a.den = 1; a.den < 0x100000000U/3; a.den*=3) { + for (a.num = -1; a.num < (1<<27); a.num += 1 + a.num/100) { + float f = av_int2float(av_q2intfloat(a)); + float f2 = av_q2d(a); + if (fabs(f - f2) > fabs(f)/5000000) { + av_log(NULL, AV_LOG_ERROR, "%d/%d %f %f\n", a.num, + a.den, f, f2); + return 1; + } + + } + } + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/ripemd.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/ripemd.c new file mode 100644 index 00000000..58e5fce3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/ripemd.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/mem.h" +#include "libavutil/ripemd.h" + +int main(void) +{ + int i, j, k; + struct AVRIPEMD *ctx; + unsigned char digest[40]; + static const int lengths[4] = { 128, 160, 256, 320 }; + + ctx = av_ripemd_alloc(); + if (!ctx) + return 1; + + for (j = 0; j < 4; j++) { + printf("Testing RIPEMD-%d\n", lengths[j]); + for (k = 0; k < 3; k++) { + av_ripemd_init(ctx, lengths[j]); + if (k == 0) + av_ripemd_update(ctx, "abc", 3); + else if (k == 1) + av_ripemd_update(ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); + else + for (i = 0; i < 1000*1000; i++) + av_ripemd_update(ctx, "a", 1); + av_ripemd_final(ctx, digest); + for (i = 0; i < lengths[j] >> 3; i++) + printf("%02X", digest[i]); + putchar('\n'); + } + switch (j) { //test vectors (from ISO:IEC 10118-3 (2004) and http://homes.esat.kuleuven.be/~bosselae/ripemd160.html) + case 0: + printf("c14a1219 9c66e4ba 84636b0f 69144c77\n" + "a1aa0689 d0fafa2d dc22e88b 49133a06\n" + "4a7f5723 f954eba1 216c9d8f 6320431f\n"); + break; + case 1: + printf("8eb208f7 e05d987a 9b044a8e 98c6b087 f15a0bfc\n" + "12a05338 4a9c0c88 e405a06c 27dcf49a da62eb2b\n" + "52783243 c1697bdb e16d37f9 7f68f083 25dc1528\n"); + break; + case 2: + printf("afbd6e22 8b9d8cbb cef5ca2d 03e6dba1 0ac0bc7d cbe4680e 1e42d2e9 75459b65\n" + "38430455 83aac6c8 c8d91285 73e7a980 9afb2a0f 34ccc36e a9e72f16 f6368e3f\n" + "ac953744 e10e3151 4c150d4d 8d7b6773 42e33399 788296e4 3ae4850c e4f97978\n"); + break; + case 3: + printf("de4c01b3 054f8930 a79d09ae 738e9230 1e5a1708 5beffdc1 b8d11671 3e74f82f a942d64c dbc4682d\n" + "d034a795 0cf72202 1ba4b84d f769a5de 2060e259 df4c9bb4 a4268c0e 935bbc74 70a969c9 d072a1ac\n" + "bdee37f4 371e2064 6b8b0d86 2dda1629 2ae36f40 965e8c85 09e63d1d bddecc50 3e2b63eb 9245bb66\n"); + break; + } + } + av_free(ctx); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/sha.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/sha.c new file mode 100644 index 00000000..a95b3a00 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/sha.c @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/mem.h" +#include "libavutil/sha.h" + +int main(void) +{ + int i, j, k; + struct AVSHA *ctx; + unsigned char digest[32]; + static const int lengths[3] = { 160, 224, 256 }; + + ctx = av_sha_alloc(); + if (!ctx) + return 1; + + for (j = 0; j < 3; j++) { + printf("Testing SHA-%d\n", lengths[j]); + for (k = 0; k < 3; k++) { + av_sha_init(ctx, lengths[j]); + if (k == 0) + av_sha_update(ctx, "abc", 3); + else if (k == 1) + av_sha_update(ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); + else + for (i = 0; i < 1000*1000; i++) + av_sha_update(ctx, "a", 1); + av_sha_final(ctx, digest); + for (i = 0; i < lengths[j] >> 3; i++) + printf("%02X", digest[i]); + putchar('\n'); + } + switch (j) { + case 0: + //test vectors (from FIPS PUB 180-1) + printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n" + "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n" + "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n"); + break; + case 1: + //test vectors (from FIPS PUB 180-2 Appendix A) + printf("23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7\n" + "75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525\n" + "20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67\n"); + break; + case 2: + //test vectors (from FIPS PUB 180-2) + printf("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad\n" + "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1\n" + "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0\n"); + break; + } + } + av_free(ctx); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/sha512.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/sha512.c new file mode 100644 index 00000000..f3b90fdf --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/sha512.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2009 Konstantin Shishkov + * Copyright (C) 2013 James Almer + * based on BSD-licensed SHA-2 code by Aaron D. Gifford + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/mem.h" +#include "libavutil/sha512.h" + +int main(void) +{ + int i, j, k; + struct AVSHA512 *ctx; + unsigned char digest[64]; + static const int lengths[4] = { 224, 256, 384, 512 }; + + ctx = av_sha512_alloc(); + if (!ctx) + return 1; + + for (j = 0; j < 4; j++) { + if (j < 2) printf("Testing SHA-512/%d\n", lengths[j]); + else printf("Testing SHA-%d\n", lengths[j]); + for (k = 0; k < 3; k++) { + av_sha512_init(ctx, lengths[j]); + if (k == 0) + av_sha512_update(ctx, "abc", 3); + else if (k == 1) + av_sha512_update(ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112); + else + for (i = 0; i < 1000*1000; i++) + av_sha512_update(ctx, "a", 1); + av_sha512_final(ctx, digest); + for (i = 0; i < lengths[j] >> 3; i++) + printf("%02X", digest[i]); + putchar('\n'); + } + switch (j) { //test vectors (from FIPS PUB 180-4 Apendix A) + case 0: + printf("4634270f 707b6a54 daae7530 460842e2 0e37ed26 5ceee9a4 3e8924aa\n" + "23fec5bb 94d60b23 30819264 0b0c4533 35d66473 4fe40e72 68674af9\n" + "37ab331d 76f0d36d e422bd0e deb22a28 accd487b 7a8453ae 965dd287\n"); + break; + case 1: + printf("53048e26 81941ef9 9b2e29b7 6b4c7dab e4c2d0c6 34fc6d46 e0e2f131 07e7af23\n" + "3928e184 fb8690f8 40da3988 121d31be 65cb9d3e f83ee614 6feac861 e19b563a\n" + "9a59a052 930187a9 7038cae6 92f30708 aa649192 3ef51943 94dc68d5 6c74fb21\n"); + break; + case 2: + printf("cb00753f 45a35e8b b5a03d69 9ac65007 272c32ab 0eded163 " + "1a8b605a 43ff5bed 8086072b a1e7cc23 58baeca1 34c825a7\n" + "09330c33 f71147e8 3d192fc7 82cd1b47 53111b17 3b3b05d2 " + "2fa08086 e3b0f712 fcc7c71a 557e2db9 66c3e9fa 91746039\n" + "9d0e1809 716474cb 086e834e 310a4a1c ed149e9c 00f24852 " + "7972cec5 704c2a5b 07b8b3dc 38ecc4eb ae97ddd8 7f3d8985\n"); + break; + case 3: + printf("ddaf35a1 93617aba cc417349 ae204131 12e6fa4e 89a97ea2 0a9eeee6 4b55d39a " + "2192992a 274fc1a8 36ba3c23 a3feebbd 454d4423 643ce80e 2a9ac94f a54ca49f\n" + "8e959b75 dae313da 8cf4f728 14fc143f 8f7779c6 eb9f7fa1 7299aead b6889018 " + "501d289e 4900f7e4 331b99de c4b5433a c7d329ee b6dd2654 5e96e55b 874be909\n" + "e718483d 0ce76964 4e2e42c7 bc15b463 8e1f98b1 3b204428 5632a803 afa973eb " + "de0ff244 877ea60a 4cb0432c e577c31b eb009c5c 2c49aa2e 4eadb217 ad8cc09b\n"); + break; + } + } + av_free(ctx); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/softfloat.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/softfloat.c new file mode 100644 index 00000000..c06de449 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/softfloat.c @@ -0,0 +1,158 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/timer.h" + +#include + +#include "libavutil/softfloat.h" +#include "libavutil/common.h" +#include "libavutil/log.h" + +#include + +static const SoftFloat FLOAT_0_017776489257 = {0x1234, 12}; +static const SoftFloat FLOAT_1374_40625 = {0xabcd, 25}; +static const SoftFloat FLOAT_0_1249694824218 = {0xFFF, 15}; + + +int main(void){ + SoftFloat one= av_int2sf(1, 0); + SoftFloat sf1, sf2, sf3; + double d1, d2, d3; + int i, j; + av_log_set_level(AV_LOG_DEBUG); + + d1= 1; + for(i= 0; i<10; i++){ + d1= 1/(d1+1); + } + printf("test1 double=%d\n", (int)(d1 * (1<<24))); + + sf1= one; + for(i= 0; i<10; i++){ + sf1= av_div_sf(one, av_normalize_sf(av_add_sf(one, sf1))); + } + printf("test1 sf =%d\n", av_sf2int(sf1, 24)); + + + for(i= 0; i<100; i++){ + START_TIMER + d1= i; + d2= i/100.0; + for(j= 0; j<1000; j++){ + d1= (d1+1)*d2; + } + STOP_TIMER("float add mul") + } + printf("test2 double=%d\n", (int)(d1 * (1<<24))); + + for(i= 0; i<100; i++){ + START_TIMER + sf1= av_int2sf(i, 0); + sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3)); + for(j= 0; j<1000; j++){ + sf1= av_mul_sf(av_add_sf(sf1, one),sf2); + } + STOP_TIMER("softfloat add mul") + } + printf("test2 sf =%d (%d %d)\n", av_sf2int(sf1, 24), sf1.exp, sf1.mant); + + d1 = 0.0177764893; + d2 = 1374.40625; + d3 = 0.1249694824; + d2 += d1; + d3 += d2; + printf("test3 double: %.10lf\n", d3); + + sf1 = FLOAT_0_017776489257; + sf2 = FLOAT_1374_40625; + sf3 = FLOAT_0_1249694824218; + sf2 = av_add_sf(sf1, sf2); + sf3 = av_add_sf(sf3, sf2); + printf("test3 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf3), sf3.mant, sf3.exp); + + sf1 = av_int2sf(0xFFFFFFF0, 0); + printf("test4 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp); + sf1 = av_int2sf(0x00000010, 0); + printf("test4 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp); + + sf1 = av_int2sf(0x1FFFFFFF, 0); + printf("test4 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp); + sf1 = av_int2sf(0xE0000001, 0); + printf("test4 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp); + + + sf1 = (SoftFloat){ 0x20000000, MIN_EXP }; + sf1 = av_mul_sf(sf1, sf1); + printf("test5 softfloat: %.10lf (0x%08x %d)\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp); + + sf1 = (SoftFloat){ 0x20000000, MIN_EXP }; + sf2 = (SoftFloat){ 0x20000000, MAX_EXP }; + i = av_cmp_sf(sf1, sf2); + j = av_cmp_sf(sf2, sf1); + sf1 = av_div_sf(sf1, sf2); + printf("test6 softfloat: %.10lf (0x%08x %d) %d %d\n", (double)av_sf2double(sf1), sf1.mant, sf1.exp, i, j); + + for(i= -50; i<50; i++) { + sf1= av_int2sf(i, 0); + for(j= -50; j<50; j++) { + int c; + sf2= av_int2sf(j, 0); + c = av_cmp_sf(sf1, sf2); + if (FFDIFFSIGN(i,j) != c && (FFDIFFSIGN(i,j)^c)<0) { + printf("av_cmp_sf failed at %d %d as %X\n", i, j, c); + } + c = av_gt_sf(sf1, sf2); + if ((i>j) != c) { + printf("av_gt_sf failed at %d %d as %X\n", i, j, c); + } + } + sf1 = av_int2sf(1, i); + for(j = -50; j < 50; j++) { + int c; + sf2 = av_int2sf(1, j); + c = av_cmp_sf(sf2, sf1); + if (FFDIFFSIGN(i,j) != c && (FFDIFFSIGN(i,j)^c) < 0) { + printf("av_cmp_sf failed2 at %d %d as %X\n", i, j, c); + } + c = av_gt_sf(sf1, sf2); + if ((i 0.00000002 || fabs(errc) >0.001) { + printf("sincos FAIL %d %f %f %f %f\n", i, (float)s/ (1<<30), (float)c/ (1<<30), sin(i*M_PI/36), cos(i*M_PI/36)); + } + + } + return 0; + +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/tea.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/tea.c new file mode 100644 index 00000000..605bb524 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/tea.c @@ -0,0 +1,115 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/tea.h" + +#define TEA_NUM_TESTS 4 + +// https://github.com/logandrews/TeaCrypt/blob/master/tea/tea_test.go +static const uint8_t tea_test_key[TEA_NUM_TESTS][16] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + } +}; + +static const uint8_t tea_test_pt[TEA_NUM_TESTS][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } +}; + +static const uint8_t tea_test_ct[TEA_NUM_TESTS][8] = { + { 0x41, 0xEA, 0x3A, 0x0A, 0x94, 0xBA, 0xA9, 0x40 }, + { 0x6A, 0x2F, 0x9C, 0xF3, 0xFC, 0xCF, 0x3C, 0x55 }, + { 0xDE, 0xB1, 0xC0, 0xA2, 0x7E, 0x74, 0x5D, 0xB3 }, + { 0x12, 0x6C, 0x6B, 0x92, 0xC0, 0x65, 0x3A, 0x3E } +}; + +static void test_tea(struct AVTEA *ctx, uint8_t *dst, const uint8_t *src, + const uint8_t *ref, int len, uint8_t *iv, int dir, + const char *test) +{ + av_tea_crypt(ctx, dst, src, len, iv, dir); + if (memcmp(dst, ref, 8*len)) { + int i; + printf("%s failed\ngot ", test); + for (i = 0; i < 8*len; i++) + printf("%02x ", dst[i]); + printf("\nexpected "); + for (i = 0; i < 8*len; i++) + printf("%02x ", ref[i]); + printf("\n"); + exit(1); + } +} + +int main(void) +{ + struct AVTEA *ctx; + uint8_t buf[8], iv[8]; + int i; + static const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld"; + uint8_t ct[32]; + uint8_t pl[32]; + + ctx = av_tea_alloc(); + if (!ctx) + return 1; + + for (i = 0; i < TEA_NUM_TESTS; i++) { + av_tea_init(ctx, tea_test_key[i], 64); + + test_tea(ctx, buf, tea_test_pt[i], tea_test_ct[i], 1, NULL, 0, "encryption"); + test_tea(ctx, buf, tea_test_ct[i], tea_test_pt[i], 1, NULL, 1, "decryption"); + + /* encrypt */ + memcpy(iv, "HALLO123", 8); + av_tea_crypt(ctx, ct, src, 4, iv, 0); + + /* decrypt into pl */ + memcpy(iv, "HALLO123", 8); + test_tea(ctx, pl, ct, src, 4, iv, 1, "CBC decryption"); + + memcpy(iv, "HALLO123", 8); + test_tea(ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption"); + } + + printf("Test encryption/decryption success.\n"); + av_free(ctx); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/tree.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/tree.c new file mode 100644 index 00000000..75032289 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/tree.c @@ -0,0 +1,108 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/tree.c" + +#include + +#include "libavutil/common.h" +#include "libavutil/lfg.h" +#include "libavutil/log.h" + +static int check(AVTreeNode *t) +{ + if (t) { + int left = check(t->child[0]); + int right = check(t->child[1]); + + if (left > 999 || right > 999) + return 1000; + if (right - left != t->state) + return 1000; + if (t->state > 1 || t->state < -1) + return 1000; + return FFMAX(left, right) + 1; + } + return 0; +} + +static void print(AVTreeNode *t, int depth) +{ + int i; + for (i = 0; i < depth * 4; i++) + av_log(NULL, AV_LOG_ERROR, " "); + if (t) { + av_log(NULL, AV_LOG_ERROR, "Node %p %2d %p\n", t, t->state, t->elem); + print(t->child[0], depth + 1); + print(t->child[1], depth + 1); + } else + av_log(NULL, AV_LOG_ERROR, "NULL\n"); +} + +static int cmp(const void *a, const void *b) +{ + return (const uint8_t *) a - (const uint8_t *) b; +} + +int main(int argc, char **argv) +{ + int i; + void *k; + AVTreeNode *root = NULL, *node = NULL; + AVLFG prng; + int log_level = argc <= 1 ? AV_LOG_INFO : atoi(argv[1]); + + av_log_set_level(log_level); + + av_lfg_init(&prng, 1); + + for (i = 0; i < 10000; i++) { + intptr_t j = av_lfg_get(&prng) % 86294; + + if (check(root) > 999) { + av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i); + print(root, 0); + return 1; + } + av_log(NULL, AV_LOG_DEBUG, "inserting %4d\n", (int)j); + + if (!node) + node = av_tree_node_alloc(); + if (!node) { + av_log(NULL, AV_LOG_ERROR, "Memory allocation failure.\n"); + return 1; + } + av_tree_insert(&root, (void *)(j + 1), cmp, &node); + + j = av_lfg_get(&prng) % 86294; + { + AVTreeNode *node2 = NULL; + av_log(NULL, AV_LOG_DEBUG, "removing %4d\n", (int)j); + av_tree_insert(&root, (void *)(j + 1), cmp, &node2); + k = av_tree_find(root, (void *)(j + 1), cmp, NULL); + if (k) + av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i); + av_free(node2); + } + } + av_free(node); + + av_tree_destroy(root); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/twofish.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/twofish.c new file mode 100644 index 00000000..a4ccbfd3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/twofish.c @@ -0,0 +1,105 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/log.h" +#include "libavutil/mem.h" +#include "libavutil/twofish.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + uint8_t Key[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }; + const uint8_t rct[6][16] = { + {0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a}, + {0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf, 0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48}, + {0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8, 0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20}, + {0x5d, 0x9d, 0x4e, 0xef, 0xfa, 0x91, 0x51, 0x57, 0x55, 0x24, 0xf1, 0x15, 0x81, 0x5a, 0x12, 0xe0}, + {0xe7, 0x54, 0x49, 0x21, 0x2b, 0xee, 0xf9, 0xf4, 0xa3, 0x90, 0xbd, 0x86, 0x0a, 0x64, 0x09, 0x41}, + {0x37, 0xfe, 0x26, 0xff, 0x1c, 0xf6, 0x61, 0x75, 0xf5, 0xdd, 0xf4, 0xc3, 0x3b, 0x97, 0xa2, 0x05} + }; + uint8_t temp[32], iv[16], rpt[32] = {0}; + const int kbits[3] = {128, 192, 256}; + int i, j, k, err = 0; + struct AVTWOFISH *cs; + cs = av_twofish_alloc(); + if (!cs) + return 1; + for (j = 1; j < 3; j++) { + av_twofish_init(cs, Key, kbits[j]); + av_twofish_crypt(cs, temp, rpt, 1, NULL, 0); + for (i = 0; i < 16; i++) { + if (rct[j][i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]); + err = 1; + } + } + av_twofish_crypt(cs, temp, rct[j], 1, NULL, 1); + for (i = 0; i < 16; i++) { + if (rpt[i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]); + err = 1; + } + } + } + for (j = 0; j < 3; j++) { + memset(Key, 0, sizeof(Key)); + memset(rpt, 0, sizeof(rpt)); + for (i = 1; i < 50; i++) { + av_twofish_init(cs, Key, kbits[j]); + av_twofish_crypt(cs, temp, rpt, 1, NULL, 0); + memcpy(Key+16,Key,(kbits[j]-128) >> 3); + memcpy(Key,rpt,16); + memcpy(rpt,temp,16); + av_twofish_crypt(cs, temp, temp, 1, NULL, 1); + for (k = 0; k < 16; k++) { + // Need to compare to Key here, because the plaintext comes + // from rpt but was moved over to Key. + if (Key[k] != temp[k]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", k, Key[k], temp[k]); + err = 1; + } + } + } + for (i = 0; i < 16; i++) { + if (rct[3 + j][i] != rpt[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[3 + j][i], rpt[i]); + err = 1; + } + } + } + memset(rpt, 0, sizeof(rpt)); + memcpy(iv, "HALLO123HALLO123", 16); + av_twofish_crypt(cs, temp, rpt, 2, iv, 0); + memcpy(iv, "HALLO123HALLO123", 16); + av_twofish_crypt(cs, temp, temp, 2, iv, 1); + for (i = 0; i < 32; i++) { + if (rpt[i] != temp[i]) { + av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]); + err = 1; + } + } + av_free(cs); + return err; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/utf8.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/utf8.c new file mode 100644 index 00000000..37a2802b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/utf8.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 Stefano Sabatini + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avstring.h" +#include "libavutil/file.h" + +static void print_sequence(const char *p, int l, int indent) +{ + int i; + for (i = 0; i < l; i++) + printf("%02X", (uint8_t)p[i]); + printf("%*s", indent-l*2, ""); +} + +int main(int argc, char **argv) +{ + int ret; + char *filename = argv[1]; + uint8_t *file_buf; + size_t file_buf_size; + uint32_t code; + const uint8_t *p, *endp; + + ret = av_file_map(filename, &file_buf, &file_buf_size, 0, NULL); + if (ret < 0) + return 1; + + p = file_buf; + endp = file_buf + file_buf_size; + while (p < endp) { + int l, r; + const uint8_t *p0 = p; + code = UINT32_MAX; + r = av_utf8_decode(&code, &p, endp, 0); + l = (int)(p-p0); + print_sequence(p0, l, 20); + if (code != UINT32_MAX) { + printf("%-10d 0x%-10X %-5d ", code, code, l); + if (r >= 0) { + if (*p0 == '\n') printf("\\n\n"); + else printf ("%.*s\n", l, p0); + } else { + printf("invalid code range\n"); + } + } else { + printf("invalid sequence\n"); + } + } + + av_file_unmap(file_buf, file_buf_size); + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/uuid.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/uuid.c new file mode 100644 index 00000000..ff688be0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/uuid.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2022 Pierre-Anthony Lemieux + * Zane van Iperen + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/uuid.h" +#include "libavutil/log.h" + +static const char *UUID_1 = "6021b21e-894e-43ff-8317-1ca891c1c49b"; +static const char *UUID_1_UC = "6021B21E-894E-43FF-8317-1CA891C1C49B"; +static const char *UUID_1_MIXED = "6021b21e-894E-43fF-8317-1CA891C1c49b"; +static const char *UUID_1_URN = "urn:uuid:6021b21e-894e-43ff-8317-1ca891c1c49b"; +static const AVUUID UUID_1_BYTES = {0x60, 0x21, 0xb2, 0x1e, 0x89, 0x4e, 0x43, 0xff, + 0x83, 0x17, 0x1c, 0xa8, 0x91, 0xc1, 0xc4, 0x9b}; + +static const AVUUID UUID_NIL = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static const char *UUID_BAD_1 = "16a2c9f8-afbc-4767-8621-8cb2b27599"; +static const char *UUID_BAD_2 = "75df62c2999b4bd38c9d8058fcde9123"; +static const char *UUID_BAD_3 = "a1b9a05e-f1d1-464g-a951-1ba0a374f02"; +static const char *UUID_BAD_4 = "279c66d432-7b39-41d5-966f-5e8138265c20"; + +int main(int argc, char **argv) +{ + AVUUID uuid; + AVUUID uuid2 = {0x32, 0xc7, 0x00, 0xc4, 0xd5, 0xd7, 0x42, 0x0, + 0x93, 0xc0, 0x3b, 0x6d, 0xea, 0x1b, 0x20, 0x5b}; + + /* test parsing */ + + if (av_uuid_parse(UUID_1, uuid)) + return 1; + + if (!av_uuid_equal(uuid, UUID_1_BYTES)) + return 1; + + /* test nil */ + + av_uuid_nil(uuid); + + if (!av_uuid_equal(uuid, UUID_NIL)) + return 1; + + /* test equality */ + + if (av_uuid_equal(UUID_1_BYTES, uuid2)) + return 1; + + /* test copy */ + + av_uuid_copy(uuid2, UUID_1_BYTES); + + if (!av_uuid_equal(uuid2, UUID_1_BYTES)) + return 1; + + /* test uppercase parsing */ + + if (av_uuid_parse(UUID_1_UC, uuid)) + return 1; + + if (!av_uuid_equal(uuid, UUID_1_BYTES)) + return 1; + + /* test mixed-case parsing */ + + if (av_uuid_parse(UUID_1_MIXED, uuid)) + return 1; + + if (!av_uuid_equal(uuid, UUID_1_BYTES)) + return 1; + + /* test URN uuid parse */ + + if (av_uuid_urn_parse(UUID_1_URN, uuid)) + return 1; + + if (!av_uuid_equal(uuid, UUID_1_BYTES)) + return 1; + + /* test parse range */ + + if (av_uuid_parse_range(UUID_1_URN + 9, UUID_1_URN + 45, uuid)) + return 1; + + if (!av_uuid_equal(uuid, UUID_1_BYTES)) + return 1; + + /* test bad parse range */ + + if (!av_uuid_parse_range(UUID_1_URN + 9, UUID_1_URN + 44, uuid)) + return 1; + + /* test bad parse range 2 */ + + if (!av_uuid_parse_range(UUID_1_URN + 8, UUID_1_URN + 44, uuid)) + return 1; + + /* test bad parse range 2 */ + + if (!av_uuid_parse_range(UUID_1_URN + 8, UUID_1_URN + 45, uuid)) + return 1; + + /* test bad uuid 1 */ + + if (!av_uuid_parse(UUID_BAD_1, uuid)) + return 1; + + /* test bad uuid 2 */ + + if (!av_uuid_parse(UUID_BAD_2, uuid)) + return 1; + + /* test bad uuid 3 */ + + if (!av_uuid_parse(UUID_BAD_3, uuid)) + return 1; + + /* test bad uuid 4 */ + + if (!av_uuid_parse(UUID_BAD_4, uuid)) + return 1; + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tests/xtea.c b/arm/raspi/third_party/ffmpeg/libavutil/tests/xtea.c new file mode 100644 index 00000000..6a8c6475 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tests/xtea.c @@ -0,0 +1,125 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" +#include "libavutil/xtea.h" + +#define XTEA_NUM_TESTS 6 + +static const uint8_t xtea_test_key[XTEA_NUM_TESTS][16] = { + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const uint8_t xtea_test_pt[XTEA_NUM_TESTS][8] = { + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } +}; + +static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = { + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } +}; + +static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + const uint8_t *ref, int len, uint8_t *iv, int dir, + const char *test, + void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *, int)) +{ + crypt(ctx, dst, src, len, iv, dir); + if (memcmp(dst, ref, 8*len)) { + int i; + printf("%s failed\ngot ", test); + for (i = 0; i < 8*len; i++) + printf("%02x ", dst[i]); + printf("\nexpected "); + for (i = 0; i < 8*len; i++) + printf("%02x ", ref[i]); + printf("\n"); + exit(1); + } +} + +int main(void) +{ + uint8_t buf[16], iv[8]; + int i, j; + static const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld"; + uint8_t ct[32]; + uint8_t pl[32]; + AVXTEA *ctx = av_xtea_alloc(); + if (!ctx) + return 1; + + for (i = 0; i < XTEA_NUM_TESTS; i++) { + av_xtea_init(ctx, xtea_test_key[i]); + + test_xtea(ctx, buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "encryption", av_xtea_crypt); + test_xtea(ctx, buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "decryption", av_xtea_crypt); + + for (j = 0; j < 4; j++) + AV_WL32(&buf[4*j], AV_RB32(&xtea_test_key[i][4*j])); + av_xtea_le_init(ctx, buf); + for (j = 0; j < 2; j++) { + AV_WL32(&ct[4*j], AV_RB32(&xtea_test_ct[i][4*j])); + AV_WL32(&pl[4*j], AV_RB32(&xtea_test_pt[i][4*j])); + } + test_xtea(ctx, buf, pl, ct, 1, NULL, 0, "encryption", av_xtea_le_crypt); + test_xtea(ctx, buf, ct, pl, 1, NULL, 1, "decryption", av_xtea_le_crypt); + + /* encrypt */ + memcpy(iv, "HALLO123", 8); + av_xtea_crypt(ctx, ct, src, 4, iv, 0); + + /* decrypt into pl */ + memcpy(iv, "HALLO123", 8); + test_xtea(ctx, pl, ct, src, 4, iv, 1, "CBC decryption", av_xtea_crypt); + + memcpy(iv, "HALLO123", 8); + test_xtea(ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption", av_xtea_crypt); + } + + printf("Test encryption/decryption success.\n"); + av_free(ctx); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/thread.h b/arm/raspi/third_party/ffmpeg/libavutil/thread.h new file mode 100644 index 00000000..2f5e7e1c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/thread.h @@ -0,0 +1,204 @@ +/* + * 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 + */ + +// This header should only be used to simplify code where +// threading is optional, not as a generic threading abstraction. + +#ifndef AVUTIL_THREAD_H +#define AVUTIL_THREAD_H + +#include "config.h" + +#if HAVE_PRCTL +#include +#endif + +#include "error.h" + +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS + +#if HAVE_PTHREADS +#include + +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 + +#include + +#include "log.h" +#include "macros.h" + +#define ASSERT_PTHREAD_ABORT(func, ret) do { \ + char errbuf[AV_ERROR_MAX_STRING_SIZE] = ""; \ + av_log(NULL, AV_LOG_FATAL, AV_STRINGIFY(func) \ + " failed with error: %s\n", \ + av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, \ + AVERROR(ret))); \ + abort(); \ +} while (0) + +#define ASSERT_PTHREAD_NORET(func, ...) do { \ + int ret = func(__VA_ARGS__); \ + if (ret) \ + ASSERT_PTHREAD_ABORT(func, ret); \ +} while (0) + +#define ASSERT_PTHREAD(func, ...) do { \ + ASSERT_PTHREAD_NORET(func, __VA_ARGS__); \ + return 0; \ +} while (0) + +static inline int strict_pthread_join(pthread_t thread, void **value_ptr) +{ + ASSERT_PTHREAD(pthread_join, thread, value_ptr); +} + +static inline int strict_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + if (attr) { + ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, attr); + } else { + pthread_mutexattr_t local_attr; + ASSERT_PTHREAD_NORET(pthread_mutexattr_init, &local_attr); + ASSERT_PTHREAD_NORET(pthread_mutexattr_settype, &local_attr, PTHREAD_MUTEX_ERRORCHECK); + ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, &local_attr); + ASSERT_PTHREAD_NORET(pthread_mutexattr_destroy, &local_attr); + } + return 0; +} + +static inline int strict_pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_destroy, mutex); +} + +static inline int strict_pthread_mutex_lock(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_lock, mutex); +} + +static inline int strict_pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_unlock, mutex); +} + +static inline int strict_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + ASSERT_PTHREAD(pthread_cond_init, cond, attr); +} + +static inline int strict_pthread_cond_destroy(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_destroy, cond); +} + +static inline int strict_pthread_cond_signal(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_signal, cond); +} + +static inline int strict_pthread_cond_broadcast(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_broadcast, cond); +} + +static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); +} + +static inline int strict_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + int ret = pthread_cond_timedwait(cond, mutex, abstime); + if (ret && ret != ETIMEDOUT) + ASSERT_PTHREAD_ABORT(pthread_cond_timedwait, ret); + return ret; +} + +static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + ASSERT_PTHREAD(pthread_once, once_control, init_routine); +} + +#define pthread_join strict_pthread_join +#define pthread_mutex_init strict_pthread_mutex_init +#define pthread_mutex_destroy strict_pthread_mutex_destroy +#define pthread_mutex_lock strict_pthread_mutex_lock +#define pthread_mutex_unlock strict_pthread_mutex_unlock +#define pthread_cond_init strict_pthread_cond_init +#define pthread_cond_destroy strict_pthread_cond_destroy +#define pthread_cond_signal strict_pthread_cond_signal +#define pthread_cond_broadcast strict_pthread_cond_broadcast +#define pthread_cond_wait strict_pthread_cond_wait +#define pthread_cond_timedwait strict_pthread_cond_timedwait +#define pthread_once strict_pthread_once +#endif + +#elif HAVE_OS2THREADS +#include "compat/os2threads.h" +#else +#include "compat/w32pthreads.h" +#endif + +#define AVMutex pthread_mutex_t +#define AV_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define ff_mutex_init pthread_mutex_init +#define ff_mutex_lock pthread_mutex_lock +#define ff_mutex_unlock pthread_mutex_unlock +#define ff_mutex_destroy pthread_mutex_destroy + +#define AVOnce pthread_once_t +#define AV_ONCE_INIT PTHREAD_ONCE_INIT + +#define ff_thread_once(control, routine) pthread_once(control, routine) + +#else + +#define AVMutex char +#define AV_MUTEX_INITIALIZER 0 + +static inline int ff_mutex_init(AVMutex *mutex, const void *attr){ return 0; } +static inline int ff_mutex_lock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_unlock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_destroy(AVMutex *mutex){ return 0; } + +#define AVOnce char +#define AV_ONCE_INIT 0 + +static inline int ff_thread_once(char *control, void (*routine)(void)) +{ + if (!*control) { + routine(); + *control = 1; + } + return 0; +} + +#endif + +static inline int ff_thread_setname(const char *name) +{ +#if HAVE_PRCTL + return AVERROR(prctl(PR_SET_NAME, name)); +#endif + + return AVERROR(ENOSYS); +} + +#endif /* AVUTIL_THREAD_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.c b/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.c new file mode 100644 index 00000000..f0e23f28 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2014 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "fifo.h" +#include "mem.h" +#include "threadmessage.h" +#include "thread.h" + +struct AVThreadMessageQueue { +#if HAVE_THREADS + AVFifo *fifo; + pthread_mutex_t lock; + pthread_cond_t cond_recv; + pthread_cond_t cond_send; + int err_send; + int err_recv; + unsigned elsize; + void (*free_func)(void *msg); +#else + int dummy; +#endif +}; + +int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, + unsigned nelem, + unsigned elsize) +{ +#if HAVE_THREADS + AVThreadMessageQueue *rmq; + int ret = 0; + + if (nelem > INT_MAX / elsize) + return AVERROR(EINVAL); + if (!(rmq = av_mallocz(sizeof(*rmq)))) + return AVERROR(ENOMEM); + if ((ret = pthread_mutex_init(&rmq->lock, NULL))) { + av_free(rmq); + return AVERROR(ret); + } + if ((ret = pthread_cond_init(&rmq->cond_recv, NULL))) { + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ret); + } + if ((ret = pthread_cond_init(&rmq->cond_send, NULL))) { + pthread_cond_destroy(&rmq->cond_recv); + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ret); + } + if (!(rmq->fifo = av_fifo_alloc2(nelem, elsize, 0))) { + pthread_cond_destroy(&rmq->cond_send); + pthread_cond_destroy(&rmq->cond_recv); + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ENOMEM); + } + rmq->elsize = elsize; + *mq = rmq; + return 0; +#else + *mq = NULL; + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, + void (*free_func)(void *msg)) +{ +#if HAVE_THREADS + mq->free_func = free_func; +#endif +} + +void av_thread_message_queue_free(AVThreadMessageQueue **mq) +{ +#if HAVE_THREADS + if (*mq) { + av_thread_message_flush(*mq); + av_fifo_freep2(&(*mq)->fifo); + pthread_cond_destroy(&(*mq)->cond_send); + pthread_cond_destroy(&(*mq)->cond_recv); + pthread_mutex_destroy(&(*mq)->lock); + av_freep(mq); + } +#endif +} + +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq) +{ +#if HAVE_THREADS + int ret; + pthread_mutex_lock(&mq->lock); + ret = av_fifo_can_read(mq->fifo); + pthread_mutex_unlock(&mq->lock); + return ret; +#else + return AVERROR(ENOSYS); +#endif +} + +#if HAVE_THREADS + +static int av_thread_message_queue_send_locked(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ + while (!mq->err_send && !av_fifo_can_write(mq->fifo)) { + if ((flags & AV_THREAD_MESSAGE_NONBLOCK)) + return AVERROR(EAGAIN); + pthread_cond_wait(&mq->cond_send, &mq->lock); + } + if (mq->err_send) + return mq->err_send; + av_fifo_write(mq->fifo, msg, 1); + /* one message is sent, signal one receiver */ + pthread_cond_signal(&mq->cond_recv); + return 0; +} + +static int av_thread_message_queue_recv_locked(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ + while (!mq->err_recv && !av_fifo_can_read(mq->fifo)) { + if ((flags & AV_THREAD_MESSAGE_NONBLOCK)) + return AVERROR(EAGAIN); + pthread_cond_wait(&mq->cond_recv, &mq->lock); + } + if (!av_fifo_can_read(mq->fifo)) + return mq->err_recv; + av_fifo_read(mq->fifo, msg, 1); + /* one message space appeared, signal one sender */ + pthread_cond_signal(&mq->cond_send); + return 0; +} + +#endif /* HAVE_THREADS */ + +int av_thread_message_queue_send(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ +#if HAVE_THREADS + int ret; + + pthread_mutex_lock(&mq->lock); + ret = av_thread_message_queue_send_locked(mq, msg, flags); + pthread_mutex_unlock(&mq->lock); + return ret; +#else + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +int av_thread_message_queue_recv(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ +#if HAVE_THREADS + int ret; + + pthread_mutex_lock(&mq->lock); + ret = av_thread_message_queue_recv_locked(mq, msg, flags); + pthread_mutex_unlock(&mq->lock); + return ret; +#else + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, + int err) +{ +#if HAVE_THREADS + pthread_mutex_lock(&mq->lock); + mq->err_send = err; + pthread_cond_broadcast(&mq->cond_send); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, + int err) +{ +#if HAVE_THREADS + pthread_mutex_lock(&mq->lock); + mq->err_recv = err; + pthread_cond_broadcast(&mq->cond_recv); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} + +#if HAVE_THREADS +static int free_func_wrap(void *arg, void *buf, size_t *nb_elems) +{ + AVThreadMessageQueue *mq = arg; + uint8_t *msg = buf; + for (size_t i = 0; i < *nb_elems; i++) + mq->free_func(msg + i * mq->elsize); + return 0; +} +#endif + +void av_thread_message_flush(AVThreadMessageQueue *mq) +{ +#if HAVE_THREADS + size_t used; + + pthread_mutex_lock(&mq->lock); + used = av_fifo_can_read(mq->fifo); + if (mq->free_func) + av_fifo_read_to_cb(mq->fifo, free_func_wrap, mq, &used); + /* only the senders need to be notified since the queue is empty and there + * is nothing to read */ + pthread_cond_broadcast(&mq->cond_send); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.h b/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.h new file mode 100644 index 00000000..42ce655f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/threadmessage.h @@ -0,0 +1,115 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_THREADMESSAGE_H +#define AVUTIL_THREADMESSAGE_H + +typedef struct AVThreadMessageQueue AVThreadMessageQueue; + +typedef enum AVThreadMessageFlags { + + /** + * Perform non-blocking operation. + * If this flag is set, send and recv operations are non-blocking and + * return AVERROR(EAGAIN) immediately if they can not proceed. + */ + AV_THREAD_MESSAGE_NONBLOCK = 1, + +} AVThreadMessageFlags; + +/** + * Allocate a new message queue. + * + * @param mq pointer to the message queue + * @param nelem maximum number of elements in the queue + * @param elsize size of each element in the queue + * @return >=0 for success; <0 for error, in particular AVERROR(ENOSYS) if + * lavu was built without thread support + */ +int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, + unsigned nelem, + unsigned elsize); + +/** + * Free a message queue. + * + * The message queue must no longer be in use by another thread. + */ +void av_thread_message_queue_free(AVThreadMessageQueue **mq); + +/** + * Send a message on the queue. + */ +int av_thread_message_queue_send(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Receive a message from the queue. + */ +int av_thread_message_queue_recv(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Set the sending error code. + * + * If the error code is set to non-zero, av_thread_message_queue_send() will + * return it immediately. Conventional values, such as AVERROR_EOF or + * AVERROR(EAGAIN), can be used to cause the sending thread to stop or + * suspend its operation. + */ +void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, + int err); + +/** + * Set the receiving error code. + * + * If the error code is set to non-zero, av_thread_message_queue_recv() will + * return it immediately when there are no longer available messages. + * Conventional values, such as AVERROR_EOF or AVERROR(EAGAIN), can be used + * to cause the receiving thread to stop or suspend its operation. + */ +void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, + int err); + +/** + * Set the optional free message callback function which will be called if an + * operation is removing messages from the queue. + */ +void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, + void (*free_func)(void *msg)); + +/** + * Return the current number of messages in the queue. + * + * @return the current number of messages or AVERROR(ENOSYS) if lavu was built + * without thread support + */ +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq); + +/** + * Flush the message queue + * + * This function is mostly equivalent to reading and free-ing every message + * except that it will be done in a single operation (no lock/unlock between + * reads). + */ +void av_thread_message_flush(AVThreadMessageQueue *mq); + +#endif /* AVUTIL_THREADMESSAGE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/time.c b/arm/raspi/third_party/ffmpeg/libavutil/time.c new file mode 100644 index 00000000..740afc47 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/time.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2000-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 + */ + +#include "config.h" + +#include +#include +#include +#if HAVE_GETTIMEOFDAY +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_WINDOWS_H +#include +#endif + +#include "time.h" +#include "error.h" + +int64_t av_gettime(void) +{ +#if HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +#elif HAVE_GETSYSTEMTIMEASFILETIME + FILETIME ft; + int64_t t; + GetSystemTimeAsFileTime(&ft); + t = (int64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime; + return t / 10 - 11644473600000000; /* Jan 1, 1601 */ +#else + return -1; +#endif +} + +int64_t av_gettime_relative(void) +{ +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) +#ifdef __APPLE__ + if (&clock_gettime) +#endif + { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + } +#endif + return av_gettime() + 42 * 60 * 60 * INT64_C(1000000); +} + +int av_gettime_relative_is_monotonic(void) +{ +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) +#ifdef __APPLE__ + if (!&clock_gettime) + return 0; +#endif + return 1; +#else + return 0; +#endif +} + +int av_usleep(unsigned usec) +{ +#if HAVE_NANOSLEEP + struct timespec ts = { usec / 1000000, usec % 1000000 * 1000 }; + while (nanosleep(&ts, &ts) < 0 && errno == EINTR); + return 0; +#elif HAVE_USLEEP + return usleep(usec); +#elif HAVE_SLEEP + Sleep(usec / 1000); + return 0; +#else + return AVERROR(ENOSYS); +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/time.h b/arm/raspi/third_party/ffmpeg/libavutil/time.h new file mode 100644 index 00000000..dc169b06 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/time.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000-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 + */ + +#ifndef AVUTIL_TIME_H +#define AVUTIL_TIME_H + +#include + +/** + * Get the current time in microseconds. + */ +int64_t av_gettime(void); + +/** + * Get the current time in microseconds since some unspecified starting point. + * On platforms that support it, the time comes from a monotonic clock + * This property makes this time source ideal for measuring relative time. + * The returned values may not be monotonic on platforms where a monotonic + * clock is not available. + */ +int64_t av_gettime_relative(void); + +/** + * Indicates with a boolean result if the av_gettime_relative() time source + * is monotonic. + */ +int av_gettime_relative_is_monotonic(void); + +/** + * Sleep for a period of time. Although the duration is expressed in + * microseconds, the actual delay may be rounded to the precision of the + * system timer. + * + * @param usec Number of microseconds to sleep. + * @return zero on success or (negative) error code. + */ +int av_usleep(unsigned usec); + +#endif /* AVUTIL_TIME_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/time_internal.h b/arm/raspi/third_party/ffmpeg/libavutil/time_internal.h new file mode 100644 index 00000000..d0f007ab --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/time_internal.h @@ -0,0 +1,49 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TIME_INTERNAL_H +#define AVUTIL_TIME_INTERNAL_H + +#include +#include "config.h" + +#if !HAVE_GMTIME_R && !defined(gmtime_r) +static inline struct tm *ff_gmtime_r(const time_t* clock, struct tm *result) +{ + struct tm *ptr = gmtime(clock); + if (!ptr) + return NULL; + *result = *ptr; + return result; +} +#define gmtime_r ff_gmtime_r +#endif + +#if !HAVE_LOCALTIME_R && !defined(localtime_r) +static inline struct tm *ff_localtime_r(const time_t* clock, struct tm *result) +{ + struct tm *ptr = localtime(clock); + if (!ptr) + return NULL; + *result = *ptr; + return result; +} +#define localtime_r ff_localtime_r +#endif + +#endif /* AVUTIL_TIME_INTERNAL_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/timecode.c b/arm/raspi/third_party/ffmpeg/libavutil/timecode.c new file mode 100644 index 00000000..b93f05b4 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/timecode.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier + * Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch + * + * 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 + * Timecode helpers + * @see https://en.wikipedia.org/wiki/SMPTE_time_code + * @see http://www.dropframetimecode.org + */ + +#include +#include "common.h" +#include "timecode.h" +#include "log.h" +#include "error.h" + +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) +{ + /* only works for multiples of NTSC 29.97 */ + int drop_frames = 0; + int d, m, frames_per_10mins; + + if (fps && fps % 30 == 0) { + drop_frames = fps / 30 * 2; + frames_per_10mins = fps / 30 * 17982; + } else + return framenum; + + d = framenum / frames_per_10mins; + m = framenum % frames_per_10mins; + + return framenum + 9U * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10)); +} + +uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) +{ + unsigned fps = tc->fps; + int drop = !!(tc->flags & AV_TIMECODE_FLAG_DROPFRAME); + int hh, mm, ss, ff; + + framenum += tc->start; + if (drop) + framenum = av_timecode_adjust_ntsc_framenum2(framenum, tc->fps); + ff = framenum % fps; + ss = framenum / fps % 60; + mm = framenum / (fps*60) % 60; + hh = framenum / (fps*3600) % 24; + return av_timecode_get_smpte(tc->rate, drop, hh, mm, ss, ff); +} + +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff) +{ + uint32_t tc = 0; + + /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS. + See SMPTE ST 12-1:2014 Sec 12.1 for more info. */ + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + if (ff % 2 == 1) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + tc |= (1 << 7); + else + tc |= (1 << 23); + } + ff /= 2; + } + + hh = hh % 24; + mm = av_clip(mm, 0, 59); + ss = av_clip(ss, 0, 59); + ff = ff % 40; + + tc |= drop << 30; + tc |= (ff / 10) << 28; + tc |= (ff % 10) << 24; + tc |= (ss / 10) << 20; + tc |= (ss % 10) << 16; + tc |= (mm / 10) << 12; + tc |= (mm % 10) << 8; + tc |= (hh / 10) << 4; + tc |= (hh % 10); + + return tc; +} + +char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) +{ + int fps = tc->fps; + int drop = tc->flags & AV_TIMECODE_FLAG_DROPFRAME; + int hh, mm, ss, ff, ff_len, neg = 0; + + framenum += tc->start; + if (drop) + framenum = av_timecode_adjust_ntsc_framenum2(framenum, fps); + if (framenum < 0) { + framenum = -framenum; + neg = tc->flags & AV_TIMECODE_FLAG_ALLOWNEGATIVE; + } + ff = framenum % fps; + ss = framenum / fps % 60; + mm = framenum / (fps*60LL) % 60; + hh = framenum / (fps*3600LL); + if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX) + hh = hh % 24; + ff_len = fps > 10000 ? 5 : fps > 1000 ? 4 : fps > 100 ? 3 : fps > 10 ? 2 : 1; + snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%0*d", + neg ? "-" : "", + hh, mm, ss, drop ? ';' : ':', ff_len, ff); + return buf; +} + +static unsigned bcd2uint(uint8_t bcd) +{ + unsigned low = bcd & 0xf; + unsigned high = bcd >> 4; + if (low > 9 || high > 9) + return 0; + return low + 10*high; +} + +char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field) +{ + unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours + unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes + unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds + unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames + unsigned drop = tcsmpte & 1<<30 && !prevent_df; // 1-bit drop if not arbitrary bit + + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + ff <<= 1; + if (!skip_field) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + ff += !!(tcsmpte & 1 << 7); + else + ff += !!(tcsmpte & 1 << 23); + } + } + + snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u", + hh, mm, ss, drop ? ';' : ':', ff); + return buf; + +} + +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df) +{ + return av_timecode_make_smpte_tc_string2(buf, (AVRational){30, 1}, tcsmpte, prevent_df, 1); +} + +char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit) +{ + snprintf(buf, AV_TIMECODE_STR_SIZE, + "%02"PRIu32":%02"PRIu32":%02"PRIu32"%c%02"PRIu32, + tc25bit>>19 & 0x1f, // 5-bit hours + tc25bit>>13 & 0x3f, // 6-bit minutes + tc25bit>>6 & 0x3f, // 6-bit seconds + tc25bit & 1<<24 ? ';' : ':', // 1-bit drop flag + tc25bit & 0x3f); // 6-bit frames + return buf; +} + +static int check_fps(int fps) +{ + int i; + static const int supported_fps[] = { + 24, 25, 30, 48, 50, 60, 100, 120, 150, + }; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_fps); i++) + if (fps == supported_fps[i]) + return 0; + return -1; +} + +static int check_timecode(void *log_ctx, AVTimecode *tc) +{ + if ((int)tc->fps <= 0) { + av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n"); + return AVERROR(EINVAL); + } + if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps % 30 != 0) { + av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with multiples of 30000/1001 FPS\n"); + return AVERROR(EINVAL); + } + if (check_fps(tc->fps) < 0) { + av_log(log_ctx, AV_LOG_WARNING, "Using non-standard frame rate %d/%d\n", + tc->rate.num, tc->rate.den); + } + return 0; +} + +static int fps_from_frame_rate(AVRational rate) +{ + if (!rate.den || !rate.num) + return -1; + return (rate.num + rate.den/2) / rate.den; +} + +int av_timecode_check_frame_rate(AVRational rate) +{ + return check_fps(fps_from_frame_rate(rate)); +} + +int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx) +{ + memset(tc, 0, sizeof(*tc)); + tc->start = frame_start; + tc->flags = flags; + tc->rate = rate; + tc->fps = fps_from_frame_rate(rate); + return check_timecode(log_ctx, tc); +} + +int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx) +{ + int ret; + + memset(tc, 0, sizeof(*tc)); + tc->flags = flags; + tc->rate = rate; + tc->fps = fps_from_frame_rate(rate); + + ret = check_timecode(log_ctx, tc); + if (ret < 0) + return ret; + + tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; + if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ + int tmins = 60*hh + mm; + tc->start -= (tc->fps / 30 * 2) * (tmins - tmins/10); + } + return 0; +} + +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx) +{ + char c; + int hh, mm, ss, ff, flags; + + if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { + av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, " + "syntax: hh:mm:ss[:;.]ff\n"); + return AVERROR_INVALIDDATA; + } + flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ... + + return av_timecode_init_from_components(tc, rate, flags, hh, mm, ss, ff, log_ctx); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/timecode.h b/arm/raspi/third_party/ffmpeg/libavutil/timecode.h new file mode 100644 index 00000000..060574a1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/timecode.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier + * Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch + * + * 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 + * Timecode helpers header + */ + +#ifndef AVUTIL_TIMECODE_H +#define AVUTIL_TIMECODE_H + +#include +#include "rational.h" + +#define AV_TIMECODE_STR_SIZE 23 + +enum AVTimecodeFlag { + AV_TIMECODE_FLAG_DROPFRAME = 1<<0, ///< timecode is drop frame + AV_TIMECODE_FLAG_24HOURSMAX = 1<<1, ///< timecode wraps after 24 hours + AV_TIMECODE_FLAG_ALLOWNEGATIVE = 1<<2, ///< negative time values are allowed +}; + +typedef struct { + int start; ///< timecode frame start (first base frame number) + uint32_t flags; ///< flags such as drop frame, +24 hours support, ... + AVRational rate; ///< frame rate in rational form + unsigned fps; ///< frame per second; must be consistent with the rate field +} AVTimecode; + +/** + * Adjust frame number for NTSC drop frame time code. + * + * @param framenum frame number to adjust + * @param fps frame per second, multiples of 30 + * @return adjusted frame number + * @warning adjustment is only valid for multiples of NTSC 29.97 + */ +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); + +/** + * Convert frame number to SMPTE 12M binary representation. + * + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the SMPTE binary representation + * + * See SMPTE ST 314M-2005 Sec 4.4.2.2.1 "Time code pack (TC)" + * the format description as follows: + * bits 0-5: hours, in BCD(6bits) + * bits 6: BGF1 + * bits 7: BGF2 (NTSC) or FIELD (PAL) + * bits 8-14: minutes, in BCD(7bits) + * bits 15: BGF0 (NTSC) or BGF2 (PAL) + * bits 16-22: seconds, in BCD(7bits) + * bits 23: FIELD (NTSC) or BGF0 (PAL) + * bits 24-29: frames, in BCD(6bits) + * bits 30: drop frame flag (0: non drop, 1: drop) + * bits 31: color frame flag (0: unsync mode, 1: sync mode) + * @note BCD numbers (6 or 7 bits): 4 or 5 lower bits for units, 2 higher bits for tens. + * @note Frame number adjustment is automatically done in case of drop timecode, + * you do NOT have to call av_timecode_adjust_ntsc_framenum2(). + * @note The frame number is relative to tc->start. + * @note Color frame (CF) and binary group flags (BGF) bits are set to zero. + */ +uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); + +/** + * Convert sei info to SMPTE 12M binary representation. + * + * @param rate frame rate in rational form + * @param drop drop flag + * @param hh hour + * @param mm minute + * @param ss second + * @param ff frame number + * @return the SMPTE binary representation + */ +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff); + +/** + * Load timecode string in buf. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the buf parameter + * + * @note Timecode representation can be a negative timecode and have more than + * 24 hours, but will only be honored if the flags are correctly set. + * @note The frame number is relative to tc->start. + */ +char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum); + +/** + * Get the timecode string from the SMPTE timecode format. + * + * In contrast to av_timecode_make_smpte_tc_string this function supports 50/60 + * fps timecodes by using the field bit. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param rate frame rate of the timecode + * @param tcsmpte the 32-bit SMPTE timecode + * @param prevent_df prevent the use of a drop flag when it is known the DF bit + * is arbitrary + * @param skip_field prevent the use of a field flag when it is known the field + * bit is arbitrary (e.g. because it is used as PC flag) + * @return the buf parameter + */ +char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field); + +/** + * Get the timecode string from the SMPTE timecode format. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tcsmpte the 32-bit SMPTE timecode + * @param prevent_df prevent the use of a drop flag when it is known the DF bit + * is arbitrary + * @return the buf parameter + */ +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df); + +/** + * Get the timecode string from the 25-bit timecode format (MPEG GOP format). + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc25bit the 25-bits timecode + * @return the buf parameter + */ +char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit); + +/** + * Init a timecode struct with the passed parameters. + * + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log) + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param flags miscellaneous flags such as drop frame, +24 hours, ... + * (see AVTimecodeFlag) + * @param frame_start the first frame number + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx); + +/** + * Init a timecode struct from the passed timecode components. + * + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log) + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param flags miscellaneous flags such as drop frame, +24 hours, ... + * (see AVTimecodeFlag) + * @param hh hours + * @param mm minutes + * @param ss seconds + * @param ff frames + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx); + +/** + * Parse timecode representation (hh:mm:ss[:;.]ff). + * + * @param log_ctx a pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct (used for av_log). + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param str timecode string which will determine the frame start + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx); + +/** + * Check if the timecode feature is available for the given frame rate + * + * @return 0 if supported, <0 otherwise + */ +int av_timecode_check_frame_rate(AVRational rate); + +#endif /* AVUTIL_TIMECODE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/timer.h new file mode 100644 index 00000000..d3db5a27 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/timer.h @@ -0,0 +1,156 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * high precision timer, useful to profile code + */ + +#ifndef AVUTIL_TIMER_H +#define AVUTIL_TIMER_H + +#include "config.h" + +#if CONFIG_LINUX_PERF +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include // read(3) +# include +# include +# include +#endif + +#include +#include +#include + +#if CONFIG_MACOS_KPERF +#include "macos_kperf.h" +#elif HAVE_MACH_ABSOLUTE_TIME +#include +#endif + +#include "common.h" +#include "log.h" + +#if ARCH_AARCH64 +# include "aarch64/timer.h" +#elif ARCH_ARM +# include "arm/timer.h" +#elif ARCH_PPC +# include "ppc/timer.h" +#elif ARCH_RISCV +# include "riscv/timer.h" +#elif ARCH_X86 +# include "x86/timer.h" +#endif + +#if !defined(AV_READ_TIME) +# if HAVE_GETHRTIME +# define AV_READ_TIME gethrtime +# elif HAVE_MACH_ABSOLUTE_TIME +# define AV_READ_TIME mach_absolute_time +# endif +#endif + +#ifndef FF_TIMER_UNITS +# define FF_TIMER_UNITS "UNITS" +#endif + +#define TIMER_REPORT(id, tdiff) \ + { \ + static uint64_t tsum = 0; \ + static int tcount = 0; \ + static int tskip_count = 0; \ + static int thistogram[32] = {0}; \ + thistogram[av_log2(tdiff)]++; \ + if (tcount < 2 || \ + (tdiff) < 8 * tsum / tcount || \ + (tdiff) < 2000) { \ + tsum += (tdiff); \ + tcount++; \ + } else \ + tskip_count++; \ + if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \ + int i; \ + av_log(NULL, AV_LOG_ERROR, \ + "%7" PRIu64 " " FF_TIMER_UNITS " in %s,%8d runs,%7d skips",\ + tsum * 10 / tcount, id, tcount, tskip_count); \ + for (i = 0; i < 32; i++) \ + av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\ + av_log(NULL, AV_LOG_ERROR, "\n"); \ + } \ + } + +#if CONFIG_LINUX_PERF + +#define START_TIMER \ + static int linux_perf_fd; \ + uint64_t tperf; \ + if (!linux_perf_fd) { \ + struct perf_event_attr attr = { \ + .type = PERF_TYPE_HARDWARE, \ + .size = sizeof(struct perf_event_attr), \ + .config = PERF_COUNT_HW_CPU_CYCLES, \ + .disabled = 1, \ + .exclude_kernel = 1, \ + .exclude_hv = 1, \ + }; \ + linux_perf_fd = syscall(__NR_perf_event_open, &attr, \ + 0, -1, -1, 0); \ + } \ + if (linux_perf_fd == -1) { \ + av_log(NULL, AV_LOG_ERROR, "perf_event_open failed: %s\n", \ + av_err2str(AVERROR(errno))); \ + } else { \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_RESET, 0); \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_ENABLE, 0); \ + } + +#define STOP_TIMER(id) \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_DISABLE, 0); \ + read(linux_perf_fd, &tperf, sizeof(tperf)); \ + TIMER_REPORT(id, tperf) + +#elif CONFIG_MACOS_KPERF + +#define START_TIMER \ + uint64_t tperf; \ + ff_kperf_init(); \ + tperf = ff_kperf_cycles(); + +#define STOP_TIMER(id) \ + TIMER_REPORT(id, ff_kperf_cycles() - tperf); + +#elif defined(AV_READ_TIME) +#define START_TIMER \ + uint64_t tend; \ + uint64_t tstart = AV_READ_TIME(); \ + +#define STOP_TIMER(id) \ + tend = AV_READ_TIME(); \ + TIMER_REPORT(id, tend - tstart) +#else +#define START_TIMER +#define STOP_TIMER(id) { } +#endif + +#endif /* AVUTIL_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/timestamp.h b/arm/raspi/third_party/ffmpeg/libavutil/timestamp.h new file mode 100644 index 00000000..e082f01b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/timestamp.h @@ -0,0 +1,78 @@ +/* + * 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 + * timestamp utils, mostly useful for debugging/logging purposes + */ + +#ifndef AVUTIL_TIMESTAMP_H +#define AVUTIL_TIMESTAMP_H + +#include "common.h" + +#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64) +#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS +#endif + +#define AV_TS_MAX_STRING_SIZE 32 + +/** + * Fill the provided buffer with a string containing a timestamp + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @return the buffer in input + */ +static inline char *av_ts_make_string(char *buf, int64_t ts) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts) + +/** + * Fill the provided buffer with a string containing a timestamp time + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @param tb the timebase of the timestamp + * @return the buffer in input + */ +static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb) + +#endif /* AVUTIL_TIMESTAMP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tomi/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/tomi/intreadwrite.h new file mode 100644 index 00000000..7dec4158 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tomi/intreadwrite.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TOMI_INTREADWRITE_H +#define AVUTIL_TOMI_INTREADWRITE_H + +#include + +#include "config.h" +#include "libavutil/attributes.h" + +#define AV_RB16 AV_RB16 +static av_always_inline uint16_t AV_RB16(const void *p) +{ + uint16_t v; + __asm__ ("loadacc, (%1+) \n\t" + "rol8 \n\t" + "storeacc, %0 \n\t" + "loadacc, (%1+) \n\t" + "add, %0 \n\t" + : "=r"(v), "+a"(p)); + return v; +} + +#define AV_WB16 AV_WB16 +static av_always_inline void AV_WB16(void *p, uint16_t v) +{ + __asm__ volatile ("loadacc, %1 \n\t" + "lsr8 \n\t" + "storeacc, (%0+) \n\t" + "loadacc, %1 \n\t" + "storeacc, (%0+) \n\t" + : "+&a"(p) : "r"(v)); +} + +#define AV_RL16 AV_RL16 +static av_always_inline uint16_t AV_RL16(const void *p) +{ + uint16_t v; + __asm__ ("loadacc, (%1+) \n\t" + "storeacc, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "add, %0 \n\t" + : "=r"(v), "+a"(p)); + return v; +} + +#define AV_WL16 AV_WL16 +static av_always_inline void AV_WL16(void *p, uint16_t v) +{ + __asm__ volatile ("loadacc, %1 \n\t" + "storeacc, (%0+) \n\t" + "lsr8 \n\t" + "storeacc, (%0+) \n\t" + : "+&a"(p) : "r"(v)); +} + +#define AV_RB32 AV_RB32 +static av_always_inline uint32_t AV_RB32(const void *p) +{ + uint32_t v; + __asm__ ("loadacc, (%1+) \n\t" + "rol8 \n\t" + "rol8 \n\t" + "rol8 \n\t" + "storeacc, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "rol8 \n\t" + "add, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "add, %0 \n\t" + "loadacc, (%1+) \n\t" + "add, %0 \n\t" + : "=r"(v), "+a"(p)); + return v; +} + +#define AV_WB32 AV_WB32 +static av_always_inline void AV_WB32(void *p, uint32_t v) +{ + __asm__ volatile ("loadacc, #4 \n\t" + "add, %0 \n\t" + "loadacc, %1 \n\t" + "storeacc, (-%0) \n\t" + "lsr8 \n\t" + "storeacc, (-%0) \n\t" + "lsr8 \n\t" + "storeacc, (-%0) \n\t" + "lsr8 \n\t" + "storeacc, (-%0) \n\t" + : "+&a"(p) : "r"(v)); +} + +#define AV_RL32 AV_RL32 +static av_always_inline uint32_t AV_RL32(const void *p) +{ + uint32_t v; + __asm__ ("loadacc, (%1+) \n\t" + "storeacc, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "add, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "rol8 \n\t" + "add, %0 \n\t" + "loadacc, (%1+) \n\t" + "rol8 \n\t" + "rol8 \n\t" + "rol8 \n\t" + "add, %0 \n\t" + : "=r"(v), "+a"(p)); + return v; +} + +#define AV_WL32 AV_WL32 +static av_always_inline void AV_WL32(void *p, uint32_t v) +{ + __asm__ volatile ("loadacc, %1 \n\t" + "storeacc, (%0+) \n\t" + "lsr8 \n\t" + "storeacc, (%0+) \n\t" + "lsr8 \n\t" + "storeacc, (%0+) \n\t" + "lsr8 \n\t" + "storeacc, (%0+) \n\t" + : "+&a"(p) : "r"(v)); +} + +#endif /* AVUTIL_TOMI_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tree.c b/arm/raspi/third_party/ffmpeg/libavutil/tree.c new file mode 100644 index 00000000..7b57b2d3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tree.c @@ -0,0 +1,168 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "error.h" +#include "log.h" +#include "mem.h" +#include "tree.h" + +typedef struct AVTreeNode { + struct AVTreeNode *child[2]; + void *elem; + int state; +} AVTreeNode; + +const int av_tree_node_size = sizeof(AVTreeNode); + +struct AVTreeNode *av_tree_node_alloc(void) +{ + return av_mallocz(sizeof(struct AVTreeNode)); +} + +void *av_tree_find(const AVTreeNode *t, void *key, + int (*cmp)(const void *key, const void *b), void *next[2]) +{ + if (t) { + unsigned int v = cmp(key, t->elem); + if (v) { + if (next) + next[v >> 31] = t->elem; + return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next); + } else { + if (next) { + av_tree_find(t->child[0], key, cmp, next); + av_tree_find(t->child[1], key, cmp, next); + } + return t->elem; + } + } + return NULL; +} + +void *av_tree_insert(AVTreeNode **tp, void *key, + int (*cmp)(const void *key, const void *b), AVTreeNode **next) +{ + AVTreeNode *t = *tp; + if (t) { + unsigned int v = cmp(t->elem, key); + void *ret; + if (!v) { + if (*next) + return t->elem; + else if (t->child[0] || t->child[1]) { + int i = !t->child[0]; + void *next_elem[2]; + av_tree_find(t->child[i], key, cmp, next_elem); + key = t->elem = next_elem[i]; + v = -i; + } else { + *next = t; + *tp = NULL; + return NULL; + } + } + ret = av_tree_insert(&t->child[v >> 31], key, cmp, next); + if (!ret) { + int i = (v >> 31) ^ !!*next; + AVTreeNode **child = &t->child[i]; + t->state += 2 * i - 1; + + if (!(t->state & 1)) { + if (t->state) { + /* The following code is equivalent to + * if ((*child)->state * 2 == -t->state) + * rotate(child, i ^ 1); + * rotate(tp, i); + * + * with rotate(): + * static void rotate(AVTreeNode **tp, int i) + * { + * AVTreeNode *t= *tp; + * + * *tp = t->child[i]; + * t->child[i] = t->child[i]->child[i ^ 1]; + * (*tp)->child[i ^ 1] = t; + * i = 4 * t->state + 2 * (*tp)->state + 12; + * t->state = ((0x614586 >> i) & 3) - 1; + * (*tp)->state = ((0x400EEA >> i) & 3) - 1 + + * ((*tp)->state >> 1); + * } + * but such a rotate function is both bigger and slower + */ + if ((*child)->state * 2 == -t->state) { + *tp = (*child)->child[i ^ 1]; + (*child)->child[i ^ 1] = (*tp)->child[i]; + (*tp)->child[i] = *child; + *child = (*tp)->child[i ^ 1]; + (*tp)->child[i ^ 1] = t; + + (*tp)->child[0]->state = -((*tp)->state > 0); + (*tp)->child[1]->state = (*tp)->state < 0; + (*tp)->state = 0; + } else { + *tp = *child; + *child = (*child)->child[i ^ 1]; + (*tp)->child[i ^ 1] = t; + if ((*tp)->state) + t->state = 0; + else + t->state >>= 1; + (*tp)->state = -t->state; + } + } + } + if (!(*tp)->state ^ !!*next) + return key; + } + return ret; + } else { + *tp = *next; + *next = NULL; + if (*tp) { + (*tp)->elem = key; + return NULL; + } else + return key; + } +} + +void av_tree_destroy(AVTreeNode *t) +{ + if (t) { + av_tree_destroy(t->child[0]); + av_tree_destroy(t->child[1]); + av_free(t); + } +} + +void av_tree_enumerate(AVTreeNode *t, void *opaque, + int (*cmp)(void *opaque, void *elem), + int (*enu)(void *opaque, void *elem)) +{ + if (t) { + int v = cmp ? cmp(opaque, t->elem) : 0; + if (v >= 0) + av_tree_enumerate(t->child[0], opaque, cmp, enu); + if (v == 0) + enu(opaque, t->elem); + if (v <= 0) + av_tree_enumerate(t->child[1], opaque, cmp, enu); + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tree.h b/arm/raspi/third_party/ffmpeg/libavutil/tree.h new file mode 100644 index 00000000..bbb8fbb1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tree.h @@ -0,0 +1,137 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * A tree container. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_TREE_H +#define AVUTIL_TREE_H + +#include "attributes.h" + +/** + * @addtogroup lavu_tree AVTree + * @ingroup lavu_data + * + * Low-complexity tree container + * + * Insertion, removal, finding equal, largest which is smaller than and + * smallest which is larger than, all have O(log n) worst-case complexity. + * @{ + */ + + +struct AVTreeNode; +extern const int av_tree_node_size; + +/** + * Allocate an AVTreeNode. + */ +struct AVTreeNode *av_tree_node_alloc(void); + +/** + * Find an element. + * @param root a pointer to the root node of the tree + * @param next If next is not NULL, then next[0] will contain the previous + * element and next[1] the next element. If either does not exist, + * then the corresponding entry in next is unchanged. + * @param cmp compare function used to compare elements in the tree, + * API identical to that of Standard C's qsort + * It is guaranteed that the first and only the first argument to cmp() + * will be the key parameter to av_tree_find(), thus it could if the + * user wants, be a different type (like an opaque context). + * @return An element with cmp(key, elem) == 0 or NULL if no such element + * exists in the tree. + */ +void *av_tree_find(const struct AVTreeNode *root, void *key, + int (*cmp)(const void *key, const void *b), void *next[2]); + +/** + * Insert or remove an element. + * + * If *next is NULL, then the supplied element will be removed if it exists. + * If *next is non-NULL, then the supplied element will be inserted, unless + * it already exists in the tree. + * + * @param rootp A pointer to a pointer to the root node of the tree; note that + * the root node can change during insertions, this is required + * to keep the tree balanced. + * @param key pointer to the element key to insert in the tree + * @param next Used to allocate and free AVTreeNodes. For insertion the user + * must set it to an allocated and zeroed object of at least + * av_tree_node_size bytes size. av_tree_insert() will set it to + * NULL if it has been consumed. + * For deleting elements *next is set to NULL by the user and + * av_tree_insert() will set it to the AVTreeNode which was + * used for the removed element. + * This allows the use of flat arrays, which have + * lower overhead compared to many malloced elements. + * You might want to define a function like: + * @code + * void *tree_insert(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b), + * AVTreeNode **next) + * { + * if (!*next) + * *next = av_mallocz(av_tree_node_size); + * return av_tree_insert(rootp, key, cmp, next); + * } + * void *tree_remove(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b, AVTreeNode **next)) + * { + * av_freep(next); + * return av_tree_insert(rootp, key, cmp, next); + * } + * @endcode + * @param cmp compare function used to compare elements in the tree, API identical + * to that of Standard C's qsort + * @return If no insertion happened, the found element; if an insertion or + * removal happened, then either key or NULL will be returned. + * Which one it is depends on the tree state and the implementation. You + * should make no assumptions that it's one or the other in the code. + */ +void *av_tree_insert(struct AVTreeNode **rootp, void *key, + int (*cmp)(const void *key, const void *b), + struct AVTreeNode **next); + +void av_tree_destroy(struct AVTreeNode *t); + +/** + * Apply enu(opaque, &elem) to all the elements in the tree in a given range. + * + * @param cmp a comparison function that returns < 0 for an element below the + * range, > 0 for an element above the range and == 0 for an + * element inside the range + * + * @note The cmp function should use the same ordering used to construct the + * tree. + */ +void av_tree_enumerate(struct AVTreeNode *t, void *opaque, + int (*cmp)(void *opaque, void *elem), + int (*enu)(void *opaque, void *elem)); + +/** + * @} + */ + +#endif /* AVUTIL_TREE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/twofish.c b/arm/raspi/third_party/ffmpeg/libavutil/twofish.c new file mode 100644 index 00000000..9f9687ec --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/twofish.c @@ -0,0 +1,335 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "twofish.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" +#include "attributes.h" + +#define LR(x, n) ((x) << (n) | (x) >> (32 - (n))) +#define RR(x, n) ((x) >> (n) | (x) << (32 - (n))) + +typedef struct AVTWOFISH { + uint32_t K[40]; + uint32_t S[4]; + int ksize; + uint32_t MDS1[256]; + uint32_t MDS2[256]; + uint32_t MDS3[256]; + uint32_t MDS4[256]; +} AVTWOFISH; + +static const uint8_t MD1[256] = { + 0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51, 0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2, + 0x14, 0x4f, 0xa2, 0xf9, 0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40, 0xad, 0xf6, + 0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0, 0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca, + 0x3c, 0x67, 0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb, 0x33, 0x68, 0x85, 0xde, + 0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e, 0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2, + 0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15, 0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6, + 0x78, 0x23, 0xce, 0x95, 0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c, 0xc1, 0x9a, + 0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84, 0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e, + 0xa0, 0xfb, 0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47, 0xaf, 0xf4, 0x19, 0x42, + 0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea, 0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56, + 0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9, 0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a, + 0x9c, 0xc7, 0x2a, 0x71, 0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8, 0x25, 0x7e, + 0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18, 0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12, + 0xe4, 0xbf, 0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03, 0xeb, 0xb0, 0x5d, 0x06, + 0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86, 0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a, + 0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d, 0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e +}; + +static const uint8_t MD2[256] = { + 0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1, 0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51, + 0x1c, 0xf3, 0xab, 0x44, 0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa, 0xa2, 0x4d, + 0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67, 0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69, + 0x24, 0xcb, 0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72, 0x2d, 0xc2, 0x9a, 0x75, + 0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98, 0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21, + 0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d, 0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d, + 0x48, 0xa7, 0xff, 0x10, 0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae, 0xf6, 0x19, + 0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b, 0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05, + 0xe0, 0x0f, 0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6, 0xe9, 0x06, 0x5e, 0xb1, + 0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14, 0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad, + 0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39, 0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89, + 0xc4, 0x2b, 0x73, 0x9c, 0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22, 0x7a, 0x95, + 0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf, 0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1, + 0x8c, 0x63, 0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda, 0x85, 0x6a, 0x32, 0xdd, + 0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40, 0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9, + 0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55, 0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5 +}; + +static const uint8_t q0[256] = { + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, + 0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48, + 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, + 0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61, + 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, + 0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, + 0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90, + 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, + 0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a, + 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, + 0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0 +}; + +static const uint8_t q1[256] = { + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, + 0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f, + 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, + 0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, + 0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2, + 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, + 0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e, + 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, + 0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64, + 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, + 0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc, + 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91 +}; + +struct AVTWOFISH *av_twofish_alloc(void) +{ + return av_mallocz(sizeof(struct AVTWOFISH)); +} + +const int av_twofish_size = sizeof(AVTWOFISH); + +static uint8_t gfmul(uint8_t a, uint8_t b) +{ + uint8_t r = 0, t; + while (a && b) { + if (a & 1) + r = r ^ b; + t = b & 0x80; + b = b << 1; + if (t) + b = b ^ 0x4d; + a = a >> 1; + } + return r; +} + +static uint32_t tf_RS(uint32_t k0, uint32_t k1) +{ + uint8_t s[4], m[8]; + AV_WL32(m, k0); + AV_WL32(m + 4, k1); + s[0] = gfmul(0x01, m[0]) ^ gfmul(0xa4, m[1]) ^ gfmul(0x55, m[2]) ^ gfmul(0x87, m[3]) ^ gfmul(0x5a, m[4]) ^ gfmul(0x58, m[5]) ^ gfmul(0xdb, m[6]) ^ gfmul(0x9e, m[7]); + s[1] = gfmul(0xa4, m[0]) ^ gfmul(0x56, m[1]) ^ gfmul(0x82, m[2]) ^ gfmul(0xf3, m[3]) ^ gfmul(0x1e, m[4]) ^ gfmul(0xc6, m[5]) ^ gfmul(0x68, m[6]) ^ gfmul(0xe5, m[7]); + s[2] = gfmul(0x02, m[0]) ^ gfmul(0xa1, m[1]) ^ gfmul(0xfc, m[2]) ^ gfmul(0xc1, m[3]) ^ gfmul(0x47, m[4]) ^ gfmul(0xae, m[5]) ^ gfmul(0x3d, m[6]) ^ gfmul(0x19, m[7]); + s[3] = gfmul(0xa4, m[0]) ^ gfmul(0x55, m[1]) ^ gfmul(0x87, m[2]) ^ gfmul(0x5a, m[3]) ^ gfmul(0x58, m[4]) ^ gfmul(0xdb, m[5]) ^ gfmul(0x9e, m[6]) ^ gfmul(0x03, m[7]); + return AV_RL32(s); +} + +static void tf_h0(uint8_t y[4], uint32_t L[4], int k) +{ + uint8_t l[4]; + if (k == 4) { + AV_WL32(l, L[3]); + y[0] = q1[y[0]] ^ l[0]; + y[1] = q0[y[1]] ^ l[1]; + y[2] = q0[y[2]] ^ l[2]; + y[3] = q1[y[3]] ^ l[3]; + } + if (k >= 3) { + AV_WL32(l, L[2]); + y[0] = q1[y[0]] ^ l[0]; + y[1] = q1[y[1]] ^ l[1]; + y[2] = q0[y[2]] ^ l[2]; + y[3] = q0[y[3]] ^ l[3]; + } + AV_WL32(l, L[1]); + y[0] = q1[q0[q0[y[0]] ^ l[0]] ^ (L[0] & 0xff)]; + y[1] = q0[q0[q1[y[1]] ^ l[1]] ^ ((L[0] >> 8) & 0xff)]; + y[2] = q1[q1[q0[y[2]] ^ l[2]] ^ ((L[0] >> 16) & 0xff)]; + y[3] = q0[q1[q1[y[3]] ^ l[3]] ^ (L[0] >> 24)]; +} + +static uint32_t tf_h(uint32_t X, uint32_t L[4], int k) +{ + uint8_t y[4], l[4]; + AV_WL32(y, X); + tf_h0(y, L, k); + + l[0] = y[0] ^ MD2[y[1]] ^ MD1[y[2]] ^ MD1[y[3]]; + l[1] = MD1[y[0]] ^ MD2[y[1]] ^ MD2[y[2]] ^ y[3]; + l[2] = MD2[y[0]] ^ MD1[y[1]] ^ y[2] ^ MD2[y[3]]; + l[3] = MD2[y[0]] ^ y[1] ^ MD2[y[2]] ^ MD1[y[3]]; + + return AV_RL32(l); +} + +static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X) +{ + return cs->MDS1[(X) & 0xff] ^ cs->MDS2[((X) >> 8) & 0xff] ^ cs->MDS3[((X) >> 16) & 0xff] ^ cs->MDS4[(X) >> 24]; +} + +static void precomputeMDS(AVTWOFISH *cs) +{ + uint8_t y[4]; + int i; + for (i = 0; i < 256; i++) { + y[0] = y[1] = y[2] = y[3] = i; + tf_h0(y, cs->S, cs->ksize); + cs->MDS1[i] = ((uint32_t)y[0]) ^ ((uint32_t)MD1[y[0]] << 8) ^ ((uint32_t)MD2[y[0]] << 16) ^ ((uint32_t)MD2[y[0]] << 24); + cs->MDS2[i] = ((uint32_t)MD2[y[1]]) ^ ((uint32_t)MD2[y[1]] << 8) ^ ((uint32_t)MD1[y[1]] << 16) ^ ((uint32_t)y[1] << 24); + cs->MDS3[i] = ((uint32_t)MD1[y[2]]) ^ ((uint32_t)MD2[y[2]] << 8) ^ ((uint32_t)y[2] << 16) ^ ((uint32_t)MD2[y[2]] << 24); + cs->MDS4[i] = ((uint32_t)MD1[y[3]]) ^ ((uint32_t)y[3] << 8) ^ ((uint32_t)MD2[y[3]] << 16) ^ ((uint32_t)MD1[y[3]] << 24); + } +} + +static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src) +{ + uint32_t P[4], t0, t1; + int i; + P[0] = AV_RL32(src) ^ cs->K[0]; + P[1] = AV_RL32(src + 4) ^ cs->K[1]; + P[2] = AV_RL32(src + 8) ^ cs->K[2]; + P[3] = AV_RL32(src + 12) ^ cs->K[3]; + for (i = 0; i < 16; i += 2) { + t0 = MDS_mul(cs, P[0]); + t1 = MDS_mul(cs, LR(P[1], 8)); + P[2] = RR(P[2] ^ (t0 + t1 + cs->K[2 * i + 8]), 1); + P[3] = LR(P[3], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 9]); + t0 = MDS_mul(cs, P[2]); + t1 = MDS_mul(cs, LR(P[3], 8)); + P[0] = RR(P[0] ^ (t0 + t1 + cs->K[2 * i + 10]), 1); + P[1] = LR(P[1], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 11]); + } + P[2] ^= cs->K[4]; + P[3] ^= cs->K[5]; + P[0] ^= cs->K[6]; + P[1] ^= cs->K[7]; + AV_WL32(dst, P[2]); + AV_WL32(dst + 4, P[3]); + AV_WL32(dst + 8, P[0]); + AV_WL32(dst + 12, P[1]); +} + +static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv) +{ + uint32_t P[4], t0, t1; + int i; + P[2] = AV_RL32(src) ^ cs->K[4]; + P[3] = AV_RL32(src + 4) ^ cs->K[5]; + P[0] = AV_RL32(src + 8) ^ cs->K[6]; + P[1] = AV_RL32(src + 12) ^ cs->K[7]; + for (i = 15; i >= 0; i -= 2) { + t0 = MDS_mul(cs, P[2]); + t1 = MDS_mul(cs, LR(P[3], 8)); + P[0] = LR(P[0], 1) ^ (t0 + t1 + cs->K[2 * i + 8]); + P[1] = RR(P[1] ^ (t0 + 2 * t1 + cs->K[2 * i + 9]), 1); + t0 = MDS_mul(cs, P[0]); + t1 = MDS_mul(cs, LR(P[1], 8)); + P[2] = LR(P[2], 1) ^ (t0 + t1 + cs->K[2 * i + 6]); + P[3] = RR(P[3] ^ (t0 + 2 * t1 + cs->K[2 * i + 7]), 1); + } + P[0] ^= cs->K[0]; + P[1] ^= cs->K[1]; + P[2] ^= cs->K[2]; + P[3] ^= cs->K[3]; + if (iv) { + P[0] ^= AV_RL32(iv); + P[1] ^= AV_RL32(iv + 4); + P[2] ^= AV_RL32(iv + 8); + P[3] ^= AV_RL32(iv + 12); + memcpy(iv, src, 16); + } + AV_WL32(dst, P[0]); + AV_WL32(dst + 4, P[1]); + AV_WL32(dst + 8, P[2]); + AV_WL32(dst + 12, P[3]); +} + +av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits) +{ + int i; + uint8_t keypad[32]; + uint32_t Key[8], Me[4], Mo[4], A, B; + const uint32_t rho = 0x01010101; + if (key_bits < 0) + return AVERROR(EINVAL); + if (key_bits <= 128) { + cs->ksize = 2; + } else if (key_bits <= 192) { + cs->ksize = 3; + } else { + cs->ksize = 4; + } + memset(keypad, 0, sizeof(keypad)); + if (key_bits <= 256) { + memcpy(keypad, key, key_bits >> 3); + } else { + memcpy(keypad, key, 32); + } + for (i = 0; i < 2 * cs->ksize ; i++) + Key[i] = AV_RL32(keypad + 4 * i); + for (i = 0; i < cs->ksize; i++) { + Me[i] = Key[2 * i]; + Mo[i] = Key[2 * i + 1]; + cs->S[cs->ksize - i - 1] = tf_RS(Me[i], Mo[i]); + } + precomputeMDS(cs); + for (i = 0; i < 20; i++) { + A = tf_h((2 * i) * rho, Me, cs->ksize); + B = tf_h((2 * i + 1) * rho, Mo, cs->ksize); + B = LR(B, 8); + cs->K[2 * i] = A + B; + cs->K[2 * i + 1] = LR((A + (2 * B)), 9); + } + if (cs->ksize << 6 != key_bits) { + return 1; + } else { + return 0; + } +} + +void av_twofish_crypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + twofish_decrypt(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 16; i++) + dst[i] = src[i] ^ iv[i]; + twofish_encrypt(cs, dst, dst); + memcpy(iv, dst, 16); + } else { + twofish_encrypt(cs, dst, src); + } + } + src = src + 16; + dst = dst + 16; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/twofish.h b/arm/raspi/third_party/ffmpeg/libavutil/twofish.h new file mode 100644 index 00000000..67f359e8 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/twofish.h @@ -0,0 +1,70 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TWOFISH_H +#define AVUTIL_TWOFISH_H + +#include + + +/** + * @file + * @brief Public header for libavutil TWOFISH algorithm + * @defgroup lavu_twofish TWOFISH + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_twofish_size; + +struct AVTWOFISH; + +/** + * Allocate an AVTWOFISH context + * To free the struct: av_free(ptr) + */ +struct AVTWOFISH *av_twofish_alloc(void); + +/** + * Initialize an AVTWOFISH context. + * + * @param ctx an AVTWOFISH context + * @param key a key of size ranging from 1 to 32 bytes used for encryption/decryption + * @param key_bits number of keybits: 128, 192, 256 If less than the required, padded with zeroes to nearest valid value; return value is 0 if key_bits is 128/192/256, -1 if less than 0, 1 otherwise + */ +int av_twofish_init(struct AVTWOFISH *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVTWOFISH context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @param iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_twofish_crypt(struct AVTWOFISH *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_TWOFISH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx.c b/arm/raspi/third_party/ffmpeg/libavutil/tx.c new file mode 100644 index 00000000..52e8685b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx.c @@ -0,0 +1,919 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avassert.h" +#include "intmath.h" +#include "cpu.h" +#include "qsort.h" +#include "bprint.h" + +#include "tx_priv.h" + +#define TYPE_IS(type, x) \ + (((x) == AV_TX_FLOAT_ ## type) || \ + ((x) == AV_TX_DOUBLE_ ## type) || \ + ((x) == AV_TX_INT32_ ## type)) + +/* Calculates the modular multiplicative inverse */ +static av_always_inline int mulinv(int n, int m) +{ + n = n % m; + for (int x = 1; x < m; x++) + if (((n * x) % m) == 1) + return x; + av_assert0(0); /* Never reached */ + return 0; +} + +int ff_tx_gen_pfa_input_map(AVTXContext *s, FFTXCodeletOptions *opts, + int d1, int d2) +{ + const int sl = d1*d2; + + s->map = av_malloc(s->len*sizeof(*s->map)); + if (!s->map) + return AVERROR(ENOMEM); + + for (int k = 0; k < s->len; k += sl) { + if (s->inv || (opts && opts->map_dir == FF_TX_MAP_SCATTER)) { + for (int m = 0; m < d2; m++) + for (int n = 0; n < d1; n++) + s->map[k + ((m*d1 + n*d2) % (sl))] = m*d1 + n; + } else { + for (int m = 0; m < d2; m++) + for (int n = 0; n < d1; n++) + s->map[k + m*d1 + n] = (m*d1 + n*d2) % (sl); + } + + if (s->inv) + for (int w = 1; w <= ((sl) >> 1); w++) + FFSWAP(int, s->map[k + w], s->map[k + sl - w]); + } + + s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; + + return 0; +} + +/* Guaranteed to work for any n, m where gcd(n, m) == 1 */ +int ff_tx_gen_compound_mapping(AVTXContext *s, FFTXCodeletOptions *opts, + int inv, int n, int m) +{ + int *in_map, *out_map; + const int len = n*m; /* Will not be equal to s->len for MDCTs */ + int m_inv, n_inv; + + /* Make sure the numbers are coprime */ + if (av_gcd(n, m) != 1) + return AVERROR(EINVAL); + + m_inv = mulinv(m, n); + n_inv = mulinv(n, m); + + if (!(s->map = av_malloc(2*len*sizeof(*s->map)))) + return AVERROR(ENOMEM); + + in_map = s->map; + out_map = s->map + len; + + /* Ruritanian map for input, CRT map for output, can be swapped */ + if (opts && opts->map_dir == FF_TX_MAP_SCATTER) { + for (int j = 0; j < m; j++) { + for (int i = 0; i < n; i++) { + in_map[(i*m + j*n) % len] = j*n + i; + out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j; + } + } + } else { + for (int j = 0; j < m; j++) { + for (int i = 0; i < n; i++) { + in_map[j*n + i] = (i*m + j*n) % len; + out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j; + } + } + } + + if (inv) { + for (int i = 0; i < m; i++) { + int *in = &in_map[i*n + 1]; /* Skip the DC */ + for (int j = 0; j < ((n - 1) >> 1); j++) + FFSWAP(int, in[j], in[n - j - 2]); + } + } + + s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; + + return 0; +} + +static inline int split_radix_permutation(int i, int len, int inv) +{ + len >>= 1; + if (len <= 1) + return i & 1; + if (!(i & len)) + return split_radix_permutation(i, len, inv) * 2; + len >>= 1; + return split_radix_permutation(i, len, inv) * 4 + 1 - 2*(!(i & len) ^ inv); +} + +int ff_tx_gen_ptwo_revtab(AVTXContext *s, FFTXCodeletOptions *opts) +{ + int len = s->len; + + if (!(s->map = av_malloc(len*sizeof(*s->map)))) + return AVERROR(ENOMEM); + + if (opts && opts->map_dir == FF_TX_MAP_SCATTER) { + for (int i = 0; i < s->len; i++) + s->map[-split_radix_permutation(i, len, s->inv) & (len - 1)] = i; + } else { + for (int i = 0; i < s->len; i++) + s->map[i] = -split_radix_permutation(i, len, s->inv) & (len - 1); + } + + s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; + + return 0; +} + +int ff_tx_gen_inplace_map(AVTXContext *s, int len) +{ + int *src_map, out_map_idx = 0; + + if (!s->sub || !s->sub->map) + return AVERROR(EINVAL); + + if (!(s->map = av_mallocz(len*sizeof(*s->map)))) + return AVERROR(ENOMEM); + + src_map = s->sub->map; + + /* The first coefficient is always already in-place */ + for (int src = 1; src < s->len; src++) { + int dst = src_map[src]; + int found = 0; + + if (dst <= src) + continue; + + /* This just checks if a closed loop has been encountered before, + * and if so, skips it, since to fully permute a loop we must only + * enter it once. */ + do { + for (int j = 0; j < out_map_idx; j++) { + if (dst == s->map[j]) { + found = 1; + break; + } + } + dst = src_map[dst]; + } while (dst != src && !found); + + if (!found) + s->map[out_map_idx++] = src; + } + + s->map[out_map_idx++] = 0; + + return 0; +} + +static void parity_revtab_generator(int *revtab, int n, int inv, int offset, + int is_dual, int dual_high, int len, + int basis, int dual_stride, int inv_lookup) +{ + len >>= 1; + + if (len <= basis) { + int k1, k2, stride, even_idx, odd_idx; + + is_dual = is_dual && dual_stride; + dual_high = is_dual & dual_high; + stride = is_dual ? FFMIN(dual_stride, len) : 0; + + even_idx = offset + dual_high*(stride - 2*len); + odd_idx = even_idx + len + (is_dual && !dual_high)*len + dual_high*len; + + for (int i = 0; i < len; i++) { + k1 = -split_radix_permutation(offset + i*2 + 0, n, inv) & (n - 1); + k2 = -split_radix_permutation(offset + i*2 + 1, n, inv) & (n - 1); + if (inv_lookup) { + revtab[even_idx++] = k1; + revtab[odd_idx++] = k2; + } else { + revtab[k1] = even_idx++; + revtab[k2] = odd_idx++; + } + if (stride && !((i + 1) % stride)) { + even_idx += stride; + odd_idx += stride; + } + } + + return; + } + + parity_revtab_generator(revtab, n, inv, offset, + 0, 0, len >> 0, basis, dual_stride, inv_lookup); + parity_revtab_generator(revtab, n, inv, offset + (len >> 0), + 1, 0, len >> 1, basis, dual_stride, inv_lookup); + parity_revtab_generator(revtab, n, inv, offset + (len >> 0) + (len >> 1), + 1, 1, len >> 1, basis, dual_stride, inv_lookup); +} + +int ff_tx_gen_split_radix_parity_revtab(AVTXContext *s, int len, int inv, + FFTXCodeletOptions *opts, + int basis, int dual_stride) +{ + basis >>= 1; + if (len < basis) + return AVERROR(EINVAL); + + if (!(s->map = av_mallocz(len*sizeof(*s->map)))) + return AVERROR(ENOMEM); + + av_assert0(!dual_stride || !(dual_stride & (dual_stride - 1))); + av_assert0(dual_stride <= basis); + + parity_revtab_generator(s->map, len, inv, 0, 0, 0, len, + basis, dual_stride, + opts ? opts->map_dir == FF_TX_MAP_GATHER : FF_TX_MAP_GATHER); + + s->map_dir = opts ? opts->map_dir : FF_TX_MAP_GATHER; + + return 0; +} + +static void reset_ctx(AVTXContext *s, int free_sub) +{ + if (!s) + return; + + if (s->sub) + for (int i = 0; i < TX_MAX_SUB; i++) + reset_ctx(&s->sub[i], free_sub + 1); + + if (s->cd_self && s->cd_self->uninit) + s->cd_self->uninit(s); + + if (free_sub) + av_freep(&s->sub); + + av_freep(&s->map); + av_freep(&s->exp); + av_freep(&s->tmp); + + /* Nothing else needs to be reset, it gets overwritten if another + * ff_tx_init_subtx() call is made. */ + s->nb_sub = 0; + s->opaque = NULL; + memset(s->fn, 0, sizeof(*s->fn)); +} + +void ff_tx_clear_ctx(AVTXContext *s) +{ + reset_ctx(s, 0); +} + +av_cold void av_tx_uninit(AVTXContext **ctx) +{ + if (!(*ctx)) + return; + + reset_ctx(*ctx, 1); + av_freep(ctx); +} + +static av_cold int ff_tx_null_init(AVTXContext *s, const FFTXCodelet *cd, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale) +{ + /* Can only handle one sample+type to one sample+type transforms */ + if (TYPE_IS(MDCT, s->type) || TYPE_IS(RDFT, s->type)) + return AVERROR(EINVAL); + return 0; +} + +/* Null transform when the length is 1 */ +static void ff_tx_null(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride) +{ + memcpy(_out, _in, stride); +} + +static const FFTXCodelet ff_tx_null_def = { + .name = NULL_IF_CONFIG_SMALL("null"), + .function = ff_tx_null, + .type = TX_TYPE_ANY, + .flags = AV_TX_UNALIGNED | FF_TX_ALIGNED | + FF_TX_OUT_OF_PLACE | AV_TX_INPLACE, + .factors[0] = TX_FACTOR_ANY, + .min_len = 1, + .max_len = 1, + .init = ff_tx_null_init, + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_MAX, +}; + +static const FFTXCodelet * const ff_tx_null_list[] = { + &ff_tx_null_def, + NULL, +}; + +/* Array of all compiled codelet lists. Order is irrelevant. */ +static const FFTXCodelet * const * const codelet_list[] = { + ff_tx_codelet_list_float_c, + // ff_tx_codelet_list_double_c, // Chromium: save on binary size + // ff_tx_codelet_list_int32_c, // Chromium: save on binary size + // Removed in commit 6a1468ead6b2b0c611f16ed6c7609eaa30e13d74 + // https://chromium-review.googlesource.com/c/chromium/third_party/ffmpeg/+/4061169 + ff_tx_null_list, +#if HAVE_X86ASM + ff_tx_codelet_list_float_x86, +#endif +#if ARCH_AARCH64 + ff_tx_codelet_list_float_aarch64, +#endif +}; +static const int codelet_list_num = FF_ARRAY_ELEMS(codelet_list); + +static const int cpu_slow_mask = AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_ATOM | AV_CPU_FLAG_SSSE3SLOW | + AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER; + +static const int cpu_slow_penalties[][2] = { + { AV_CPU_FLAG_SSE2SLOW, 1 + 64 }, + { AV_CPU_FLAG_SSE3SLOW, 1 + 64 }, + { AV_CPU_FLAG_SSSE3SLOW, 1 + 64 }, + { AV_CPU_FLAG_ATOM, 1 + 128 }, + { AV_CPU_FLAG_AVXSLOW, 1 + 128 }, + { AV_CPU_FLAG_SLOW_GATHER, 1 + 32 }, +}; + +static int get_codelet_prio(const FFTXCodelet *cd, int cpu_flags, int len) +{ + int prio = cd->prio; + int max_factor = 0; + + /* If the CPU has a SLOW flag, and the instruction is also flagged + * as being slow for such, reduce its priority */ + for (int i = 0; i < FF_ARRAY_ELEMS(cpu_slow_penalties); i++) { + if ((cpu_flags & cd->cpu_flags) & cpu_slow_penalties[i][0]) + prio -= cpu_slow_penalties[i][1]; + } + + /* Prioritize aligned-only codelets */ + if ((cd->flags & FF_TX_ALIGNED) && !(cd->flags & AV_TX_UNALIGNED)) + prio += 64; + + /* Codelets for specific lengths are generally faster */ + if ((len == cd->min_len) && (len == cd->max_len)) + prio += 64; + + /* Forward-only or inverse-only transforms are generally better */ + if ((cd->flags & (FF_TX_FORWARD_ONLY | FF_TX_INVERSE_ONLY))) + prio += 64; + + /* Larger factors are generally better */ + for (int i = 0; i < TX_MAX_SUB; i++) + max_factor = FFMAX(cd->factors[i], max_factor); + if (max_factor) + prio += 16*max_factor; + + return prio; +} + +typedef struct FFTXLenDecomp { + int len; + int len2; + int prio; + const FFTXCodelet *cd; +} FFTXLenDecomp; + +static int cmp_decomp(FFTXLenDecomp *a, FFTXLenDecomp *b) +{ + return FFDIFFSIGN(b->prio, a->prio); +} + +int ff_tx_decompose_length(int dst[TX_MAX_DECOMPOSITIONS], enum AVTXType type, + int len, int inv) +{ + int nb_decomp = 0; + FFTXLenDecomp ld[TX_MAX_DECOMPOSITIONS]; + int codelet_list_idx = codelet_list_num; + + const int cpu_flags = av_get_cpu_flags(); + + /* Loop through all codelets in all codelet lists to find matches + * to the requirements */ + while (codelet_list_idx--) { + const FFTXCodelet * const * list = codelet_list[codelet_list_idx]; + const FFTXCodelet *cd = NULL; + + while ((cd = *list++)) { + int fl = len; + int skip = 0, prio; + int factors_product = 1, factors_mod = 0; + + if (nb_decomp >= TX_MAX_DECOMPOSITIONS) + goto sort; + + /* Check if the type matches */ + if (cd->type != TX_TYPE_ANY && type != cd->type) + continue; + + /* Check direction for non-orthogonal codelets */ + if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) || + ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv)) + continue; + + /* Check if the CPU supports the required ISA */ + if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL && + !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask))) + continue; + + for (int i = 0; i < TX_MAX_FACTORS; i++) { + if (!cd->factors[i] || (fl == 1)) + break; + + if (cd->factors[i] == TX_FACTOR_ANY) { + factors_mod++; + factors_product *= fl; + } else if (!(fl % cd->factors[i])) { + factors_mod++; + if (cd->factors[i] == 2) { + int b = ff_ctz(fl); + fl >>= b; + factors_product <<= b; + } else { + do { + fl /= cd->factors[i]; + factors_product *= cd->factors[i]; + } while (!(fl % cd->factors[i])); + } + } + } + + /* Disqualify if factor requirements are not satisfied or if trivial */ + if ((factors_mod < cd->nb_factors) || (len == factors_product)) + continue; + + if (av_gcd(factors_product, fl) != 1) + continue; + + /* Check if length is supported and factorization was successful */ + if ((factors_product < cd->min_len) || + (cd->max_len != TX_LEN_UNLIMITED && (factors_product > cd->max_len))) + continue; + + prio = get_codelet_prio(cd, cpu_flags, factors_product) * factors_product; + + /* Check for duplicates */ + for (int i = 0; i < nb_decomp; i++) { + if (factors_product == ld[i].len) { + /* Update priority if new one is higher */ + if (prio > ld[i].prio) + ld[i].prio = prio; + skip = 1; + break; + } + } + + /* Add decomposition if unique */ + if (!skip) { + ld[nb_decomp].cd = cd; + ld[nb_decomp].len = factors_product; + ld[nb_decomp].len2 = fl; + ld[nb_decomp].prio = prio; + nb_decomp++; + } + } + } + + if (!nb_decomp) + return AVERROR(EINVAL); + +sort: + AV_QSORT(ld, nb_decomp, FFTXLenDecomp, cmp_decomp); + + for (int i = 0; i < nb_decomp; i++) { + if (ld[i].cd->nb_factors > 1) + dst[i] = ld[i].len2; + else + dst[i] = ld[i].len; + } + + return nb_decomp; +} + +int ff_tx_gen_default_map(AVTXContext *s, FFTXCodeletOptions *opts) +{ + s->map = av_malloc(s->len*sizeof(*s->map)); + if (!s->map) + return AVERROR(ENOMEM); + + s->map[0] = 0; /* DC is always at the start */ + if (s->inv) /* Reversing the ACs flips the transform direction */ + for (int i = 1; i < s->len; i++) + s->map[i] = s->len - i; + else + for (int i = 1; i < s->len; i++) + s->map[i] = i; + + s->map_dir = FF_TX_MAP_GATHER; + + return 0; +} + +#if !CONFIG_SMALL +static void print_flags(AVBPrint *bp, uint64_t f) +{ + int prev = 0; + const char *sep = ", "; + av_bprintf(bp, "flags: ["); + if ((f & FF_TX_ALIGNED) && ++prev) + av_bprintf(bp, "aligned"); + if ((f & AV_TX_UNALIGNED) && ++prev) + av_bprintf(bp, "%sunaligned", prev > 1 ? sep : ""); + if ((f & AV_TX_INPLACE) && ++prev) + av_bprintf(bp, "%sinplace", prev > 1 ? sep : ""); + if ((f & FF_TX_OUT_OF_PLACE) && ++prev) + av_bprintf(bp, "%sout_of_place", prev > 1 ? sep : ""); + if ((f & FF_TX_FORWARD_ONLY) && ++prev) + av_bprintf(bp, "%sfwd_only", prev > 1 ? sep : ""); + if ((f & FF_TX_INVERSE_ONLY) && ++prev) + av_bprintf(bp, "%sinv_only", prev > 1 ? sep : ""); + if ((f & FF_TX_PRESHUFFLE) && ++prev) + av_bprintf(bp, "%spreshuf", prev > 1 ? sep : ""); + if ((f & AV_TX_FULL_IMDCT) && ++prev) + av_bprintf(bp, "%simdct_full", prev > 1 ? sep : ""); + if ((f & FF_TX_ASM_CALL) && ++prev) + av_bprintf(bp, "%sasm_call", prev > 1 ? sep : ""); + av_bprintf(bp, "]"); +} + +static void print_type(AVBPrint *bp, enum AVTXType type) +{ + av_bprintf(bp, "%s", + type == TX_TYPE_ANY ? "any" : + type == AV_TX_FLOAT_FFT ? "fft_float" : + type == AV_TX_FLOAT_MDCT ? "mdct_float" : + type == AV_TX_FLOAT_RDFT ? "rdft_float" : + type == AV_TX_DOUBLE_FFT ? "fft_double" : + type == AV_TX_DOUBLE_MDCT ? "mdct_double" : + type == AV_TX_DOUBLE_RDFT ? "rdft_double" : + type == AV_TX_INT32_FFT ? "fft_int32" : + type == AV_TX_INT32_MDCT ? "mdct_int32" : + type == AV_TX_INT32_RDFT ? "rdft_int32" : + "unknown"); +} + +static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio) +{ + AVBPrint bp = { 0 }; + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); + + av_bprintf(&bp, "%s - type: ", cd->name); + + print_type(&bp, cd->type); + + av_bprintf(&bp, ", len: "); + if (!len) { + if (cd->min_len != cd->max_len) + av_bprintf(&bp, "[%i, ", cd->min_len); + + if (cd->max_len == TX_LEN_UNLIMITED) + av_bprintf(&bp, "∞"); + else + av_bprintf(&bp, "%i", cd->max_len); + } else { + av_bprintf(&bp, "%i", len); + } + + if (cd->factors[1]) { + av_bprintf(&bp, "%s, factors", !len && cd->min_len != cd->max_len ? "]" : ""); + if (!cd->nb_factors) + av_bprintf(&bp, ": ["); + else + av_bprintf(&bp, "[%i]: [", cd->nb_factors); + + for (int i = 0; i < TX_MAX_FACTORS; i++) { + if (i && cd->factors[i]) + av_bprintf(&bp, ", "); + if (cd->factors[i] == TX_FACTOR_ANY) + av_bprintf(&bp, "any"); + else if (cd->factors[i]) + av_bprintf(&bp, "%i", cd->factors[i]); + else + break; + } + + av_bprintf(&bp, "], "); + } else { + av_bprintf(&bp, "%s, factor: %i, ", + !len && cd->min_len != cd->max_len ? "]" : "", cd->factors[0]); + } + print_flags(&bp, cd->flags); + + if (print_prio) + av_bprintf(&bp, ", prio: %i", prio); + + av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str); +} + +static void print_tx_structure(AVTXContext *s, int depth) +{ + const FFTXCodelet *cd = s->cd_self; + + for (int i = 0; i <= depth; i++) + av_log(NULL, AV_LOG_DEBUG, " "); + + print_cd_info(cd, cd->prio, s->len, 0); + + for (int i = 0; i < s->nb_sub; i++) + print_tx_structure(&s->sub[i], depth + 1); +} +#endif /* CONFIG_SMALL */ + +typedef struct TXCodeletMatch { + const FFTXCodelet *cd; + int prio; +} TXCodeletMatch; + +static int cmp_matches(TXCodeletMatch *a, TXCodeletMatch *b) +{ + return FFDIFFSIGN(b->prio, a->prio); +} + +/* We want all factors to completely cover the length */ +static inline int check_cd_factors(const FFTXCodelet *cd, int len) +{ + int matches = 0, any_flag = 0; + + for (int i = 0; i < TX_MAX_FACTORS; i++) { + int factor = cd->factors[i]; + + if (factor == TX_FACTOR_ANY) { + any_flag = 1; + matches++; + continue; + } else if (len <= 1 || !factor) { + break; + } else if (factor == 2) { /* Fast path */ + int bits_2 = ff_ctz(len); + if (!bits_2) + continue; /* Factor not supported */ + + len >>= bits_2; + matches++; + } else { + int res = len % factor; + if (res) + continue; /* Factor not supported */ + + while (!res) { + len /= factor; + res = len % factor; + } + matches++; + } + } + + return (cd->nb_factors <= matches) && (any_flag || len == 1); +} + +av_cold int ff_tx_init_subtx(AVTXContext *s, enum AVTXType type, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale) +{ + int ret = 0; + AVTXContext *sub = NULL; + TXCodeletMatch *cd_tmp, *cd_matches = NULL; + unsigned int cd_matches_size = 0; + int codelet_list_idx = codelet_list_num; + int nb_cd_matches = 0; +#if !CONFIG_SMALL + AVBPrint bp = { 0 }; +#endif + + /* We still accept functions marked with SLOW, even if the CPU is + * marked with the same flag, but we give them lower priority. */ + const int cpu_flags = av_get_cpu_flags(); + + /* Flags the transform wants */ + uint64_t req_flags = flags; + + /* Flags the codelet may require to be present */ + uint64_t inv_req_mask = AV_TX_FULL_IMDCT | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL; + + /* Unaligned codelets are compatible with the aligned flag */ + if (req_flags & FF_TX_ALIGNED) + req_flags |= AV_TX_UNALIGNED; + + /* If either flag is set, both are okay, so don't check for an exact match */ + if ((req_flags & AV_TX_INPLACE) && (req_flags & FF_TX_OUT_OF_PLACE)) + req_flags &= ~(AV_TX_INPLACE | FF_TX_OUT_OF_PLACE); + if ((req_flags & FF_TX_ALIGNED) && (req_flags & AV_TX_UNALIGNED)) + req_flags &= ~(FF_TX_ALIGNED | AV_TX_UNALIGNED); + + /* Loop through all codelets in all codelet lists to find matches + * to the requirements */ + while (codelet_list_idx--) { + const FFTXCodelet * const * list = codelet_list[codelet_list_idx]; + const FFTXCodelet *cd = NULL; + + while ((cd = *list++)) { + /* Check if the type matches */ + if (cd->type != TX_TYPE_ANY && type != cd->type) + continue; + + /* Check direction for non-orthogonal codelets */ + if (((cd->flags & FF_TX_FORWARD_ONLY) && inv) || + ((cd->flags & (FF_TX_INVERSE_ONLY | AV_TX_FULL_IMDCT)) && !inv)) + continue; + + /* Check if the requested flags match from both sides */ + if (((req_flags & cd->flags) != (req_flags)) || + ((inv_req_mask & cd->flags) != (req_flags & inv_req_mask))) + continue; + + /* Check if length is supported */ + if ((len < cd->min_len) || (cd->max_len != -1 && (len > cd->max_len))) + continue; + + /* Check if the CPU supports the required ISA */ + if (cd->cpu_flags != FF_TX_CPU_FLAGS_ALL && + !(cpu_flags & (cd->cpu_flags & ~cpu_slow_mask))) + continue; + + /* Check for factors */ + if (!check_cd_factors(cd, len)) + continue; + + /* Realloc array and append */ + cd_tmp = av_fast_realloc(cd_matches, &cd_matches_size, + sizeof(*cd_tmp) * (nb_cd_matches + 1)); + if (!cd_tmp) { + av_free(cd_matches); + return AVERROR(ENOMEM); + } + + cd_matches = cd_tmp; + cd_matches[nb_cd_matches].cd = cd; + cd_matches[nb_cd_matches].prio = get_codelet_prio(cd, cpu_flags, len); + nb_cd_matches++; + } + } + +#if !CONFIG_SMALL + /* Print debugging info */ + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprintf(&bp, "For transform of length %i, %s, ", len, + inv ? "inverse" : "forward"); + print_type(&bp, type); + av_bprintf(&bp, ", "); + print_flags(&bp, flags); + av_bprintf(&bp, ", found %i matches%s", nb_cd_matches, + nb_cd_matches ? ":" : "."); +#endif + + /* No matches found */ + if (!nb_cd_matches) + return AVERROR(ENOSYS); + + /* Sort the list */ + AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches); + +#if !CONFIG_SMALL + av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str); + + for (int i = 0; i < nb_cd_matches; i++) { + av_log(NULL, AV_LOG_DEBUG, " %i: ", i + 1); + print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1); + } +#endif + + if (!s->sub) { + s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub)); + if (!sub) { + ret = AVERROR(ENOMEM); + goto end; + } + } + + /* Attempt to initialize each */ + for (int i = 0; i < nb_cd_matches; i++) { + const FFTXCodelet *cd = cd_matches[i].cd; + AVTXContext *sctx = &s->sub[s->nb_sub]; + + sctx->len = len; + sctx->inv = inv; + sctx->type = type; + sctx->flags = cd->flags | flags; + sctx->cd_self = cd; + + s->fn[s->nb_sub] = cd->function; + s->cd[s->nb_sub] = cd; + + ret = 0; + if (cd->init) + ret = cd->init(sctx, cd, flags, opts, len, inv, scale); + + if (ret >= 0) { + if (opts && opts->map_dir != FF_TX_MAP_NONE && + sctx->map_dir == FF_TX_MAP_NONE) { + /* If a specific map direction was requested, and it doesn't + * exist, create one.*/ + sctx->map = av_malloc(len*sizeof(*sctx->map)); + if (!sctx->map) { + ret = AVERROR(ENOMEM); + goto end; + } + + for (int i = 0; i < len; i++) + sctx->map[i] = i; + } else if (opts && (opts->map_dir != sctx->map_dir)) { + int *tmp = av_malloc(len*sizeof(*sctx->map)); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto end; + } + + memcpy(tmp, sctx->map, len*sizeof(*sctx->map)); + + for (int i = 0; i < len; i++) + sctx->map[tmp[i]] = i; + + av_free(tmp); + } + + s->nb_sub++; + goto end; + } + + s->fn[s->nb_sub] = NULL; + s->cd[s->nb_sub] = NULL; + + reset_ctx(sctx, 0); + if (ret == AVERROR(ENOMEM)) + break; + } + + if (!s->nb_sub) + av_freep(&s->sub); + +end: + av_free(cd_matches); + return ret; +} + +av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags) +{ + int ret; + AVTXContext tmp = { 0 }; + const double default_scale_d = 1.0; + const float default_scale_f = 1.0f; + + if (!len || type >= AV_TX_NB || !ctx || !tx) + return AVERROR(EINVAL); + + if (!(flags & AV_TX_UNALIGNED)) + flags |= FF_TX_ALIGNED; + if (!(flags & AV_TX_INPLACE)) + flags |= FF_TX_OUT_OF_PLACE; + + if (!scale && ((type == AV_TX_FLOAT_MDCT) || (type == AV_TX_INT32_MDCT))) + scale = &default_scale_f; + else if (!scale && (type == AV_TX_DOUBLE_MDCT)) + scale = &default_scale_d; + + ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale); + if (ret < 0) + return ret; + + *ctx = &tmp.sub[0]; + *tx = tmp.fn[0]; + +#if !CONFIG_SMALL + av_log(NULL, AV_LOG_DEBUG, "Transform tree:\n"); + print_tx_structure(*ctx, 0); +#endif + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx.h b/arm/raspi/third_party/ffmpeg/libavutil/tx.h new file mode 100644 index 00000000..064edbc0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx.h @@ -0,0 +1,176 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TX_H +#define AVUTIL_TX_H + +#include +#include + +typedef struct AVTXContext AVTXContext; + +typedef struct AVComplexFloat { + float re, im; +} AVComplexFloat; + +typedef struct AVComplexDouble { + double re, im; +} AVComplexDouble; + +typedef struct AVComplexInt32 { + int32_t re, im; +} AVComplexInt32; + +enum AVTXType { + /** + * Standard complex to complex FFT with sample data type of AVComplexFloat, + * AVComplexDouble or AVComplexInt32, for each respective variant. + * + * Output is not 1/len normalized. Scaling currently unsupported. + * The stride parameter must be set to the size of a single sample in bytes. + */ + AV_TX_FLOAT_FFT = 0, + AV_TX_DOUBLE_FFT = 2, + AV_TX_INT32_FFT = 4, + + /** + * Standard MDCT with a sample data type of float, double or int32_t, + * respecively. For the float and int32 variants, the scale type is + * 'float', while for the double variant, it's 'double'. + * If scale is NULL, 1.0 will be used as a default. + * + * Length is the frame size, not the window size (which is 2x frame). + * For forward transforms, the stride specifies the spacing between each + * sample in the output array in bytes. The input must be a flat array. + * + * For inverse transforms, the stride specifies the spacing between each + * sample in the input array in bytes. The output must be a flat array. + * + * NOTE: the inverse transform is half-length, meaning the output will not + * contain redundant data. This is what most codecs work with. To do a full + * inverse transform, set the AV_TX_FULL_IMDCT flag on init. + */ + AV_TX_FLOAT_MDCT = 1, + AV_TX_DOUBLE_MDCT = 3, + AV_TX_INT32_MDCT = 5, + + /** + * Real to complex and complex to real DFTs. + * For the float and int32 variants, the scale type is 'float', while for + * the double variant, it's a 'double'. If scale is NULL, 1.0 will be used + * as a default. + * + * For forward transforms (R2C), stride must be the spacing between two + * samples in bytes. For inverse transforms, the stride must be set + * to the spacing between two complex values in bytes. + * + * The forward transform performs a real-to-complex DFT of N samples to + * N/2+1 complex values. + * + * The inverse transform performs a complex-to-real DFT of N/2+1 complex + * values to N real samples. The output is not normalized, but can be + * made so by setting the scale value to 1.0/len. + * NOTE: the inverse transform always overwrites the input. + */ + AV_TX_FLOAT_RDFT = 6, + AV_TX_DOUBLE_RDFT = 7, + AV_TX_INT32_RDFT = 8, + + /** + * Real to real (DCT) transforms. + * + * The forward transform is a DCT-II. + * The inverse transform is a DCT-III. + * + * The input array is always overwritten. DCT-III requires that the + * input be padded with 2 extra samples. Stride must be set to the + * spacing between two samples in bytes. + */ + AV_TX_FLOAT_DCT = 9, + AV_TX_DOUBLE_DCT = 10, + AV_TX_INT32_DCT = 11, + + /* Not part of the API, do not use */ + AV_TX_NB, +}; + +/** + * Function pointer to a function to perform the transform. + * + * @note Using a different context than the one allocated during av_tx_init() + * is not allowed. + * + * @param s the transform context + * @param out the output array + * @param in the input array + * @param stride the input or output stride in bytes + * + * The out and in arrays must be aligned to the maximum required by the CPU + * architecture unless the AV_TX_UNALIGNED flag was set in av_tx_init(). + * The stride must follow the constraints the transform type has specified. + */ +typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride); + +/** + * Flags for av_tx_init() + */ +enum AVTXFlags { + /** + * Allows for in-place transformations, where input == output. + * May be unsupported or slower for some transform types. + */ + AV_TX_INPLACE = 1ULL << 0, + + /** + * Relaxes alignment requirement for the in and out arrays of av_tx_fn(). + * May be slower with certain transform types. + */ + AV_TX_UNALIGNED = 1ULL << 1, + + /** + * Performs a full inverse MDCT rather than leaving out samples that can be + * derived through symmetry. Requires an output array of 'len' floats, + * rather than the usual 'len/2' floats. + * Ignored for all transforms but inverse MDCTs. + */ + AV_TX_FULL_IMDCT = 1ULL << 2, +}; + +/** + * Initialize a transform context with the given configuration + * (i)MDCTs with an odd length are currently not supported. + * + * @param ctx the context to allocate, will be NULL on error + * @param tx pointer to the transform function pointer to set + * @param type type the type of transform + * @param inv whether to do an inverse or a forward transform + * @param len the size of the transform in samples + * @param scale pointer to the value to scale the output if supported by type + * @param flags a bitmask of AVTXFlags or 0 + * + * @return 0 on success, negative error code on failure + */ +int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags); + +/** + * Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL. + */ +void av_tx_uninit(AVTXContext **ctx); + +#endif /* AVUTIL_TX_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx_double.c b/arm/raspi/third_party/ffmpeg/libavutil/tx_double.c new file mode 100644 index 00000000..7ea4283c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx_double.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TX_DOUBLE +#include "tx_priv.h" +#include "tx_template.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx_float.c b/arm/raspi/third_party/ffmpeg/libavutil/tx_float.c new file mode 100644 index 00000000..018f2a21 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx_float.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TX_FLOAT +#include "tx_priv.h" +#include "tx_template.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx_int32.c b/arm/raspi/third_party/ffmpeg/libavutil/tx_int32.c new file mode 100644 index 00000000..9261013b --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx_int32.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TX_INT32 +#include "tx_priv.h" +#include "tx_template.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx_priv.h b/arm/raspi/third_party/ffmpeg/libavutil/tx_priv.h new file mode 100644 index 00000000..72f336ee --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx_priv.h @@ -0,0 +1,385 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TX_PRIV_H +#define AVUTIL_TX_PRIV_H + +#include "tx.h" +#include "thread.h" +#include "mem_internal.h" +#include "attributes.h" + +#ifdef TX_FLOAT +#define TX_TAB(x) x ## _float +#define TX_NAME(x) x ## _float_c +#define TX_NAME_STR(x) NULL_IF_CONFIG_SMALL(x "_float_c") +#define TX_TYPE(x) AV_TX_FLOAT_ ## x +#define TX_FN_NAME(fn, suffix) ff_tx_ ## fn ## _float_ ## suffix +#define TX_FN_NAME_STR(fn, suffix) NULL_IF_CONFIG_SMALL(#fn "_float_" #suffix) +#define MULT(x, m) ((x) * (m)) +#define SCALE_TYPE float +typedef float TXSample; +typedef float TXUSample; +typedef AVComplexFloat TXComplex; +#elif defined(TX_DOUBLE) +#define TX_TAB(x) x ## _double +#define TX_NAME(x) x ## _double_c +#define TX_NAME_STR(x) NULL_IF_CONFIG_SMALL(x "_double_c") +#define TX_TYPE(x) AV_TX_DOUBLE_ ## x +#define TX_FN_NAME(fn, suffix) ff_tx_ ## fn ## _double_ ## suffix +#define TX_FN_NAME_STR(fn, suffix) NULL_IF_CONFIG_SMALL(#fn "_double_" #suffix) +#define MULT(x, m) ((x) * (m)) +#define SCALE_TYPE double +typedef double TXSample; +typedef double TXUSample; +typedef AVComplexDouble TXComplex; +#elif defined(TX_INT32) +#define TX_TAB(x) x ## _int32 +#define TX_NAME(x) x ## _int32_c +#define TX_NAME_STR(x) NULL_IF_CONFIG_SMALL(x "_int32_c") +#define TX_TYPE(x) AV_TX_INT32_ ## x +#define TX_FN_NAME(fn, suffix) ff_tx_ ## fn ## _int32_ ## suffix +#define TX_FN_NAME_STR(fn, suffix) NULL_IF_CONFIG_SMALL(#fn "_int32_" #suffix) +#define MULT(x, m) (((((int64_t)(x)) * (int64_t)(m)) + 0x40000000) >> 31) +#define SCALE_TYPE float +typedef int32_t TXSample; +typedef uint32_t TXUSample; +typedef AVComplexInt32 TXComplex; +#else +typedef void TXComplex; +#endif + +#define TX_DECL_FN(fn, suffix) \ + void TX_FN_NAME(fn, suffix)(AVTXContext *s, void *o, void *i, ptrdiff_t st); + +#define TX_DEF(fn, tx_type, len_min, len_max, f1, f2, \ + p, init_fn, suffix, cf, cd_flags, cf2) \ + &(const FFTXCodelet){ \ + .name = TX_FN_NAME_STR(fn, suffix), \ + .function = TX_FN_NAME(fn, suffix), \ + .type = TX_TYPE(tx_type), \ + .flags = FF_TX_ALIGNED | FF_TX_OUT_OF_PLACE | cd_flags, \ + .factors = { (f1), (f2) }, \ + .nb_factors = !!(f1) + !!(f2), \ + .min_len = len_min, \ + .max_len = len_max, \ + .init = init_fn, \ + .cpu_flags = cf2 | AV_CPU_FLAG_ ## cf, \ + .prio = p, \ + } + +#if defined(TX_FLOAT) || defined(TX_DOUBLE) + +#define CMUL(dre, dim, are, aim, bre, bim) \ + do { \ + (dre) = (are) * (bre) - (aim) * (bim); \ + (dim) = (are) * (bim) + (aim) * (bre); \ + } while (0) + +#define SMUL(dre, dim, are, aim, bre, bim) \ + do { \ + (dre) = (are) * (bre) - (aim) * (bim); \ + (dim) = (are) * (bim) - (aim) * (bre); \ + } while (0) + +#define UNSCALE(x) (x) +#define RESCALE(x) (x) + +#define FOLD(a, b) ((a) + (b)) + +#elif defined(TX_INT32) + +/* Properly rounds the result */ +#define CMUL(dre, dim, are, aim, bre, bim) \ + do { \ + int64_t accu; \ + (accu) = (int64_t)(bre) * (are); \ + (accu) -= (int64_t)(bim) * (aim); \ + (dre) = (int)(((accu) + 0x40000000) >> 31); \ + (accu) = (int64_t)(bim) * (are); \ + (accu) += (int64_t)(bre) * (aim); \ + (dim) = (int)(((accu) + 0x40000000) >> 31); \ + } while (0) + +#define SMUL(dre, dim, are, aim, bre, bim) \ + do { \ + int64_t accu; \ + (accu) = (int64_t)(bre) * (are); \ + (accu) -= (int64_t)(bim) * (aim); \ + (dre) = (int)(((accu) + 0x40000000) >> 31); \ + (accu) = (int64_t)(bim) * (are); \ + (accu) -= (int64_t)(bre) * (aim); \ + (dim) = (int)(((accu) + 0x40000000) >> 31); \ + } while (0) + +#define UNSCALE(x) ((double)(x)/2147483648.0) +#define RESCALE(x) (av_clip64(llrintf((x) * 2147483648.0), INT32_MIN, INT32_MAX)) + +#define FOLD(x, y) ((int32_t)((x) + (unsigned)(y) + 32) >> 6) + +#endif /* TX_INT32 */ + +#define BF(x, y, a, b) \ + do { \ + x = (a) - (b); \ + y = (a) + (b); \ + } while (0) + +#define CMUL3(c, a, b) CMUL((c).re, (c).im, (a).re, (a).im, (b).re, (b).im) + +/* Codelet flags, used to pick codelets. Must be a superset of enum AVTXFlags, + * but if it runs out of bits, it can be made separate. */ +#define FF_TX_OUT_OF_PLACE (1ULL << 63) /* Can be OR'd with AV_TX_INPLACE */ +#define FF_TX_ALIGNED (1ULL << 62) /* Cannot be OR'd with AV_TX_UNALIGNED */ +#define FF_TX_PRESHUFFLE (1ULL << 61) /* Codelet expects permuted coeffs */ +#define FF_TX_INVERSE_ONLY (1ULL << 60) /* For non-orthogonal inverse-only transforms */ +#define FF_TX_FORWARD_ONLY (1ULL << 59) /* For non-orthogonal forward-only transforms */ +#define FF_TX_ASM_CALL (1ULL << 58) /* For asm->asm functions only */ + +typedef enum FFTXCodeletPriority { + FF_TX_PRIO_BASE = 0, /* Baseline priority */ + + /* For SIMD, set base prio to the register size in bits and increment in + * steps of 64 depending on faster/slower features, like FMA. */ + + FF_TX_PRIO_MIN = -131072, /* For naive implementations */ + FF_TX_PRIO_MAX = 32768, /* For custom implementations/ASICs */ +} FFTXCodeletPriority; + +typedef enum FFTXMapDirection { + /* No map. Make a map up. */ + FF_TX_MAP_NONE = 0, + + /* Lookup table must be applied via dst[i] = src[lut[i]]; */ + FF_TX_MAP_GATHER, + + /* Lookup table must be applied via dst[lut[i]] = src[i]; */ + FF_TX_MAP_SCATTER, +} FFTXMapDirection; + +/* Codelet options */ +typedef struct FFTXCodeletOptions { + /* Request a specific lookup table direction. Codelets MUST put the + * direction in AVTXContext. If the codelet does not respect this, a + * conversion will be performed. */ + FFTXMapDirection map_dir; +} FFTXCodeletOptions; + +/* Maximum number of factors a codelet may have. Arbitrary. */ +#define TX_MAX_FACTORS 16 + +/* Maximum amount of subtransform functions, subtransforms and factors. Arbitrary. */ +#define TX_MAX_SUB 4 + +/* Maximum number of returned results for ff_tx_decompose_length. Arbitrary. */ +#define TX_MAX_DECOMPOSITIONS 512 + +typedef struct FFTXCodelet { + const char *name; /* Codelet name, for debugging */ + av_tx_fn function; /* Codelet function, != NULL */ + enum AVTXType type; /* Type of codelet transform */ +#define TX_TYPE_ANY INT32_MAX /* Special type to allow all types */ + + uint64_t flags; /* A combination of AVTXFlags and codelet + * flags that describe its properties. */ + + int factors[TX_MAX_FACTORS]; /* Length factors. MUST be coprime. */ +#define TX_FACTOR_ANY -1 /* When used alone, signals that the codelet + * supports all factors. Otherwise, if other + * factors are present, it signals that whatever + * remains will be supported, as long as the + * other factors are a component of the length */ + + int nb_factors; /* Minimum number of factors that have to + * be a modulo of the length. Must not be 0. */ + + int min_len; /* Minimum length of transform, must be >= 1 */ + int max_len; /* Maximum length of transform */ +#define TX_LEN_UNLIMITED -1 /* Special length value to permit all lengths */ + + int (*init)(AVTXContext *s, /* Optional callback for current context initialization. */ + const struct FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale); + + int (*uninit)(AVTXContext *s); /* Optional callback for uninitialization. */ + + int cpu_flags; /* CPU flags. If any negative flags like + * SLOW are present, will avoid picking. + * 0x0 to signal it's a C codelet */ +#define FF_TX_CPU_FLAGS_ALL 0x0 /* Special CPU flag for C */ + + int prio; /* < 0 = least, 0 = no pref, > 0 = prefer */ +} FFTXCodelet; + +struct AVTXContext { + /* Fields the root transform and subtransforms use or may use. + * NOTE: This section is used by assembly, do not reorder or change */ + int len; /* Length of the transform */ + int inv; /* If transform is inverse */ + int *map; /* Lookup table(s) */ + TXComplex *exp; /* Any non-pre-baked multiplication factors, + * or extra temporary buffer */ + TXComplex *tmp; /* Temporary buffer, if needed */ + + AVTXContext *sub; /* Subtransform context(s), if needed */ + av_tx_fn fn[TX_MAX_SUB]; /* Function(s) for the subtransforms */ + int nb_sub; /* Number of subtransforms. + * The reason all of these are set here + * rather than in each separate context + * is to eliminate extra pointer + * dereferences. */ + + /* Fields mainly useul/applicable for the root transform or initialization. + * Fields below are not used by assembly code. */ + const FFTXCodelet *cd[TX_MAX_SUB]; /* Subtransform codelets */ + const FFTXCodelet *cd_self; /* Codelet for the current context */ + enum AVTXType type; /* Type of transform */ + uint64_t flags; /* A combination of AVTXFlags and + * codelet flags used when creating */ + FFTXMapDirection map_dir; /* Direction of AVTXContext->map */ + float scale_f; + double scale_d; + void *opaque; /* Free to use by implementations */ +}; + +/* This function embeds a Ruritanian PFA input map into an existing lookup table + * to avoid double permutation. This allows for compound factors to be + * synthesized as fast PFA FFTs and embedded into either other or standalone + * transforms. + * The output CRT map must still be pre-baked into the transform. */ +#define TX_EMBED_INPUT_PFA_MAP(map, tot_len, d1, d2) \ + do { \ + int mtmp[(d1)*(d2)]; \ + for (int k = 0; k < tot_len; k += (d1)*(d2)) { \ + memcpy(mtmp, &map[k], (d1)*(d2)*sizeof(*mtmp)); \ + for (int m = 0; m < (d2); m++) \ + for (int n = 0; n < (d1); n++) \ + map[k + m*(d1) + n] = mtmp[(m*(d1) + n*(d2)) % ((d1)*(d2))]; \ + } \ + } while (0) + +/* This function generates a Ruritanian PFA input map into s->map. */ +int ff_tx_gen_pfa_input_map(AVTXContext *s, FFTXCodeletOptions *opts, + int d1, int d2); + +/* Create a subtransform in the current context with the given parameters. + * The flags parameter from FFTXCodelet.init() should be preserved as much + * as that's possible. + * MUST be called during the sub() callback of each codelet. */ +int ff_tx_init_subtx(AVTXContext *s, enum AVTXType type, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale); + +/* Clear the context by freeing all tables, maps and subtransforms. */ +void ff_tx_clear_ctx(AVTXContext *s); + +/* Attempt to factorize a length into 2 integers such that + * len / dst1 == dst2, where dst1 and dst2 are coprime. */ +int ff_tx_decompose_length(int dst[TX_MAX_DECOMPOSITIONS], enum AVTXType type, + int len, int inv); + +/* Generate a default map (0->len or 0, (len-1)->1 for inverse transforms) + * for a context. */ +int ff_tx_gen_default_map(AVTXContext *s, FFTXCodeletOptions *opts); + +/* + * Generates the PFA permutation table into AVTXContext->pfatab. The end table + * is appended to the start table. + * The `inv` flag should only be enabled if the lookup tables of subtransforms + * won't get flattened. + */ +int ff_tx_gen_compound_mapping(AVTXContext *s, FFTXCodeletOptions *opts, + int inv, int n, int m); + +/* + * Generates a standard-ish (slightly modified) Split-Radix revtab into + * AVTXContext->map. Invert lookup changes how the mapping needs to be applied. + * If it's set to 0, it has to be applied like out[map[i]] = in[i], otherwise + * if it's set to 1, has to be applied as out[i] = in[map[i]] + */ +int ff_tx_gen_ptwo_revtab(AVTXContext *s, FFTXCodeletOptions *opts); + +/* + * Generates an index into AVTXContext->inplace_idx that if followed in the + * specific order, allows the revtab to be done in-place. The sub-transform + * and its map should already be initialized. + */ +int ff_tx_gen_inplace_map(AVTXContext *s, int len); + +/* + * This generates a parity-based revtab of length len and direction inv. + * + * Parity means even and odd complex numbers will be split, e.g. the even + * coefficients will come first, after which the odd coefficients will be + * placed. For example, a 4-point transform's coefficients after reordering: + * z[0].re, z[0].im, z[2].re, z[2].im, z[1].re, z[1].im, z[3].re, z[3].im + * + * The basis argument is the length of the largest non-composite transform + * supported, and also implies that the basis/2 transform is supported as well, + * as the split-radix algorithm requires it to be. + * + * The dual_stride argument indicates that both the basis, as well as the + * basis/2 transforms support doing two transforms at once, and the coefficients + * will be interleaved between each pair in a split-radix like so (stride == 2): + * tx1[0], tx1[2], tx2[0], tx2[2], tx1[1], tx1[3], tx2[1], tx2[3] + * A non-zero number switches this on, with the value indicating the stride + * (how many values of 1 transform to put first before switching to the other). + * Must be a power of two or 0. Must be less than the basis. + * Value will be clipped to the transform size, so for a basis of 16 and a + * dual_stride of 8, dual 8-point transforms will be laid out as if dual_stride + * was set to 4. + * Usually you'll set this to half the complex numbers that fit in a single + * register or 0. This allows to reuse SSE functions as dual-transform + * functions in AVX mode. + * + * If length is smaller than basis/2 this function will not do anything. + * + * If inv_lookup is set to 1, it will flip the lookup from out[map[i]] = src[i] + * to out[i] = src[map[i]]. + */ +int ff_tx_gen_split_radix_parity_revtab(AVTXContext *s, int len, int inv, + FFTXCodeletOptions *opts, + int basis, int dual_stride); + +/* Typed init function to initialize shared tables. Will initialize all tables + * for all factors of a length. */ +void ff_tx_init_tabs_float (int len); +void ff_tx_init_tabs_double(int len); +void ff_tx_init_tabs_int32 (int len); + +/* Typed init function to initialize an MDCT exptab in a context. + * If pre_tab is set, duplicates the entire table, with the first + * copy being shuffled according to pre_tab, and the second copy + * being the original. */ +int ff_tx_mdct_gen_exp_float (AVTXContext *s, int *pre_tab); +int ff_tx_mdct_gen_exp_double(AVTXContext *s, int *pre_tab); +int ff_tx_mdct_gen_exp_int32 (AVTXContext *s, int *pre_tab); + +/* Lists of codelets */ +extern const FFTXCodelet * const ff_tx_codelet_list_float_c []; +extern const FFTXCodelet * const ff_tx_codelet_list_float_x86 []; +extern const FFTXCodelet * const ff_tx_codelet_list_float_aarch64 []; + +extern const FFTXCodelet * const ff_tx_codelet_list_double_c []; + +extern const FFTXCodelet * const ff_tx_codelet_list_int32_c []; + +#endif /* AVUTIL_TX_PRIV_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/tx_template.c b/arm/raspi/third_party/ffmpeg/libavutil/tx_template.c new file mode 100644 index 00000000..983de75a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/tx_template.c @@ -0,0 +1,1993 @@ +/* + * Copyright (c) Lynne + * + * Power of two FFT: + * Copyright (c) Lynne + * Copyright (c) 2008 Loren Merritt + * Copyright (c) 2002 Fabrice Bellard + * Partly based on libdjbfft by D. J. Bernstein + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TABLE_DEF(name, size) \ + DECLARE_ALIGNED(32, TXSample, TX_TAB(ff_tx_tab_ ##name))[size] + +#define SR_POW2_TABLES \ + SR_TABLE(8) \ + SR_TABLE(16) \ + SR_TABLE(32) \ + SR_TABLE(64) \ + SR_TABLE(128) \ + SR_TABLE(256) \ + SR_TABLE(512) \ + SR_TABLE(1024) \ + SR_TABLE(2048) \ + SR_TABLE(4096) \ + SR_TABLE(8192) \ + SR_TABLE(16384) \ + SR_TABLE(32768) \ + SR_TABLE(65536) \ + SR_TABLE(131072) \ + +#define SR_TABLE(len) \ + TABLE_DEF(len, len/4 + 1); +/* Power of two tables */ +SR_POW2_TABLES +#undef SR_TABLE + +/* Other factors' tables */ +TABLE_DEF(53, 12); +TABLE_DEF( 7, 6); +TABLE_DEF( 9, 8); + +typedef struct FFTabInitData { + void (*func)(void); + int factors[TX_MAX_SUB]; /* Must be sorted high -> low */ +} FFTabInitData; + +#define SR_TABLE(len) \ +static av_cold void TX_TAB(ff_tx_init_tab_ ##len)(void) \ +{ \ + double freq = 2*M_PI/len; \ + TXSample *tab = TX_TAB(ff_tx_tab_ ##len); \ + \ + for (int i = 0; i < len/4; i++) \ + *tab++ = RESCALE(cos(i*freq)); \ + \ + *tab = 0; \ +} +SR_POW2_TABLES +#undef SR_TABLE + +static void (*const sr_tabs_init_funcs[])(void) = { +#define SR_TABLE(len) TX_TAB(ff_tx_init_tab_ ##len), + SR_POW2_TABLES +#undef SR_TABLE +}; + +static AVOnce sr_tabs_init_once[] = { +#define SR_TABLE(len) AV_ONCE_INIT, + SR_POW2_TABLES +#undef SR_TABLE +}; + +static av_cold void TX_TAB(ff_tx_init_tab_53)(void) +{ + /* 5pt, doubled to eliminate AVX lane shuffles */ + TX_TAB(ff_tx_tab_53)[0] = RESCALE(cos(2 * M_PI / 5)); + TX_TAB(ff_tx_tab_53)[1] = RESCALE(cos(2 * M_PI / 5)); + TX_TAB(ff_tx_tab_53)[2] = RESCALE(cos(2 * M_PI / 10)); + TX_TAB(ff_tx_tab_53)[3] = RESCALE(cos(2 * M_PI / 10)); + TX_TAB(ff_tx_tab_53)[4] = RESCALE(sin(2 * M_PI / 5)); + TX_TAB(ff_tx_tab_53)[5] = RESCALE(sin(2 * M_PI / 5)); + TX_TAB(ff_tx_tab_53)[6] = RESCALE(sin(2 * M_PI / 10)); + TX_TAB(ff_tx_tab_53)[7] = RESCALE(sin(2 * M_PI / 10)); + + /* 3pt */ + TX_TAB(ff_tx_tab_53)[ 8] = RESCALE(cos(2 * M_PI / 12)); + TX_TAB(ff_tx_tab_53)[ 9] = RESCALE(cos(2 * M_PI / 12)); + TX_TAB(ff_tx_tab_53)[10] = RESCALE(cos(2 * M_PI / 6)); + TX_TAB(ff_tx_tab_53)[11] = RESCALE(cos(8 * M_PI / 6)); +} + +static av_cold void TX_TAB(ff_tx_init_tab_7)(void) +{ + TX_TAB(ff_tx_tab_7)[0] = RESCALE(cos(2 * M_PI / 7)); + TX_TAB(ff_tx_tab_7)[1] = RESCALE(sin(2 * M_PI / 7)); + TX_TAB(ff_tx_tab_7)[2] = RESCALE(sin(2 * M_PI / 28)); + TX_TAB(ff_tx_tab_7)[3] = RESCALE(cos(2 * M_PI / 28)); + TX_TAB(ff_tx_tab_7)[4] = RESCALE(cos(2 * M_PI / 14)); + TX_TAB(ff_tx_tab_7)[5] = RESCALE(sin(2 * M_PI / 14)); +} + +static av_cold void TX_TAB(ff_tx_init_tab_9)(void) +{ + TX_TAB(ff_tx_tab_9)[0] = RESCALE(cos(2 * M_PI / 3)); + TX_TAB(ff_tx_tab_9)[1] = RESCALE(sin(2 * M_PI / 3)); + TX_TAB(ff_tx_tab_9)[2] = RESCALE(cos(2 * M_PI / 9)); + TX_TAB(ff_tx_tab_9)[3] = RESCALE(sin(2 * M_PI / 9)); + TX_TAB(ff_tx_tab_9)[4] = RESCALE(cos(2 * M_PI / 36)); + TX_TAB(ff_tx_tab_9)[5] = RESCALE(sin(2 * M_PI / 36)); + TX_TAB(ff_tx_tab_9)[6] = TX_TAB(ff_tx_tab_9)[2] + TX_TAB(ff_tx_tab_9)[5]; + TX_TAB(ff_tx_tab_9)[7] = TX_TAB(ff_tx_tab_9)[3] - TX_TAB(ff_tx_tab_9)[4]; +} + +static const FFTabInitData nptwo_tabs_init_data[] = { + { TX_TAB(ff_tx_init_tab_53), { 15, 5, 3 } }, + { TX_TAB(ff_tx_init_tab_9), { 9 } }, + { TX_TAB(ff_tx_init_tab_7), { 7 } }, +}; + +static AVOnce nptwo_tabs_init_once[] = { + AV_ONCE_INIT, + AV_ONCE_INIT, + AV_ONCE_INIT, +}; + +av_cold void TX_TAB(ff_tx_init_tabs)(int len) +{ + int factor_2 = ff_ctz(len); + if (factor_2) { + int idx = factor_2 - 3; + for (int i = 0; i <= idx; i++) + ff_thread_once(&sr_tabs_init_once[i], + sr_tabs_init_funcs[i]); + len >>= factor_2; + } + + for (int i = 0; i < FF_ARRAY_ELEMS(nptwo_tabs_init_data); i++) { + int f, f_idx = 0; + + if (len <= 1) + return; + + while ((f = nptwo_tabs_init_data[i].factors[f_idx++])) { + if (f % len) + continue; + + ff_thread_once(&nptwo_tabs_init_once[i], + nptwo_tabs_init_data[i].func); + len /= f; + break; + } + } +} + +static av_always_inline void fft3(TXComplex *out, TXComplex *in, + ptrdiff_t stride) +{ + TXComplex tmp[3]; + const TXSample *tab = TX_TAB(ff_tx_tab_53); +#ifdef TX_INT32 + int64_t mtmp[4]; +#endif + + tmp[0] = in[0]; + BF(tmp[1].re, tmp[2].im, in[1].im, in[2].im); + BF(tmp[1].im, tmp[2].re, in[1].re, in[2].re); + + out[0*stride].re = tmp[0].re + tmp[2].re; + out[0*stride].im = tmp[0].im + tmp[2].im; + +#ifdef TX_INT32 + mtmp[0] = (int64_t)tab[ 8] * tmp[1].re; + mtmp[1] = (int64_t)tab[ 9] * tmp[1].im; + mtmp[2] = (int64_t)tab[10] * tmp[2].re; + mtmp[3] = (int64_t)tab[10] * tmp[2].im; + out[1*stride].re = tmp[0].re - (mtmp[2] + mtmp[0] + 0x40000000 >> 31); + out[1*stride].im = tmp[0].im - (mtmp[3] - mtmp[1] + 0x40000000 >> 31); + out[2*stride].re = tmp[0].re - (mtmp[2] - mtmp[0] + 0x40000000 >> 31); + out[2*stride].im = tmp[0].im - (mtmp[3] + mtmp[1] + 0x40000000 >> 31); +#else + tmp[1].re = tab[ 8] * tmp[1].re; + tmp[1].im = tab[ 9] * tmp[1].im; + tmp[2].re = tab[10] * tmp[2].re; + tmp[2].im = tab[10] * tmp[2].im; + out[1*stride].re = tmp[0].re - tmp[2].re + tmp[1].re; + out[1*stride].im = tmp[0].im - tmp[2].im - tmp[1].im; + out[2*stride].re = tmp[0].re - tmp[2].re - tmp[1].re; + out[2*stride].im = tmp[0].im - tmp[2].im + tmp[1].im; +#endif +} + +#define DECL_FFT5(NAME, D0, D1, D2, D3, D4) \ +static av_always_inline void NAME(TXComplex *out, TXComplex *in, \ + ptrdiff_t stride) \ +{ \ + TXComplex dc, z0[4], t[6]; \ + const TXSample *tab = TX_TAB(ff_tx_tab_53); \ + \ + dc = in[0]; \ + BF(t[1].im, t[0].re, in[1].re, in[4].re); \ + BF(t[1].re, t[0].im, in[1].im, in[4].im); \ + BF(t[3].im, t[2].re, in[2].re, in[3].re); \ + BF(t[3].re, t[2].im, in[2].im, in[3].im); \ + \ + out[D0*stride].re = dc.re + t[0].re + t[2].re; \ + out[D0*stride].im = dc.im + t[0].im + t[2].im; \ + \ + SMUL(t[4].re, t[0].re, tab[0], tab[2], t[2].re, t[0].re); \ + SMUL(t[4].im, t[0].im, tab[0], tab[2], t[2].im, t[0].im); \ + CMUL(t[5].re, t[1].re, tab[4], tab[6], t[3].re, t[1].re); \ + CMUL(t[5].im, t[1].im, tab[4], tab[6], t[3].im, t[1].im); \ + \ + BF(z0[0].re, z0[3].re, t[0].re, t[1].re); \ + BF(z0[0].im, z0[3].im, t[0].im, t[1].im); \ + BF(z0[2].re, z0[1].re, t[4].re, t[5].re); \ + BF(z0[2].im, z0[1].im, t[4].im, t[5].im); \ + \ + out[D1*stride].re = dc.re + z0[3].re; \ + out[D1*stride].im = dc.im + z0[0].im; \ + out[D2*stride].re = dc.re + z0[2].re; \ + out[D2*stride].im = dc.im + z0[1].im; \ + out[D3*stride].re = dc.re + z0[1].re; \ + out[D3*stride].im = dc.im + z0[2].im; \ + out[D4*stride].re = dc.re + z0[0].re; \ + out[D4*stride].im = dc.im + z0[3].im; \ +} + +DECL_FFT5(fft5, 0, 1, 2, 3, 4) +DECL_FFT5(fft5_m1, 0, 6, 12, 3, 9) +DECL_FFT5(fft5_m2, 10, 1, 7, 13, 4) +DECL_FFT5(fft5_m3, 5, 11, 2, 8, 14) + +static av_always_inline void fft7(TXComplex *out, TXComplex *in, + ptrdiff_t stride) +{ + TXComplex dc, t[6], z[3]; + const TXComplex *tab = (const TXComplex *)TX_TAB(ff_tx_tab_7); +#ifdef TX_INT32 + int64_t mtmp[12]; +#endif + + dc = in[0]; + BF(t[1].re, t[0].re, in[1].re, in[6].re); + BF(t[1].im, t[0].im, in[1].im, in[6].im); + BF(t[3].re, t[2].re, in[2].re, in[5].re); + BF(t[3].im, t[2].im, in[2].im, in[5].im); + BF(t[5].re, t[4].re, in[3].re, in[4].re); + BF(t[5].im, t[4].im, in[3].im, in[4].im); + + out[0*stride].re = dc.re + t[0].re + t[2].re + t[4].re; + out[0*stride].im = dc.im + t[0].im + t[2].im + t[4].im; + +#ifdef TX_INT32 /* NOTE: it's possible to do this with 16 mults but 72 adds */ + mtmp[ 0] = ((int64_t)tab[0].re)*t[0].re - ((int64_t)tab[2].re)*t[4].re; + mtmp[ 1] = ((int64_t)tab[0].re)*t[4].re - ((int64_t)tab[1].re)*t[0].re; + mtmp[ 2] = ((int64_t)tab[0].re)*t[2].re - ((int64_t)tab[2].re)*t[0].re; + mtmp[ 3] = ((int64_t)tab[0].re)*t[0].im - ((int64_t)tab[1].re)*t[2].im; + mtmp[ 4] = ((int64_t)tab[0].re)*t[4].im - ((int64_t)tab[1].re)*t[0].im; + mtmp[ 5] = ((int64_t)tab[0].re)*t[2].im - ((int64_t)tab[2].re)*t[0].im; + + mtmp[ 6] = ((int64_t)tab[2].im)*t[1].im + ((int64_t)tab[1].im)*t[5].im; + mtmp[ 7] = ((int64_t)tab[0].im)*t[5].im + ((int64_t)tab[2].im)*t[3].im; + mtmp[ 8] = ((int64_t)tab[2].im)*t[5].im + ((int64_t)tab[1].im)*t[3].im; + mtmp[ 9] = ((int64_t)tab[0].im)*t[1].re + ((int64_t)tab[1].im)*t[3].re; + mtmp[10] = ((int64_t)tab[2].im)*t[3].re + ((int64_t)tab[0].im)*t[5].re; + mtmp[11] = ((int64_t)tab[2].im)*t[1].re + ((int64_t)tab[1].im)*t[5].re; + + z[0].re = (int32_t)(mtmp[ 0] - ((int64_t)tab[1].re)*t[2].re + 0x40000000 >> 31); + z[1].re = (int32_t)(mtmp[ 1] - ((int64_t)tab[2].re)*t[2].re + 0x40000000 >> 31); + z[2].re = (int32_t)(mtmp[ 2] - ((int64_t)tab[1].re)*t[4].re + 0x40000000 >> 31); + z[0].im = (int32_t)(mtmp[ 3] - ((int64_t)tab[2].re)*t[4].im + 0x40000000 >> 31); + z[1].im = (int32_t)(mtmp[ 4] - ((int64_t)tab[2].re)*t[2].im + 0x40000000 >> 31); + z[2].im = (int32_t)(mtmp[ 5] - ((int64_t)tab[1].re)*t[4].im + 0x40000000 >> 31); + + t[0].re = (int32_t)(mtmp[ 6] - ((int64_t)tab[0].im)*t[3].im + 0x40000000 >> 31); + t[2].re = (int32_t)(mtmp[ 7] - ((int64_t)tab[1].im)*t[1].im + 0x40000000 >> 31); + t[4].re = (int32_t)(mtmp[ 8] + ((int64_t)tab[0].im)*t[1].im + 0x40000000 >> 31); + t[0].im = (int32_t)(mtmp[ 9] + ((int64_t)tab[2].im)*t[5].re + 0x40000000 >> 31); + t[2].im = (int32_t)(mtmp[10] - ((int64_t)tab[1].im)*t[1].re + 0x40000000 >> 31); + t[4].im = (int32_t)(mtmp[11] - ((int64_t)tab[0].im)*t[3].re + 0x40000000 >> 31); +#else + z[0].re = tab[0].re*t[0].re - tab[2].re*t[4].re - tab[1].re*t[2].re; + z[1].re = tab[0].re*t[4].re - tab[1].re*t[0].re - tab[2].re*t[2].re; + z[2].re = tab[0].re*t[2].re - tab[2].re*t[0].re - tab[1].re*t[4].re; + z[0].im = tab[0].re*t[0].im - tab[1].re*t[2].im - tab[2].re*t[4].im; + z[1].im = tab[0].re*t[4].im - tab[1].re*t[0].im - tab[2].re*t[2].im; + z[2].im = tab[0].re*t[2].im - tab[2].re*t[0].im - tab[1].re*t[4].im; + + /* It's possible to do t[4].re and t[0].im with 2 multiplies only by + * multiplying the sum of all with the average of the twiddles */ + + t[0].re = tab[2].im*t[1].im + tab[1].im*t[5].im - tab[0].im*t[3].im; + t[2].re = tab[0].im*t[5].im + tab[2].im*t[3].im - tab[1].im*t[1].im; + t[4].re = tab[2].im*t[5].im + tab[1].im*t[3].im + tab[0].im*t[1].im; + t[0].im = tab[0].im*t[1].re + tab[1].im*t[3].re + tab[2].im*t[5].re; + t[2].im = tab[2].im*t[3].re + tab[0].im*t[5].re - tab[1].im*t[1].re; + t[4].im = tab[2].im*t[1].re + tab[1].im*t[5].re - tab[0].im*t[3].re; +#endif + + BF(t[1].re, z[0].re, z[0].re, t[4].re); + BF(t[3].re, z[1].re, z[1].re, t[2].re); + BF(t[5].re, z[2].re, z[2].re, t[0].re); + BF(t[1].im, z[0].im, z[0].im, t[0].im); + BF(t[3].im, z[1].im, z[1].im, t[2].im); + BF(t[5].im, z[2].im, z[2].im, t[4].im); + + out[1*stride].re = dc.re + z[0].re; + out[1*stride].im = dc.im + t[1].im; + out[2*stride].re = dc.re + t[3].re; + out[2*stride].im = dc.im + z[1].im; + out[3*stride].re = dc.re + z[2].re; + out[3*stride].im = dc.im + t[5].im; + out[4*stride].re = dc.re + t[5].re; + out[4*stride].im = dc.im + z[2].im; + out[5*stride].re = dc.re + z[1].re; + out[5*stride].im = dc.im + t[3].im; + out[6*stride].re = dc.re + t[1].re; + out[6*stride].im = dc.im + z[0].im; +} + +static av_always_inline void fft9(TXComplex *out, TXComplex *in, + ptrdiff_t stride) +{ + const TXComplex *tab = (const TXComplex *)TX_TAB(ff_tx_tab_9); + TXComplex dc, t[16], w[4], x[5], y[5], z[2]; +#ifdef TX_INT32 + int64_t mtmp[12]; +#endif + + dc = in[0]; + BF(t[1].re, t[0].re, in[1].re, in[8].re); + BF(t[1].im, t[0].im, in[1].im, in[8].im); + BF(t[3].re, t[2].re, in[2].re, in[7].re); + BF(t[3].im, t[2].im, in[2].im, in[7].im); + BF(t[5].re, t[4].re, in[3].re, in[6].re); + BF(t[5].im, t[4].im, in[3].im, in[6].im); + BF(t[7].re, t[6].re, in[4].re, in[5].re); + BF(t[7].im, t[6].im, in[4].im, in[5].im); + + w[0].re = t[0].re - t[6].re; + w[0].im = t[0].im - t[6].im; + w[1].re = t[2].re - t[6].re; + w[1].im = t[2].im - t[6].im; + w[2].re = t[1].re - t[7].re; + w[2].im = t[1].im - t[7].im; + w[3].re = t[3].re + t[7].re; + w[3].im = t[3].im + t[7].im; + + z[0].re = dc.re + t[4].re; + z[0].im = dc.im + t[4].im; + + z[1].re = t[0].re + t[2].re + t[6].re; + z[1].im = t[0].im + t[2].im + t[6].im; + + out[0*stride].re = z[0].re + z[1].re; + out[0*stride].im = z[0].im + z[1].im; + +#ifdef TX_INT32 + mtmp[0] = t[1].re - t[3].re + t[7].re; + mtmp[1] = t[1].im - t[3].im + t[7].im; + + y[3].re = (int32_t)(((int64_t)tab[0].im)*mtmp[0] + 0x40000000 >> 31); + y[3].im = (int32_t)(((int64_t)tab[0].im)*mtmp[1] + 0x40000000 >> 31); + + mtmp[0] = (int32_t)(((int64_t)tab[0].re)*z[1].re + 0x40000000 >> 31); + mtmp[1] = (int32_t)(((int64_t)tab[0].re)*z[1].im + 0x40000000 >> 31); + mtmp[2] = (int32_t)(((int64_t)tab[0].re)*t[4].re + 0x40000000 >> 31); + mtmp[3] = (int32_t)(((int64_t)tab[0].re)*t[4].im + 0x40000000 >> 31); + + x[3].re = z[0].re + (int32_t)mtmp[0]; + x[3].im = z[0].im + (int32_t)mtmp[1]; + z[0].re = in[0].re + (int32_t)mtmp[2]; + z[0].im = in[0].im + (int32_t)mtmp[3]; + + mtmp[0] = ((int64_t)tab[1].re)*w[0].re; + mtmp[1] = ((int64_t)tab[1].re)*w[0].im; + mtmp[2] = ((int64_t)tab[2].im)*w[0].re; + mtmp[3] = ((int64_t)tab[2].im)*w[0].im; + mtmp[4] = ((int64_t)tab[1].im)*w[2].re; + mtmp[5] = ((int64_t)tab[1].im)*w[2].im; + mtmp[6] = ((int64_t)tab[2].re)*w[2].re; + mtmp[7] = ((int64_t)tab[2].re)*w[2].im; + + x[1].re = (int32_t)(mtmp[0] + ((int64_t)tab[2].im)*w[1].re + 0x40000000 >> 31); + x[1].im = (int32_t)(mtmp[1] + ((int64_t)tab[2].im)*w[1].im + 0x40000000 >> 31); + x[2].re = (int32_t)(mtmp[2] - ((int64_t)tab[3].re)*w[1].re + 0x40000000 >> 31); + x[2].im = (int32_t)(mtmp[3] - ((int64_t)tab[3].re)*w[1].im + 0x40000000 >> 31); + y[1].re = (int32_t)(mtmp[4] + ((int64_t)tab[2].re)*w[3].re + 0x40000000 >> 31); + y[1].im = (int32_t)(mtmp[5] + ((int64_t)tab[2].re)*w[3].im + 0x40000000 >> 31); + y[2].re = (int32_t)(mtmp[6] - ((int64_t)tab[3].im)*w[3].re + 0x40000000 >> 31); + y[2].im = (int32_t)(mtmp[7] - ((int64_t)tab[3].im)*w[3].im + 0x40000000 >> 31); + + y[0].re = (int32_t)(((int64_t)tab[0].im)*t[5].re + 0x40000000 >> 31); + y[0].im = (int32_t)(((int64_t)tab[0].im)*t[5].im + 0x40000000 >> 31); + +#else + y[3].re = tab[0].im*(t[1].re - t[3].re + t[7].re); + y[3].im = tab[0].im*(t[1].im - t[3].im + t[7].im); + + x[3].re = z[0].re + tab[0].re*z[1].re; + x[3].im = z[0].im + tab[0].re*z[1].im; + z[0].re = dc.re + tab[0].re*t[4].re; + z[0].im = dc.im + tab[0].re*t[4].im; + + x[1].re = tab[1].re*w[0].re + tab[2].im*w[1].re; + x[1].im = tab[1].re*w[0].im + tab[2].im*w[1].im; + x[2].re = tab[2].im*w[0].re - tab[3].re*w[1].re; + x[2].im = tab[2].im*w[0].im - tab[3].re*w[1].im; + y[1].re = tab[1].im*w[2].re + tab[2].re*w[3].re; + y[1].im = tab[1].im*w[2].im + tab[2].re*w[3].im; + y[2].re = tab[2].re*w[2].re - tab[3].im*w[3].re; + y[2].im = tab[2].re*w[2].im - tab[3].im*w[3].im; + + y[0].re = tab[0].im*t[5].re; + y[0].im = tab[0].im*t[5].im; +#endif + + x[4].re = x[1].re + x[2].re; + x[4].im = x[1].im + x[2].im; + + y[4].re = y[1].re - y[2].re; + y[4].im = y[1].im - y[2].im; + x[1].re = z[0].re + x[1].re; + x[1].im = z[0].im + x[1].im; + y[1].re = y[0].re + y[1].re; + y[1].im = y[0].im + y[1].im; + x[2].re = z[0].re + x[2].re; + x[2].im = z[0].im + x[2].im; + y[2].re = y[2].re - y[0].re; + y[2].im = y[2].im - y[0].im; + x[4].re = z[0].re - x[4].re; + x[4].im = z[0].im - x[4].im; + y[4].re = y[0].re - y[4].re; + y[4].im = y[0].im - y[4].im; + + out[1*stride] = (TXComplex){ x[1].re + y[1].im, x[1].im - y[1].re }; + out[2*stride] = (TXComplex){ x[2].re + y[2].im, x[2].im - y[2].re }; + out[3*stride] = (TXComplex){ x[3].re + y[3].im, x[3].im - y[3].re }; + out[4*stride] = (TXComplex){ x[4].re + y[4].im, x[4].im - y[4].re }; + out[5*stride] = (TXComplex){ x[4].re - y[4].im, x[4].im + y[4].re }; + out[6*stride] = (TXComplex){ x[3].re - y[3].im, x[3].im + y[3].re }; + out[7*stride] = (TXComplex){ x[2].re - y[2].im, x[2].im + y[2].re }; + out[8*stride] = (TXComplex){ x[1].re - y[1].im, x[1].im + y[1].re }; +} + +static av_always_inline void fft15(TXComplex *out, TXComplex *in, + ptrdiff_t stride) +{ + TXComplex tmp[15]; + + for (int i = 0; i < 5; i++) + fft3(tmp + i, in + i*3, 5); + + fft5_m1(out, tmp + 0, stride); + fft5_m2(out, tmp + 5, stride); + fft5_m3(out, tmp + 10, stride); +} + +static av_cold int TX_NAME(ff_tx_fft_factor_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret = 0; + TX_TAB(ff_tx_init_tabs)(len); + + if (len == 15) + ret = ff_tx_gen_pfa_input_map(s, opts, 3, 5); + else if (flags & FF_TX_PRESHUFFLE) + ret = ff_tx_gen_default_map(s, opts); + + return ret; +} + +#define DECL_FACTOR_S(n) \ +static void TX_NAME(ff_tx_fft##n)(AVTXContext *s, void *dst, \ + void *src, ptrdiff_t stride) \ +{ \ + fft##n((TXComplex *)dst, (TXComplex *)src, stride / sizeof(TXComplex)); \ +} \ +static const FFTXCodelet TX_NAME(ff_tx_fft##n##_ns_def) = { \ + .name = TX_NAME_STR("fft" #n "_ns"), \ + .function = TX_NAME(ff_tx_fft##n), \ + .type = TX_TYPE(FFT), \ + .flags = AV_TX_INPLACE | FF_TX_OUT_OF_PLACE | \ + AV_TX_UNALIGNED | FF_TX_PRESHUFFLE, \ + .factors[0] = n, \ + .nb_factors = 1, \ + .min_len = n, \ + .max_len = n, \ + .init = TX_NAME(ff_tx_fft_factor_init), \ + .cpu_flags = FF_TX_CPU_FLAGS_ALL, \ + .prio = FF_TX_PRIO_BASE, \ +}; + +#define DECL_FACTOR_F(n) \ +DECL_FACTOR_S(n) \ +static const FFTXCodelet TX_NAME(ff_tx_fft##n##_fwd_def) = { \ + .name = TX_NAME_STR("fft" #n "_fwd"), \ + .function = TX_NAME(ff_tx_fft##n), \ + .type = TX_TYPE(FFT), \ + .flags = AV_TX_INPLACE | FF_TX_OUT_OF_PLACE | \ + AV_TX_UNALIGNED | FF_TX_FORWARD_ONLY, \ + .factors[0] = n, \ + .nb_factors = 1, \ + .min_len = n, \ + .max_len = n, \ + .init = TX_NAME(ff_tx_fft_factor_init), \ + .cpu_flags = FF_TX_CPU_FLAGS_ALL, \ + .prio = FF_TX_PRIO_BASE, \ +}; + +DECL_FACTOR_F(3) +DECL_FACTOR_F(5) +DECL_FACTOR_F(7) +DECL_FACTOR_F(9) +DECL_FACTOR_S(15) + +#define BUTTERFLIES(a0, a1, a2, a3) \ + do { \ + r0=a0.re; \ + i0=a0.im; \ + r1=a1.re; \ + i1=a1.im; \ + BF(t3, t5, t5, t1); \ + BF(a2.re, a0.re, r0, t5); \ + BF(a3.im, a1.im, i1, t3); \ + BF(t4, t6, t2, t6); \ + BF(a3.re, a1.re, r1, t4); \ + BF(a2.im, a0.im, i0, t6); \ + } while (0) + +#define TRANSFORM(a0, a1, a2, a3, wre, wim) \ + do { \ + CMUL(t1, t2, a2.re, a2.im, wre, -wim); \ + CMUL(t5, t6, a3.re, a3.im, wre, wim); \ + BUTTERFLIES(a0, a1, a2, a3); \ + } while (0) + +/* z[0...8n-1], w[1...2n-1] */ +static inline void TX_NAME(ff_tx_fft_sr_combine)(TXComplex *z, + const TXSample *cos, int len) +{ + int o1 = 2*len; + int o2 = 4*len; + int o3 = 6*len; + const TXSample *wim = cos + o1 - 7; + TXUSample t1, t2, t3, t4, t5, t6, r0, i0, r1, i1; + + for (int i = 0; i < len; i += 4) { + TRANSFORM(z[0], z[o1 + 0], z[o2 + 0], z[o3 + 0], cos[0], wim[7]); + TRANSFORM(z[2], z[o1 + 2], z[o2 + 2], z[o3 + 2], cos[2], wim[5]); + TRANSFORM(z[4], z[o1 + 4], z[o2 + 4], z[o3 + 4], cos[4], wim[3]); + TRANSFORM(z[6], z[o1 + 6], z[o2 + 6], z[o3 + 6], cos[6], wim[1]); + + TRANSFORM(z[1], z[o1 + 1], z[o2 + 1], z[o3 + 1], cos[1], wim[6]); + TRANSFORM(z[3], z[o1 + 3], z[o2 + 3], z[o3 + 3], cos[3], wim[4]); + TRANSFORM(z[5], z[o1 + 5], z[o2 + 5], z[o3 + 5], cos[5], wim[2]); + TRANSFORM(z[7], z[o1 + 7], z[o2 + 7], z[o3 + 7], cos[7], wim[0]); + + z += 2*4; + cos += 2*4; + wim -= 2*4; + } +} + +static av_cold int TX_NAME(ff_tx_fft_sr_codelet_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + TX_TAB(ff_tx_init_tabs)(len); + return ff_tx_gen_ptwo_revtab(s, opts); +} + +#define DECL_SR_CODELET_DEF(n) \ +static const FFTXCodelet TX_NAME(ff_tx_fft##n##_ns_def) = { \ + .name = TX_NAME_STR("fft" #n "_ns"), \ + .function = TX_NAME(ff_tx_fft##n##_ns), \ + .type = TX_TYPE(FFT), \ + .flags = FF_TX_OUT_OF_PLACE | AV_TX_INPLACE | \ + AV_TX_UNALIGNED | FF_TX_PRESHUFFLE, \ + .factors[0] = 2, \ + .nb_factors = 1, \ + .min_len = n, \ + .max_len = n, \ + .init = TX_NAME(ff_tx_fft_sr_codelet_init), \ + .cpu_flags = FF_TX_CPU_FLAGS_ALL, \ + .prio = FF_TX_PRIO_BASE, \ +}; + +#define DECL_SR_CODELET(n, n2, n4) \ +static void TX_NAME(ff_tx_fft##n##_ns)(AVTXContext *s, void *_dst, \ + void *_src, ptrdiff_t stride) \ +{ \ + TXComplex *src = _src; \ + TXComplex *dst = _dst; \ + const TXSample *cos = TX_TAB(ff_tx_tab_##n); \ + \ + TX_NAME(ff_tx_fft##n2##_ns)(s, dst, src, stride); \ + TX_NAME(ff_tx_fft##n4##_ns)(s, dst + n4*2, src + n4*2, stride); \ + TX_NAME(ff_tx_fft##n4##_ns)(s, dst + n4*3, src + n4*3, stride); \ + TX_NAME(ff_tx_fft_sr_combine)(dst, cos, n4 >> 1); \ +} \ + \ +DECL_SR_CODELET_DEF(n) + +static void TX_NAME(ff_tx_fft2_ns)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + TXComplex tmp; + + BF(tmp.re, dst[0].re, src[0].re, src[1].re); + BF(tmp.im, dst[0].im, src[0].im, src[1].im); + dst[1] = tmp; +} + +static void TX_NAME(ff_tx_fft4_ns)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + TXSample t1, t2, t3, t4, t5, t6, t7, t8; + + BF(t3, t1, src[0].re, src[1].re); + BF(t8, t6, src[3].re, src[2].re); + BF(dst[2].re, dst[0].re, t1, t6); + BF(t4, t2, src[0].im, src[1].im); + BF(t7, t5, src[2].im, src[3].im); + BF(dst[3].im, dst[1].im, t4, t8); + BF(dst[3].re, dst[1].re, t3, t7); + BF(dst[2].im, dst[0].im, t2, t5); +} + +static void TX_NAME(ff_tx_fft8_ns)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + TXUSample t1, t2, t3, t4, t5, t6, r0, i0, r1, i1; + const TXSample cos = TX_TAB(ff_tx_tab_8)[1]; + + TX_NAME(ff_tx_fft4_ns)(s, dst, src, stride); + + BF(t1, dst[5].re, src[4].re, -src[5].re); + BF(t2, dst[5].im, src[4].im, -src[5].im); + BF(t5, dst[7].re, src[6].re, -src[7].re); + BF(t6, dst[7].im, src[6].im, -src[7].im); + + BUTTERFLIES(dst[0], dst[2], dst[4], dst[6]); + TRANSFORM(dst[1], dst[3], dst[5], dst[7], cos, cos); +} + +static void TX_NAME(ff_tx_fft16_ns)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + const TXSample *cos = TX_TAB(ff_tx_tab_16); + + TXUSample t1, t2, t3, t4, t5, t6, r0, i0, r1, i1; + TXSample cos_16_1 = cos[1]; + TXSample cos_16_2 = cos[2]; + TXSample cos_16_3 = cos[3]; + + TX_NAME(ff_tx_fft8_ns)(s, dst + 0, src + 0, stride); + TX_NAME(ff_tx_fft4_ns)(s, dst + 8, src + 8, stride); + TX_NAME(ff_tx_fft4_ns)(s, dst + 12, src + 12, stride); + + t1 = dst[ 8].re; + t2 = dst[ 8].im; + t5 = dst[12].re; + t6 = dst[12].im; + BUTTERFLIES(dst[0], dst[4], dst[8], dst[12]); + + TRANSFORM(dst[ 2], dst[ 6], dst[10], dst[14], cos_16_2, cos_16_2); + TRANSFORM(dst[ 1], dst[ 5], dst[ 9], dst[13], cos_16_1, cos_16_3); + TRANSFORM(dst[ 3], dst[ 7], dst[11], dst[15], cos_16_3, cos_16_1); +} + +DECL_SR_CODELET_DEF(2) +DECL_SR_CODELET_DEF(4) +DECL_SR_CODELET_DEF(8) +DECL_SR_CODELET_DEF(16) +DECL_SR_CODELET(32,16,8) +DECL_SR_CODELET(64,32,16) +DECL_SR_CODELET(128,64,32) +DECL_SR_CODELET(256,128,64) +DECL_SR_CODELET(512,256,128) +DECL_SR_CODELET(1024,512,256) +DECL_SR_CODELET(2048,1024,512) +DECL_SR_CODELET(4096,2048,1024) +DECL_SR_CODELET(8192,4096,2048) +DECL_SR_CODELET(16384,8192,4096) +DECL_SR_CODELET(32768,16384,8192) +DECL_SR_CODELET(65536,32768,16384) +DECL_SR_CODELET(131072,65536,32768) + +static av_cold int TX_NAME(ff_tx_fft_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + int is_inplace = !!(flags & AV_TX_INPLACE); + FFTXCodeletOptions sub_opts = { + .map_dir = is_inplace ? FF_TX_MAP_SCATTER : FF_TX_MAP_GATHER, + }; + + flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */ + flags |= AV_TX_INPLACE; /* in-place */ + flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */ + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, len, inv, scale))) + return ret; + + if (is_inplace && (ret = ff_tx_gen_inplace_map(s, len))) + return ret; + + return 0; +} + +static av_cold int TX_NAME(ff_tx_fft_inplace_small_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + if (!(s->tmp = av_malloc(len*sizeof(*s->tmp)))) + return AVERROR(ENOMEM); + flags &= ~AV_TX_INPLACE; + return TX_NAME(ff_tx_fft_init)(s, cd, flags, opts, len, inv, scale); +} + +static void TX_NAME(ff_tx_fft)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst1 = s->flags & AV_TX_INPLACE ? s->tmp : _dst; + TXComplex *dst2 = _dst; + int *map = s->sub[0].map; + int len = s->len; + + /* Compilers can't vectorize this anyway without assuming AVX2, which they + * generally don't, at least without -march=native -mtune=native */ + for (int i = 0; i < len; i++) + dst1[i] = src[map[i]]; + + s->fn[0](&s->sub[0], dst2, dst1, stride); +} + +static void TX_NAME(ff_tx_fft_inplace)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + TXComplex tmp; + const int *map = s->sub->map; + const int *inplace_idx = s->map; + int src_idx, dst_idx; + + src_idx = *inplace_idx++; + do { + tmp = src[src_idx]; + dst_idx = map[src_idx]; + do { + FFSWAP(TXComplex, tmp, src[dst_idx]); + dst_idx = map[dst_idx]; + } while (dst_idx != src_idx); /* Can be > as well, but was less predictable */ + src[dst_idx] = tmp; + } while ((src_idx = *inplace_idx++)); + + s->fn[0](&s->sub[0], dst, src, stride); +} + +static const FFTXCodelet TX_NAME(ff_tx_fft_def) = { + .name = TX_NAME_STR("fft"), + .function = TX_NAME(ff_tx_fft), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE, + .factors[0] = TX_FACTOR_ANY, + .nb_factors = 1, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_fft_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static const FFTXCodelet TX_NAME(ff_tx_fft_inplace_small_def) = { + .name = TX_NAME_STR("fft_inplace_small"), + .function = TX_NAME(ff_tx_fft), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | AV_TX_INPLACE, + .factors[0] = TX_FACTOR_ANY, + .nb_factors = 1, + .min_len = 2, + .max_len = 65536, + .init = TX_NAME(ff_tx_fft_inplace_small_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE - 256, +}; + +static const FFTXCodelet TX_NAME(ff_tx_fft_inplace_def) = { + .name = TX_NAME_STR("fft_inplace"), + .function = TX_NAME(ff_tx_fft_inplace), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | AV_TX_INPLACE, + .factors[0] = TX_FACTOR_ANY, + .nb_factors = 1, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_fft_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE - 512, +}; + +static av_cold int TX_NAME(ff_tx_fft_init_naive_small)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + const double phase = s->inv ? 2.0*M_PI/len : -2.0*M_PI/len; + + if (!(s->exp = av_malloc(len*len*sizeof(*s->exp)))) + return AVERROR(ENOMEM); + + for (int i = 0; i < len; i++) { + for (int j = 0; j < len; j++) { + const double factor = phase*i*j; + s->exp[i*j] = (TXComplex){ + RESCALE(cos(factor)), + RESCALE(sin(factor)), + }; + } + } + + return 0; +} + +static void TX_NAME(ff_tx_fft_naive)(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + const int n = s->len; + double phase = s->inv ? 2.0*M_PI/n : -2.0*M_PI/n; + + stride /= sizeof(*dst); + + for (int i = 0; i < n; i++) { + TXComplex tmp = { 0 }; + for (int j = 0; j < n; j++) { + const double factor = phase*i*j; + const TXComplex mult = { + RESCALE(cos(factor)), + RESCALE(sin(factor)), + }; + TXComplex res; + CMUL3(res, src[j], mult); + tmp.re += res.re; + tmp.im += res.im; + } + dst[i*stride] = tmp; + } +} + +static void TX_NAME(ff_tx_fft_naive_small)(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + TXComplex *src = _src; + TXComplex *dst = _dst; + const int n = s->len; + + stride /= sizeof(*dst); + + for (int i = 0; i < n; i++) { + TXComplex tmp = { 0 }; + for (int j = 0; j < n; j++) { + TXComplex res; + const TXComplex mult = s->exp[i*j]; + CMUL3(res, src[j], mult); + tmp.re += res.re; + tmp.im += res.im; + } + dst[i*stride] = tmp; + } +} + +static const FFTXCodelet TX_NAME(ff_tx_fft_naive_small_def) = { + .name = TX_NAME_STR("fft_naive_small"), + .function = TX_NAME(ff_tx_fft_naive_small), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE, + .factors[0] = TX_FACTOR_ANY, + .nb_factors = 1, + .min_len = 2, + .max_len = 1024, + .init = TX_NAME(ff_tx_fft_init_naive_small), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_MIN/2, +}; + +static const FFTXCodelet TX_NAME(ff_tx_fft_naive_def) = { + .name = TX_NAME_STR("fft_naive"), + .function = TX_NAME(ff_tx_fft_naive), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE, + .factors[0] = TX_FACTOR_ANY, + .nb_factors = 1, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = NULL, + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_MIN, +}; + +static av_cold int TX_NAME(ff_tx_fft_pfa_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret, *tmp, ps = flags & FF_TX_PRESHUFFLE; + FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_GATHER }; + size_t extra_tmp_len = 0; + int len_list[TX_MAX_DECOMPOSITIONS]; + + if ((ret = ff_tx_decompose_length(len_list, TX_TYPE(FFT), len, inv)) < 0) + return ret; + + /* Two iterations to test both orderings. */ + for (int i = 0; i < ret; i++) { + int len1 = len_list[i]; + int len2 = len / len1; + + /* Our ptwo transforms don't support striding the output. */ + if (len2 & (len2 - 1)) + FFSWAP(int, len1, len2); + + ff_tx_clear_ctx(s); + + /* First transform */ + sub_opts.map_dir = FF_TX_MAP_GATHER; + flags &= ~AV_TX_INPLACE; + flags |= FF_TX_OUT_OF_PLACE; + flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */ + ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + len1, inv, scale); + + if (ret == AVERROR(ENOMEM)) { + return ret; + } else if (ret < 0) { /* Try again without a preshuffle flag */ + flags &= ~FF_TX_PRESHUFFLE; + ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + len1, inv, scale); + if (ret == AVERROR(ENOMEM)) + return ret; + else if (ret < 0) + continue; + } + + /* Second transform. */ + sub_opts.map_dir = FF_TX_MAP_SCATTER; + flags |= FF_TX_PRESHUFFLE; +retry: + flags &= ~FF_TX_OUT_OF_PLACE; + flags |= AV_TX_INPLACE; + ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + len2, inv, scale); + + if (ret == AVERROR(ENOMEM)) { + return ret; + } else if (ret < 0) { /* Try again with an out-of-place transform */ + flags |= FF_TX_OUT_OF_PLACE; + flags &= ~AV_TX_INPLACE; + ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + len2, inv, scale); + if (ret == AVERROR(ENOMEM)) { + return ret; + } else if (ret < 0) { + if (flags & FF_TX_PRESHUFFLE) { /* Retry again without a preshuf flag */ + flags &= ~FF_TX_PRESHUFFLE; + goto retry; + } else { + continue; + } + } + } + + /* Success */ + break; + } + + /* If nothing was sucessful, error out */ + if (ret < 0) + return ret; + + /* Generate PFA map */ + if ((ret = ff_tx_gen_compound_mapping(s, opts, 0, + s->sub[0].len, s->sub[1].len))) + return ret; + + if (!(s->tmp = av_malloc(len*sizeof(*s->tmp)))) + return AVERROR(ENOMEM); + + /* Flatten input map */ + tmp = (int *)s->tmp; + for (int k = 0; k < len; k += s->sub[0].len) { + memcpy(tmp, &s->map[k], s->sub[0].len*sizeof(*tmp)); + for (int i = 0; i < s->sub[0].len; i++) + s->map[k + i] = tmp[s->sub[0].map[i]]; + } + + /* Only allocate extra temporary memory if we need it */ + if (!(s->sub[1].flags & AV_TX_INPLACE)) + extra_tmp_len = len; + else if (!ps) + extra_tmp_len = s->sub[0].len; + + if (extra_tmp_len && !(s->exp = av_malloc(extra_tmp_len*sizeof(*s->exp)))) + return AVERROR(ENOMEM); + + return 0; +} + +static void TX_NAME(ff_tx_fft_pfa)(AVTXContext *s, void *_out, + void *_in, ptrdiff_t stride) +{ + const int n = s->sub[0].len, m = s->sub[1].len, l = s->len; + const int *in_map = s->map, *out_map = in_map + l; + const int *sub_map = s->sub[1].map; + TXComplex *tmp1 = s->sub[1].flags & AV_TX_INPLACE ? s->tmp : s->exp; + TXComplex *in = _in, *out = _out; + + stride /= sizeof(*out); + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) + s->exp[j] = in[in_map[i*n + j]]; + s->fn[0](&s->sub[0], &s->tmp[sub_map[i]], s->exp, m*sizeof(TXComplex)); + } + + for (int i = 0; i < n; i++) + s->fn[1](&s->sub[1], &tmp1[m*i], &s->tmp[m*i], sizeof(TXComplex)); + + for (int i = 0; i < l; i++) + out[i*stride] = tmp1[out_map[i]]; +} + +static void TX_NAME(ff_tx_fft_pfa_ns)(AVTXContext *s, void *_out, + void *_in, ptrdiff_t stride) +{ + const int n = s->sub[0].len, m = s->sub[1].len, l = s->len; + const int *in_map = s->map, *out_map = in_map + l; + const int *sub_map = s->sub[1].map; + TXComplex *tmp1 = s->sub[1].flags & AV_TX_INPLACE ? s->tmp : s->exp; + TXComplex *in = _in, *out = _out; + + stride /= sizeof(*out); + + for (int i = 0; i < m; i++) + s->fn[0](&s->sub[0], &s->tmp[sub_map[i]], &in[i*n], m*sizeof(TXComplex)); + + for (int i = 0; i < n; i++) + s->fn[1](&s->sub[1], &tmp1[m*i], &s->tmp[m*i], sizeof(TXComplex)); + + for (int i = 0; i < l; i++) + out[i*stride] = tmp1[out_map[i]]; +} + +static const FFTXCodelet TX_NAME(ff_tx_fft_pfa_def) = { + .name = TX_NAME_STR("fft_pfa"), + .function = TX_NAME(ff_tx_fft_pfa), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | FF_TX_OUT_OF_PLACE, + .factors = { 7, 5, 3, 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2*3, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_fft_pfa_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static const FFTXCodelet TX_NAME(ff_tx_fft_pfa_ns_def) = { + .name = TX_NAME_STR("fft_pfa_ns"), + .function = TX_NAME(ff_tx_fft_pfa_ns), + .type = TX_TYPE(FFT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | FF_TX_OUT_OF_PLACE | + FF_TX_PRESHUFFLE, + .factors = { 7, 5, 3, 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2*3, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_fft_pfa_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static av_cold int TX_NAME(ff_tx_mdct_naive_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + return 0; +} + +static void TX_NAME(ff_tx_mdct_naive_fwd)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXSample *src = _src; + TXSample *dst = _dst; + double scale = s->scale_d; + int len = s->len; + const double phase = M_PI/(4.0*len); + + stride /= sizeof(*dst); + + for (int i = 0; i < len; i++) { + double sum = 0.0; + for (int j = 0; j < len*2; j++) { + int a = (2*j + 1 + len) * (2*i + 1); + sum += UNSCALE(src[j]) * cos(a * phase); + } + dst[i*stride] = RESCALE(sum*scale); + } +} + +static void TX_NAME(ff_tx_mdct_naive_inv)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXSample *src = _src; + TXSample *dst = _dst; + double scale = s->scale_d; + int len = s->len >> 1; + int len2 = len*2; + const double phase = M_PI/(4.0*len2); + + stride /= sizeof(*src); + + for (int i = 0; i < len; i++) { + double sum_d = 0.0; + double sum_u = 0.0; + double i_d = phase * (4*len - 2*i - 1); + double i_u = phase * (3*len2 + 2*i + 1); + for (int j = 0; j < len2; j++) { + double a = (2 * j + 1); + double a_d = cos(a * i_d); + double a_u = cos(a * i_u); + double val = UNSCALE(src[j*stride]); + sum_d += a_d * val; + sum_u += a_u * val; + } + dst[i + 0] = RESCALE( sum_d*scale); + dst[i + len] = RESCALE(-sum_u*scale); + } +} + +static const FFTXCodelet TX_NAME(ff_tx_mdct_naive_fwd_def) = { + .name = TX_NAME_STR("mdct_naive_fwd"), + .function = TX_NAME(ff_tx_mdct_naive_fwd), + .type = TX_TYPE(MDCT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_FORWARD_ONLY, + .factors = { 2, TX_FACTOR_ANY }, /* MDCTs need an even length */ + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_mdct_naive_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_MIN, +}; + +static const FFTXCodelet TX_NAME(ff_tx_mdct_naive_inv_def) = { + .name = TX_NAME_STR("mdct_naive_inv"), + .function = TX_NAME(ff_tx_mdct_naive_inv), + .type = TX_TYPE(MDCT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_INVERSE_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_mdct_naive_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_MIN, +}; + +static av_cold int TX_NAME(ff_tx_mdct_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + FFTXCodeletOptions sub_opts = { + .map_dir = !inv ? FF_TX_MAP_SCATTER : FF_TX_MAP_GATHER, + }; + + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + + flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */ + flags |= AV_TX_INPLACE; /* in-place */ + flags |= FF_TX_PRESHUFFLE; /* First try with an in-place transform */ + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, len >> 1, + inv, scale))) { + flags &= ~FF_TX_PRESHUFFLE; /* Now try with a generic FFT */ + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, len >> 1, + inv, scale))) + return ret; + } + + s->map = av_malloc((len >> 1)*sizeof(*s->map)); + if (!s->map) + return AVERROR(ENOMEM); + + /* If we need to preshuffle copy the map from the subcontext */ + if (s->sub[0].flags & FF_TX_PRESHUFFLE) { + memcpy(s->map, s->sub->map, (len >> 1)*sizeof(*s->map)); + } else { + for (int i = 0; i < len >> 1; i++) + s->map[i] = i; + } + + if ((ret = TX_TAB(ff_tx_mdct_gen_exp)(s, inv ? s->map : NULL))) + return ret; + + /* Saves a multiply in a hot path. */ + if (inv) + for (int i = 0; i < (s->len >> 1); i++) + s->map[i] <<= 1; + + return 0; +} + +static void TX_NAME(ff_tx_mdct_fwd)(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + TXSample *src = _src, *dst = _dst; + TXComplex *exp = s->exp, tmp, *z = _dst; + const int len2 = s->len >> 1; + const int len4 = s->len >> 2; + const int len3 = len2 * 3; + const int *sub_map = s->map; + + stride /= sizeof(*dst); + + for (int i = 0; i < len2; i++) { /* Folding and pre-reindexing */ + const int k = 2*i; + const int idx = sub_map[i]; + if (k < len2) { + tmp.re = FOLD(-src[ len2 + k], src[1*len2 - 1 - k]); + tmp.im = FOLD(-src[ len3 + k], -src[1*len3 - 1 - k]); + } else { + tmp.re = FOLD(-src[ len2 + k], -src[5*len2 - 1 - k]); + tmp.im = FOLD( src[-len2 + k], -src[1*len3 - 1 - k]); + } + CMUL(z[idx].im, z[idx].re, tmp.re, tmp.im, exp[i].re, exp[i].im); + } + + s->fn[0](&s->sub[0], z, z, sizeof(TXComplex)); + + for (int i = 0; i < len4; i++) { + const int i0 = len4 + i, i1 = len4 - i - 1; + TXComplex src1 = { z[i1].re, z[i1].im }; + TXComplex src0 = { z[i0].re, z[i0].im }; + + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], src0.re, src0.im, + exp[i0].im, exp[i0].re); + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], src1.re, src1.im, + exp[i1].im, exp[i1].re); + } +} + +static void TX_NAME(ff_tx_mdct_inv)(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + TXComplex *z = _dst, *exp = s->exp; + const TXSample *src = _src, *in1, *in2; + const int len2 = s->len >> 1; + const int len4 = s->len >> 2; + const int *sub_map = s->map; + + stride /= sizeof(*src); + in1 = src; + in2 = src + ((len2*2) - 1) * stride; + + for (int i = 0; i < len2; i++) { + int k = sub_map[i]; + TXComplex tmp = { in2[-k*stride], in1[k*stride] }; + CMUL3(z[i], tmp, exp[i]); + } + + s->fn[0](&s->sub[0], z, z, sizeof(TXComplex)); + + exp += len2; + for (int i = 0; i < len4; i++) { + const int i0 = len4 + i, i1 = len4 - i - 1; + TXComplex src1 = { z[i1].im, z[i1].re }; + TXComplex src0 = { z[i0].im, z[i0].re }; + + CMUL(z[i1].re, z[i0].im, src1.re, src1.im, exp[i1].im, exp[i1].re); + CMUL(z[i0].re, z[i1].im, src0.re, src0.im, exp[i0].im, exp[i0].re); + } +} + +static const FFTXCodelet TX_NAME(ff_tx_mdct_fwd_def) = { + .name = TX_NAME_STR("mdct_fwd"), + .function = TX_NAME(ff_tx_mdct_fwd), + .type = TX_TYPE(MDCT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_FORWARD_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_mdct_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static const FFTXCodelet TX_NAME(ff_tx_mdct_inv_def) = { + .name = TX_NAME_STR("mdct_inv"), + .function = TX_NAME(ff_tx_mdct_inv), + .type = TX_TYPE(MDCT), + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_INVERSE_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_mdct_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static av_cold int TX_NAME(ff_tx_mdct_inv_full_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + + flags &= ~AV_TX_FULL_IMDCT; + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(MDCT), flags, NULL, len, 1, scale))) + return ret; + + return 0; +} + +static void TX_NAME(ff_tx_mdct_inv_full)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + int len = s->len << 1; + int len2 = len >> 1; + int len4 = len >> 2; + TXSample *dst = _dst; + + s->fn[0](&s->sub[0], dst + len4, _src, stride); + + stride /= sizeof(*dst); + + for (int i = 0; i < len4; i++) { + dst[ i*stride] = -dst[(len2 - i - 1)*stride]; + dst[(len - i - 1)*stride] = dst[(len2 + i + 0)*stride]; + } +} + +static const FFTXCodelet TX_NAME(ff_tx_mdct_inv_full_def) = { + .name = TX_NAME_STR("mdct_inv_full"), + .function = TX_NAME(ff_tx_mdct_inv_full), + .type = TX_TYPE(MDCT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | + FF_TX_OUT_OF_PLACE | AV_TX_FULL_IMDCT, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_mdct_inv_full_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static av_cold int TX_NAME(ff_tx_mdct_pfa_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret, sub_len; + FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_SCATTER }; + + len >>= 1; + sub_len = len / cd->factors[0]; + + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + + flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */ + flags |= AV_TX_INPLACE; /* in-place */ + flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */ + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + sub_len, inv, scale))) + return ret; + + if ((ret = ff_tx_gen_compound_mapping(s, opts, s->inv, cd->factors[0], sub_len))) + return ret; + + /* Our 15-point transform is also a compound one, so embed its input map */ + if (cd->factors[0] == 15) + TX_EMBED_INPUT_PFA_MAP(s->map, len, 3, 5); + + if ((ret = TX_TAB(ff_tx_mdct_gen_exp)(s, inv ? s->map : NULL))) + return ret; + + /* Saves multiplies in loops. */ + for (int i = 0; i < len; i++) + s->map[i] <<= 1; + + if (!(s->tmp = av_malloc(len*sizeof(*s->tmp)))) + return AVERROR(ENOMEM); + + TX_TAB(ff_tx_init_tabs)(len / sub_len); + + return 0; +} + +#define DECL_COMP_IMDCT(N) \ +static void TX_NAME(ff_tx_mdct_pfa_##N##xM_inv)(AVTXContext *s, void *_dst, \ + void *_src, ptrdiff_t stride) \ +{ \ + TXComplex fft##N##in[N]; \ + TXComplex *z = _dst, *exp = s->exp; \ + const TXSample *src = _src, *in1, *in2; \ + const int len4 = s->len >> 2; \ + const int len2 = s->len >> 1; \ + const int m = s->sub->len; \ + const int *in_map = s->map, *out_map = in_map + N*m; \ + const int *sub_map = s->sub->map; \ + \ + stride /= sizeof(*src); /* To convert it from bytes */ \ + in1 = src; \ + in2 = src + ((N*m*2) - 1) * stride; \ + \ + for (int i = 0; i < len2; i += N) { \ + for (int j = 0; j < N; j++) { \ + const int k = in_map[j]; \ + TXComplex tmp = { in2[-k*stride], in1[k*stride] }; \ + CMUL3(fft##N##in[j], tmp, exp[j]); \ + } \ + fft##N(s->tmp + *(sub_map++), fft##N##in, m); \ + exp += N; \ + in_map += N; \ + } \ + \ + for (int i = 0; i < N; i++) \ + s->fn[0](&s->sub[0], s->tmp + m*i, s->tmp + m*i, sizeof(TXComplex)); \ + \ + for (int i = 0; i < len4; i++) { \ + const int i0 = len4 + i, i1 = len4 - i - 1; \ + const int s0 = out_map[i0], s1 = out_map[i1]; \ + TXComplex src1 = { s->tmp[s1].im, s->tmp[s1].re }; \ + TXComplex src0 = { s->tmp[s0].im, s->tmp[s0].re }; \ + \ + CMUL(z[i1].re, z[i0].im, src1.re, src1.im, exp[i1].im, exp[i1].re); \ + CMUL(z[i0].re, z[i1].im, src0.re, src0.im, exp[i0].im, exp[i0].re); \ + } \ +} \ + \ +static const FFTXCodelet TX_NAME(ff_tx_mdct_pfa_##N##xM_inv_def) = { \ + .name = TX_NAME_STR("mdct_pfa_" #N "xM_inv"), \ + .function = TX_NAME(ff_tx_mdct_pfa_##N##xM_inv), \ + .type = TX_TYPE(MDCT), \ + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_INVERSE_ONLY, \ + .factors = { N, TX_FACTOR_ANY }, \ + .nb_factors = 2, \ + .min_len = N*2, \ + .max_len = TX_LEN_UNLIMITED, \ + .init = TX_NAME(ff_tx_mdct_pfa_init), \ + .cpu_flags = FF_TX_CPU_FLAGS_ALL, \ + .prio = FF_TX_PRIO_BASE, \ +}; + +DECL_COMP_IMDCT(3) +DECL_COMP_IMDCT(5) +DECL_COMP_IMDCT(7) +DECL_COMP_IMDCT(9) +DECL_COMP_IMDCT(15) + +#define DECL_COMP_MDCT(N) \ +static void TX_NAME(ff_tx_mdct_pfa_##N##xM_fwd)(AVTXContext *s, void *_dst, \ + void *_src, ptrdiff_t stride) \ +{ \ + TXComplex fft##N##in[N]; \ + TXSample *src = _src, *dst = _dst; \ + TXComplex *exp = s->exp, tmp; \ + const int m = s->sub->len; \ + const int len4 = N*m; \ + const int len3 = len4 * 3; \ + const int len8 = s->len >> 2; \ + const int *in_map = s->map, *out_map = in_map + N*m; \ + const int *sub_map = s->sub->map; \ + \ + stride /= sizeof(*dst); \ + \ + for (int i = 0; i < m; i++) { /* Folding and pre-reindexing */ \ + for (int j = 0; j < N; j++) { \ + const int k = in_map[i*N + j]; \ + if (k < len4) { \ + tmp.re = FOLD(-src[ len4 + k], src[1*len4 - 1 - k]); \ + tmp.im = FOLD(-src[ len3 + k], -src[1*len3 - 1 - k]); \ + } else { \ + tmp.re = FOLD(-src[ len4 + k], -src[5*len4 - 1 - k]); \ + tmp.im = FOLD( src[-len4 + k], -src[1*len3 - 1 - k]); \ + } \ + CMUL(fft##N##in[j].im, fft##N##in[j].re, tmp.re, tmp.im, \ + exp[k >> 1].re, exp[k >> 1].im); \ + } \ + fft##N(s->tmp + sub_map[i], fft##N##in, m); \ + } \ + \ + for (int i = 0; i < N; i++) \ + s->fn[0](&s->sub[0], s->tmp + m*i, s->tmp + m*i, sizeof(TXComplex)); \ + \ + for (int i = 0; i < len8; i++) { \ + const int i0 = len8 + i, i1 = len8 - i - 1; \ + const int s0 = out_map[i0], s1 = out_map[i1]; \ + TXComplex src1 = { s->tmp[s1].re, s->tmp[s1].im }; \ + TXComplex src0 = { s->tmp[s0].re, s->tmp[s0].im }; \ + \ + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], src0.re, src0.im, \ + exp[i0].im, exp[i0].re); \ + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], src1.re, src1.im, \ + exp[i1].im, exp[i1].re); \ + } \ +} \ + \ +static const FFTXCodelet TX_NAME(ff_tx_mdct_pfa_##N##xM_fwd_def) = { \ + .name = TX_NAME_STR("mdct_pfa_" #N "xM_fwd"), \ + .function = TX_NAME(ff_tx_mdct_pfa_##N##xM_fwd), \ + .type = TX_TYPE(MDCT), \ + .flags = AV_TX_UNALIGNED | FF_TX_OUT_OF_PLACE | FF_TX_FORWARD_ONLY, \ + .factors = { N, TX_FACTOR_ANY }, \ + .nb_factors = 2, \ + .min_len = N*2, \ + .max_len = TX_LEN_UNLIMITED, \ + .init = TX_NAME(ff_tx_mdct_pfa_init), \ + .cpu_flags = FF_TX_CPU_FLAGS_ALL, \ + .prio = FF_TX_PRIO_BASE, \ +}; + +DECL_COMP_MDCT(3) +DECL_COMP_MDCT(5) +DECL_COMP_MDCT(7) +DECL_COMP_MDCT(9) +DECL_COMP_MDCT(15) + +static av_cold int TX_NAME(ff_tx_rdft_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + double f, m; + TXSample *tab; + + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, NULL, len >> 1, inv, scale))) + return ret; + + if (!(s->exp = av_mallocz((8 + (len >> 2) - 1)*sizeof(*s->exp)))) + return AVERROR(ENOMEM); + + tab = (TXSample *)s->exp; + + f = 2*M_PI/len; + + m = (inv ? 2*s->scale_d : s->scale_d); + + *tab++ = RESCALE((inv ? 0.5 : 1.0) * m); + *tab++ = RESCALE(inv ? 0.5*m : 1.0*m); + *tab++ = RESCALE( m); + *tab++ = RESCALE(-m); + + *tab++ = RESCALE( (0.5 - 0.0) * m); + *tab++ = RESCALE( (0.0 - 0.5) * m); + *tab++ = RESCALE( (0.5 - inv) * m); + *tab++ = RESCALE(-(0.5 - inv) * m); + + for (int i = 0; i < len >> 2; i++) + *tab++ = RESCALE(cos(i*f)); + for (int i = len >> 2; i >= 0; i--) + *tab++ = RESCALE(cos(i*f) * (inv ? +1.0 : -1.0)); + + return 0; +} + +#define DECL_RDFT(name, inv) \ +static void TX_NAME(ff_tx_rdft_ ##name)(AVTXContext *s, void *_dst, \ + void *_src, ptrdiff_t stride) \ +{ \ + const int len2 = s->len >> 1; \ + const int len4 = s->len >> 2; \ + const TXSample *fact = (void *)s->exp; \ + const TXSample *tcos = fact + 8; \ + const TXSample *tsin = tcos + len4; \ + TXComplex *data = inv ? _src : _dst; \ + TXComplex t[3]; \ + \ + if (!inv) \ + s->fn[0](&s->sub[0], data, _src, sizeof(TXComplex)); \ + else \ + data[0].im = data[len2].re; \ + \ + /* The DC value's both components are real, but we need to change them \ + * into complex values. Also, the middle of the array is special-cased. \ + * These operations can be done before or after the loop. */ \ + t[0].re = data[0].re; \ + data[0].re = t[0].re + data[0].im; \ + data[0].im = t[0].re - data[0].im; \ + data[ 0].re = MULT(fact[0], data[ 0].re); \ + data[ 0].im = MULT(fact[1], data[ 0].im); \ + data[len4].re = MULT(fact[2], data[len4].re); \ + data[len4].im = MULT(fact[3], data[len4].im); \ + \ + for (int i = 1; i < len4; i++) { \ + /* Separate even and odd FFTs */ \ + t[0].re = MULT(fact[4], (data[i].re + data[len2 - i].re)); \ + t[0].im = MULT(fact[5], (data[i].im - data[len2 - i].im)); \ + t[1].re = MULT(fact[6], (data[i].im + data[len2 - i].im)); \ + t[1].im = MULT(fact[7], (data[i].re - data[len2 - i].re)); \ + \ + /* Apply twiddle factors to the odd FFT and add to the even FFT */ \ + CMUL(t[2].re, t[2].im, t[1].re, t[1].im, tcos[i], tsin[i]); \ + \ + data[ i].re = t[0].re + t[2].re; \ + data[ i].im = t[2].im - t[0].im; \ + data[len2 - i].re = t[0].re - t[2].re; \ + data[len2 - i].im = t[2].im + t[0].im; \ + } \ + \ + if (inv) { \ + s->fn[0](&s->sub[0], _dst, data, sizeof(TXComplex)); \ + } else { \ + /* Move [0].im to the last position, as convention requires */ \ + data[len2].re = data[0].im; \ + data[ 0].im = data[len2].im = 0; \ + } \ +} + +DECL_RDFT(r2c, 0) +DECL_RDFT(c2r, 1) + +static const FFTXCodelet TX_NAME(ff_tx_rdft_r2c_def) = { + .name = TX_NAME_STR("rdft_r2c"), + .function = TX_NAME(ff_tx_rdft_r2c), + .type = TX_TYPE(RDFT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | + FF_TX_OUT_OF_PLACE | FF_TX_FORWARD_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_rdft_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static const FFTXCodelet TX_NAME(ff_tx_rdft_c2r_def) = { + .name = TX_NAME_STR("rdft_c2r"), + .function = TX_NAME(ff_tx_rdft_c2r), + .type = TX_TYPE(RDFT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | + FF_TX_OUT_OF_PLACE | FF_TX_INVERSE_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .nb_factors = 2, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_rdft_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static av_cold int TX_NAME(ff_tx_dct_init)(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + double freq; + TXSample *tab; + SCALE_TYPE rsc = *((SCALE_TYPE *)scale); + + if (inv) { + len *= 2; + s->len *= 2; + rsc *= 0.5; + } + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(RDFT), flags, NULL, len, inv, &rsc))) + return ret; + + s->exp = av_malloc((len/2)*3*sizeof(TXSample)); + if (!s->exp) + return AVERROR(ENOMEM); + + tab = (TXSample *)s->exp; + + freq = M_PI/(len*2); + + for (int i = 0; i < len; i++) + tab[i] = RESCALE(cos(i*freq)*(!inv + 1)); + + if (inv) { + for (int i = 0; i < len/2; i++) + tab[len + i] = RESCALE(0.5 / sin((2*i + 1)*freq)); + } else { + for (int i = 0; i < len/2; i++) + tab[len + i] = RESCALE(cos((len - 2*i - 1)*freq)); + } + + return 0; +} + +static void TX_NAME(ff_tx_dctII)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXSample *dst = _dst; + TXSample *src = _src; + const int len = s->len; + const int len2 = len >> 1; + const TXSample *exp = (void *)s->exp; + TXSample next; +#ifdef TX_INT32 + int64_t tmp1, tmp2; +#else + TXSample tmp1, tmp2; +#endif + + for (int i = 0; i < len2; i++) { + TXSample in1 = src[i]; + TXSample in2 = src[len - i - 1]; + TXSample s = exp[len + i]; + +#ifdef TX_INT32 + tmp1 = in1 + in2; + tmp2 = in1 - in2; + + tmp1 >>= 1; + tmp2 *= s; + + tmp2 = (tmp2 + 0x40000000) >> 31; +#else + tmp1 = (in1 + in2)*0.5; + tmp2 = (in1 - in2)*s; +#endif + + src[i] = tmp1 + tmp2; + src[len - i - 1] = tmp1 - tmp2; + } + + s->fn[0](&s->sub[0], dst, src, sizeof(TXComplex)); + + next = dst[len]; + + for (int i = len - 2; i > 0; i -= 2) { + TXSample tmp; + + CMUL(tmp, dst[i], exp[len - i], exp[i], dst[i + 0], dst[i + 1]); + + dst[i + 1] = next; + + next += tmp; + } + +#ifdef TX_INT32 + tmp1 = ((int64_t)exp[0]) * ((int64_t)dst[0]); + dst[0] = (tmp1 + 0x40000000) >> 31; +#else + dst[0] = exp[0] * dst[0]; +#endif + dst[1] = next; +} + +static void TX_NAME(ff_tx_dctIII)(AVTXContext *s, void *_dst, + void *_src, ptrdiff_t stride) +{ + TXSample *dst = _dst; + TXSample *src = _src; + const int len = s->len; + const int len2 = len >> 1; + const TXSample *exp = (void *)s->exp; +#ifdef TX_INT32 + int64_t tmp1, tmp2 = src[len - 1]; + tmp2 = (2*tmp2 + 0x40000000) >> 31; +#else + TXSample tmp1, tmp2 = 2*src[len - 1]; +#endif + + src[len] = tmp2; + + for (int i = len - 2; i >= 2; i -= 2) { + TXSample val1 = src[i - 0]; + TXSample val2 = src[i - 1] - src[i + 1]; + + CMUL(src[i + 1], src[i], exp[len - i], exp[i], val1, val2); + } + + s->fn[0](&s->sub[0], dst, src, sizeof(float)); + + for (int i = 0; i < len2; i++) { + TXSample in1 = dst[i]; + TXSample in2 = dst[len - i - 1]; + TXSample c = exp[len + i]; + + tmp1 = in1 + in2; + tmp2 = in1 - in2; + tmp2 *= c; +#ifdef TX_INT32 + tmp2 = (tmp2 + 0x40000000) >> 31; +#endif + + dst[i] = tmp1 + tmp2; + dst[len - i - 1] = tmp1 - tmp2; + } +} + +static const FFTXCodelet TX_NAME(ff_tx_dctII_def) = { + .name = TX_NAME_STR("dctII"), + .function = TX_NAME(ff_tx_dctII), + .type = TX_TYPE(DCT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | + FF_TX_OUT_OF_PLACE | FF_TX_FORWARD_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_dct_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +static const FFTXCodelet TX_NAME(ff_tx_dctIII_def) = { + .name = TX_NAME_STR("dctIII"), + .function = TX_NAME(ff_tx_dctIII), + .type = TX_TYPE(DCT), + .flags = AV_TX_UNALIGNED | AV_TX_INPLACE | + FF_TX_OUT_OF_PLACE | FF_TX_INVERSE_ONLY, + .factors = { 2, TX_FACTOR_ANY }, + .min_len = 2, + .max_len = TX_LEN_UNLIMITED, + .init = TX_NAME(ff_tx_dct_init), + .cpu_flags = FF_TX_CPU_FLAGS_ALL, + .prio = FF_TX_PRIO_BASE, +}; + +int TX_TAB(ff_tx_mdct_gen_exp)(AVTXContext *s, int *pre_tab) +{ + int off = 0; + int len4 = s->len >> 1; + double scale = s->scale_d; + const double theta = (scale < 0 ? len4 : 0) + 1.0/8.0; + size_t alloc = pre_tab ? 2*len4 : len4; + + if (!(s->exp = av_malloc_array(alloc, sizeof(*s->exp)))) + return AVERROR(ENOMEM); + + scale = sqrt(fabs(scale)); + + if (pre_tab) + off = len4; + + for (int i = 0; i < len4; i++) { + const double alpha = M_PI_2 * (i + theta) / len4; + s->exp[off + i] = (TXComplex){ RESCALE(cos(alpha) * scale), + RESCALE(sin(alpha) * scale) }; + } + + if (pre_tab) + for (int i = 0; i < len4; i++) + s->exp[i] = s->exp[len4 + pre_tab[i]]; + + return 0; +} + +const FFTXCodelet * const TX_NAME(ff_tx_codelet_list)[] = { + /* Split-Radix codelets */ + &TX_NAME(ff_tx_fft2_ns_def), + &TX_NAME(ff_tx_fft4_ns_def), + &TX_NAME(ff_tx_fft8_ns_def), + &TX_NAME(ff_tx_fft16_ns_def), + &TX_NAME(ff_tx_fft32_ns_def), + &TX_NAME(ff_tx_fft64_ns_def), + &TX_NAME(ff_tx_fft128_ns_def), + &TX_NAME(ff_tx_fft256_ns_def), + &TX_NAME(ff_tx_fft512_ns_def), + &TX_NAME(ff_tx_fft1024_ns_def), + &TX_NAME(ff_tx_fft2048_ns_def), + &TX_NAME(ff_tx_fft4096_ns_def), + &TX_NAME(ff_tx_fft8192_ns_def), + &TX_NAME(ff_tx_fft16384_ns_def), + &TX_NAME(ff_tx_fft32768_ns_def), + &TX_NAME(ff_tx_fft65536_ns_def), + &TX_NAME(ff_tx_fft131072_ns_def), + + /* Prime factor codelets */ + &TX_NAME(ff_tx_fft3_ns_def), + &TX_NAME(ff_tx_fft5_ns_def), + &TX_NAME(ff_tx_fft7_ns_def), + &TX_NAME(ff_tx_fft9_ns_def), + &TX_NAME(ff_tx_fft15_ns_def), + + /* We get these for free */ + &TX_NAME(ff_tx_fft3_fwd_def), + &TX_NAME(ff_tx_fft5_fwd_def), + &TX_NAME(ff_tx_fft7_fwd_def), + &TX_NAME(ff_tx_fft9_fwd_def), + + /* Standalone transforms */ + &TX_NAME(ff_tx_fft_def), + &TX_NAME(ff_tx_fft_inplace_def), + &TX_NAME(ff_tx_fft_inplace_small_def), + &TX_NAME(ff_tx_fft_pfa_def), + &TX_NAME(ff_tx_fft_pfa_ns_def), + &TX_NAME(ff_tx_fft_naive_def), + &TX_NAME(ff_tx_fft_naive_small_def), + &TX_NAME(ff_tx_mdct_fwd_def), + &TX_NAME(ff_tx_mdct_inv_def), + &TX_NAME(ff_tx_mdct_pfa_3xM_fwd_def), + &TX_NAME(ff_tx_mdct_pfa_5xM_fwd_def), + &TX_NAME(ff_tx_mdct_pfa_7xM_fwd_def), + &TX_NAME(ff_tx_mdct_pfa_9xM_fwd_def), + &TX_NAME(ff_tx_mdct_pfa_15xM_fwd_def), + &TX_NAME(ff_tx_mdct_pfa_3xM_inv_def), + &TX_NAME(ff_tx_mdct_pfa_5xM_inv_def), + &TX_NAME(ff_tx_mdct_pfa_7xM_inv_def), + &TX_NAME(ff_tx_mdct_pfa_9xM_inv_def), + &TX_NAME(ff_tx_mdct_pfa_15xM_inv_def), + &TX_NAME(ff_tx_mdct_naive_fwd_def), + &TX_NAME(ff_tx_mdct_naive_inv_def), + &TX_NAME(ff_tx_mdct_inv_full_def), + &TX_NAME(ff_tx_rdft_r2c_def), + &TX_NAME(ff_tx_rdft_c2r_def), + &TX_NAME(ff_tx_dctII_def), + &TX_NAME(ff_tx_dctIII_def), + + NULL, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/utils.c b/arm/raspi/third_party/ffmpeg/libavutil/utils.c new file mode 100644 index 00000000..94d247bb --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/utils.c @@ -0,0 +1,112 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "avutil.h" +#include "avassert.h" + +/** + * @file + * various utility functions + */ + +const char *av_get_media_type_string(enum AVMediaType media_type) +{ + switch (media_type) { + case AVMEDIA_TYPE_VIDEO: return "video"; + case AVMEDIA_TYPE_AUDIO: return "audio"; + case AVMEDIA_TYPE_DATA: return "data"; + case AVMEDIA_TYPE_SUBTITLE: return "subtitle"; + case AVMEDIA_TYPE_ATTACHMENT: return "attachment"; + default: return NULL; + } +} + +char av_get_picture_type_char(enum AVPictureType pict_type) +{ + switch (pict_type) { + case AV_PICTURE_TYPE_I: return 'I'; + case AV_PICTURE_TYPE_P: return 'P'; + case AV_PICTURE_TYPE_B: return 'B'; + case AV_PICTURE_TYPE_S: return 'S'; + case AV_PICTURE_TYPE_SI: return 'i'; + case AV_PICTURE_TYPE_SP: return 'p'; + case AV_PICTURE_TYPE_BI: return 'b'; + default: return '?'; + } +} + +unsigned av_int_list_length_for_size(unsigned elsize, + const void *list, uint64_t term) +{ + unsigned i; + + if (!list) + return 0; +#define LIST_LENGTH(type) \ + { type t = term, *l = (type *)list; for (i = 0; l[i] != t; i++); } + switch (elsize) { + case 1: LIST_LENGTH(uint8_t); break; + case 2: LIST_LENGTH(uint16_t); break; + case 4: LIST_LENGTH(uint32_t); break; + case 8: LIST_LENGTH(uint64_t); break; + default: av_assert0(!"valid element size"); + } + return i; +} + +char *av_fourcc_make_string(char *buf, uint32_t fourcc) +{ + int i; + char *orig_buf = buf; + size_t buf_size = AV_FOURCC_MAX_STRING_SIZE; + + for (i = 0; i < 4; i++) { + const int c = fourcc & 0xff; + const int print_chr = (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c && strchr(". -_", c)); + const int len = snprintf(buf, buf_size, print_chr ? "%c" : "[%d]", c); + if (len < 0) + break; + buf += len; + buf_size = buf_size > len ? buf_size - len : 0; + fourcc >>= 8; + } + + return orig_buf; +} + +AVRational av_get_time_base_q(void) +{ + return (AVRational){1, AV_TIME_BASE}; +} + +void av_assert0_fpu(void) { +#if HAVE_MMX_INLINE + uint16_t state[14]; + __asm__ volatile ( + "fstenv %0 \n\t" + : "+m" (state) + : + : "memory" + ); + av_assert0((state[4] & 3) == 3); +#endif +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/uuid.c b/arm/raspi/third_party/ffmpeg/libavutil/uuid.c new file mode 100644 index 00000000..062e2873 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/uuid.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2022 Pierre-Anthony Lemieux + * Zane van Iperen + * + * 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 + */ + +/* + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 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 name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/** + * @file + * UUID parsing and serialization utilities. + * The library treat the UUID as an opaque sequence of 16 unsigned bytes, + * i.e. ignoring the internal layout of the UUID, which depends on the type + * of the UUID. + * + * @author Pierre-Anthony Lemieux + * @author Zane van Iperen + */ + +#include "uuid.h" +#include "error.h" +#include "avstring.h" + +int av_uuid_parse(const char *in, AVUUID uu) +{ + if (strlen(in) != 36) + return AVERROR(EINVAL); + + return av_uuid_parse_range(in, in + 36, uu); +} + +static int xdigit_to_int(char c) +{ + c = av_tolower(c); + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= '0' && c <= '9') + return c - '0'; + + return -1; +} + +int av_uuid_parse_range(const char *in_start, const char *in_end, AVUUID uu) +{ + int i; + const char *cp; + + if ((in_end - in_start) != 36) + return AVERROR(EINVAL); + + for (i = 0, cp = in_start; i < 16; i++) { + int hi; + int lo; + + if (i == 4 || i == 6 || i == 8 || i == 10) + cp++; + + hi = xdigit_to_int(*cp++); + lo = xdigit_to_int(*cp++); + + if (hi == -1 || lo == -1) + return AVERROR(EINVAL); + + uu[i] = (hi << 4) + lo; + } + + return 0; +} + +static const char hexdigits_lower[16] = "0123456789abcdef"; + +void av_uuid_unparse(const AVUUID uuid, char *out) +{ + char *p = out; + + for (int i = 0; i < 16; i++) { + uint8_t tmp; + + if (i == 4 || i == 6 || i == 8 || i == 10) + *p++ = '-'; + + tmp = uuid[i]; + *p++ = hexdigits_lower[tmp >> 4]; + *p++ = hexdigits_lower[tmp & 15]; + } + + *p = '\0'; +} + +int av_uuid_urn_parse(const char *in, AVUUID uu) +{ + if (av_stristr(in, "urn:uuid:") != in) + return AVERROR(EINVAL); + + return av_uuid_parse(in + 9, uu); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/uuid.h b/arm/raspi/third_party/ffmpeg/libavutil/uuid.h new file mode 100644 index 00000000..748b7ed3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/uuid.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022 Pierre-Anthony Lemieux + * Zane van Iperen + * + * 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 + * UUID parsing and serialization utilities. + * The library treats the UUID as an opaque sequence of 16 unsigned bytes, + * i.e. ignoring the internal layout of the UUID, which depends on the type + * of the UUID. + * + * @author Pierre-Anthony Lemieux + * @author Zane van Iperen + */ + +#ifndef AVUTIL_UUID_H +#define AVUTIL_UUID_H + +#include +#include + +#define AV_PRI_UUID \ + "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-" \ + "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" + +#define AV_PRI_URN_UUID \ + "urn:uuid:%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-" \ + "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" + +/* AV_UUID_ARG() is used together with AV_PRI_UUID() or AV_PRI_URN_UUID + * to print UUIDs, e.g. + * av_log(NULL, AV_LOG_DEBUG, "UUID: " AV_PRI_UUID, AV_UUID_ARG(uuid)); + */ +#define AV_UUID_ARG(x) \ + (x)[ 0], (x)[ 1], (x)[ 2], (x)[ 3], \ + (x)[ 4], (x)[ 5], (x)[ 6], (x)[ 7], \ + (x)[ 8], (x)[ 9], (x)[10], (x)[11], \ + (x)[12], (x)[13], (x)[14], (x)[15] + +#define AV_UUID_LEN 16 + +/* Binary representation of a UUID */ +typedef uint8_t AVUUID[AV_UUID_LEN]; + +/** + * Parses a string representation of a UUID formatted according to IETF RFC 4122 + * into an AVUUID. The parsing is case-insensitive. The string must be 37 + * characters long, including the terminating NUL character. + * + * Example string representation: "2fceebd0-7017-433d-bafb-d073a7116696" + * + * @param[in] in String representation of a UUID, + * e.g. 2fceebd0-7017-433d-bafb-d073a7116696 + * @param[out] uu AVUUID + * @return A non-zero value in case of an error. + */ +int av_uuid_parse(const char *in, AVUUID uu); + +/** + * Parses a URN representation of a UUID, as specified at IETF RFC 4122, + * into an AVUUID. The parsing is case-insensitive. The string must be 46 + * characters long, including the terminating NUL character. + * + * Example string representation: "urn:uuid:2fceebd0-7017-433d-bafb-d073a7116696" + * + * @param[in] in URN UUID + * @param[out] uu AVUUID + * @return A non-zero value in case of an error. + */ +int av_uuid_urn_parse(const char *in, AVUUID uu); + +/** + * Parses a string representation of a UUID formatted according to IETF RFC 4122 + * into an AVUUID. The parsing is case-insensitive. + * + * @param[in] in_start Pointer to the first character of the string representation + * @param[in] in_end Pointer to the character after the last character of the + * string representation. That memory location is never + * accessed. It is an error if `in_end - in_start != 36`. + * @param[out] uu AVUUID + * @return A non-zero value in case of an error. + */ +int av_uuid_parse_range(const char *in_start, const char *in_end, AVUUID uu); + +/** + * Serializes a AVUUID into a string representation according to IETF RFC 4122. + * The string is lowercase and always 37 characters long, including the + * terminating NUL character. + * + * @param[in] uu AVUUID + * @param[out] out Pointer to an array of no less than 37 characters. + */ +void av_uuid_unparse(const AVUUID uu, char *out); + +/** + * Compares two UUIDs for equality. + * + * @param[in] uu1 AVUUID + * @param[in] uu2 AVUUID + * @return Nonzero if uu1 and uu2 are identical, 0 otherwise + */ +static inline int av_uuid_equal(const AVUUID uu1, const AVUUID uu2) +{ + return memcmp(uu1, uu2, AV_UUID_LEN) == 0; +} + +/** + * Copies the bytes of src into dest. + * + * @param[out] dest AVUUID + * @param[in] src AVUUID + */ +static inline void av_uuid_copy(AVUUID dest, const AVUUID src) +{ + memcpy(dest, src, AV_UUID_LEN); +} + +/** + * Sets a UUID to the nil UUID, i.e. a UUID with have all + * its 128 bits set to zero. + * + * @param[in,out] uu UUID to be set to the nil UUID + */ +static inline void av_uuid_nil(AVUUID uu) +{ + memset(uu, 0, AV_UUID_LEN); +} + +#endif /* AVUTIL_UUID_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/version.c b/arm/raspi/third_party/ffmpeg/libavutil/version.c new file mode 100644 index 00000000..b0f4f94a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/version.c @@ -0,0 +1,71 @@ +/* + * Version functions. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "avassert.h" +#include "avutil.h" +#include "common.h" +#include "libm.h" +#include "log.h" +#include "samplefmt.h" +#include "version.h" + +#include "libavutil/ffversion.h" +const char av_util_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + +const char *av_version_info(void) +{ + return FFMPEG_VERSION; +} + +unsigned avutil_version(void) +{ + av_assert0(AV_SAMPLE_FMT_DBLP == 9); + av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); + av_assert0(AV_PICTURE_TYPE_BI == 7); + av_assert0(LIBAVUTIL_VERSION_MICRO >= 100); + av_assert0(HAVE_MMX2 == HAVE_MMXEXT); + + av_assert0(((size_t)-1) > 0); // C guarantees this but if false on a platform we care about revert at least b284e1ffe343d6697fb950d1ee517bafda8a9844 + + if (av_sat_dadd32(1, 2) != 5) { + av_log(NULL, AV_LOG_FATAL, "Libavutil has been built with a broken binutils, please upgrade binutils and rebuild\n"); + abort(); + } + + if (llrint(1LL<<60) != 1LL<<60) { + av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n"); + } + + return LIBAVUTIL_VERSION_INT; +} + +const char *avutil_configuration(void) +{ + return FFMPEG_CONFIGURATION; +} + +const char *avutil_license(void) +{ +#define LICENSE_PREFIX "libavutil license: " + return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1]; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/version.h b/arm/raspi/third_party/ffmpeg/libavutil/version.h new file mode 100644 index 00000000..60f96af5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/version.h @@ -0,0 +1,124 @@ +/* + * 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 + * @ingroup lavu + * Libavutil version macros + */ + +#ifndef AVUTIL_VERSION_H +#define AVUTIL_VERSION_H + +#include "macros.h" + +/** + * @addtogroup version_utils + * + * Useful to check and match library version in order to maintain + * backward compatibility. + * + * The FFmpeg libraries follow a versioning sheme very similar to + * Semantic Versioning (http://semver.org/) + * The difference is that the component called PATCH is called MICRO in FFmpeg + * and its value is reset to 100 instead of 0 to keep it above or equal to 100. + * Also we do not increase MICRO for every bugfix or change in git master. + * + * Prior to FFmpeg 3.2 point releases did not change any lib version number to + * avoid aliassing different git master checkouts. + * Starting with FFmpeg 3.2, the released library versions will occupy + * a separate MAJOR.MINOR that is not used on the master development branch. + * That is if we branch a release of master 55.10.123 we will bump to 55.11.100 + * for the release and master will continue at 55.12.100 after it. Each new + * point release will then bump the MICRO improving the usefulness of the lib + * versions. + * + * @{ + */ + +#define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c)) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +/** + * Extract version components from the full ::AV_VERSION_INT int as returned + * by functions like ::avformat_version() and ::avcodec_version() + */ +#define AV_VERSION_MAJOR(a) ((a) >> 16) +#define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8) +#define AV_VERSION_MICRO(a) ((a) & 0xFF) + +/** + * @} + */ + +/** + * @defgroup lavu_ver Version and Build diagnostics + * + * Macros and function useful to check at compiletime and at runtime + * which version of libavutil is in use. + * + * @{ + */ + +#define LIBAVUTIL_VERSION_MAJOR 57 +#define LIBAVUTIL_VERSION_MINOR 44 +#define LIBAVUTIL_VERSION_MICRO 100 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * @defgroup lavu_depr_guards Deprecation Guards + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + * + * @{ + */ + +#define FF_API_D2STR (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_DECLARE_ALIGNED (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_COLORSPACE_NAME (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_AV_MALLOCZ_ARRAY (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_FIFO_PEEK2 (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_FIFO_OLD_API (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_OLD_CHANNEL_LAYOUT (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_AV_FOPEN_UTF8 (LIBAVUTIL_VERSION_MAJOR < 58) +#define FF_API_PKT_DURATION (LIBAVUTIL_VERSION_MAJOR < 58) + +/** + * @} + * @} + */ + +#endif /* AVUTIL_VERSION_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/version_major.h b/arm/raspi/third_party/ffmpeg/libavutil/version_major.h new file mode 100644 index 00000000..e4db2e34 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/version_major.h @@ -0,0 +1,25 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VERSION_MAJOR_H +#define AVUTIL_VERSION_MAJOR_H + +/* This file is intentionally empty; it's only kept to fulfill make + * dependencies for ffbuild/libversion.sh. It is not installed. */ + +#endif /* AVUTIL_VERSION_MAJOR_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.c b/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.c new file mode 100644 index 00000000..33592dc1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.c @@ -0,0 +1,80 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "buffer.h" +#include "frame.h" +#include "mem.h" +#include "video_enc_params.h" + +AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type, + unsigned int nb_blocks, size_t *out_size) +{ + struct TestStruct { + AVVideoEncParams p; + AVVideoBlockParams b; + }; + const size_t blocks_offset = offsetof(struct TestStruct, b); + size_t size = blocks_offset; + AVVideoEncParams *par; + + if (nb_blocks > (SIZE_MAX - size) / sizeof(AVVideoBlockParams)) + return NULL; + size += sizeof(AVVideoBlockParams) * nb_blocks; + + par = av_mallocz(size); + if (!par) + return NULL; + + par->type = type; + par->nb_blocks = nb_blocks; + par->block_size = sizeof(AVVideoBlockParams); + par->blocks_offset = blocks_offset; + + if (out_size) + *out_size = size; + + return par; +} + +AVVideoEncParams* +av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type, + unsigned int nb_blocks) +{ + AVBufferRef *buf; + AVVideoEncParams *par; + size_t size; + + par = av_video_enc_params_alloc(type, nb_blocks, &size); + if (!par) + return NULL; + buf = av_buffer_create((uint8_t *)par, size, NULL, NULL, 0); + if (!buf) { + av_freep(&par); + return NULL; + } + + if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_VIDEO_ENC_PARAMS, buf)) { + av_buffer_unref(&buf); + return NULL; + } + + return par; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.h b/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.h new file mode 100644 index 00000000..fc0c3bc1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/video_enc_params.h @@ -0,0 +1,171 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VIDEO_ENC_PARAMS_H +#define AVUTIL_VIDEO_ENC_PARAMS_H + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/frame.h" + +enum AVVideoEncParamsType { + AV_VIDEO_ENC_PARAMS_NONE = -1, + /** + * VP9 stores: + * - per-frame base (luma AC) quantizer index, exported as AVVideoEncParams.qp + * - deltas for luma DC, chroma AC and chroma DC, exported in the + * corresponding entries in AVVideoEncParams.delta_qp + * - per-segment delta, exported as for each block as AVVideoBlockParams.delta_qp + * + * To compute the resulting quantizer index for a block: + * - for luma AC, add the base qp and the per-block delta_qp, saturating to + * unsigned 8-bit. + * - for luma DC and chroma AC/DC, add the corresponding + * AVVideoBlockParams.delta_qp to the luma AC index, again saturating to + * unsigned 8-bit. + */ + AV_VIDEO_ENC_PARAMS_VP9, + + /** + * H.264 stores: + * - in PPS (per-picture): + * * initial QP_Y (luma) value, exported as AVVideoEncParams.qp + * * delta(s) for chroma QP values (same for both, or each separately), + * exported as in the corresponding entries in AVVideoEncParams.delta_qp + * - per-slice QP delta, not exported directly, added to the per-MB value + * - per-MB delta; not exported directly; the final per-MB quantizer + * parameter - QP_Y - minus the value in AVVideoEncParams.qp is exported + * as AVVideoBlockParams.qp_delta. + */ + AV_VIDEO_ENC_PARAMS_H264, + + /* + * MPEG-2-compatible quantizer. + * + * Summing the frame-level qp with the per-block delta_qp gives the + * resulting quantizer for the block. + */ + AV_VIDEO_ENC_PARAMS_MPEG2, +}; + +/** + * Video encoding parameters for a given frame. This struct is allocated along + * with an optional array of per-block AVVideoBlockParams descriptors. + * Must be allocated with av_video_enc_params_alloc(). + */ +typedef struct AVVideoEncParams { + /** + * Number of blocks in the array. + * + * May be 0, in which case no per-block information is present. In this case + * the values of blocks_offset / block_size are unspecified and should not + * be accessed. + */ + unsigned int nb_blocks; + /** + * Offset in bytes from the beginning of this structure at which the array + * of blocks starts. + */ + size_t blocks_offset; + /* + * Size of each block in bytes. May not match sizeof(AVVideoBlockParams). + */ + size_t block_size; + + /** + * Type of the parameters (the codec they are used with). + */ + enum AVVideoEncParamsType type; + + /** + * Base quantisation parameter for the frame. The final quantiser for a + * given block in a given plane is obtained from this value, possibly + * combined with {@code delta_qp} and the per-block delta in a manner + * documented for each type. + */ + int32_t qp; + + /** + * Quantisation parameter offset from the base (per-frame) qp for a given + * plane (first index) and AC/DC coefficients (second index). + */ + int32_t delta_qp[4][2]; +} AVVideoEncParams; + +/** + * Data structure for storing block-level encoding information. + * It is allocated as a part of AVVideoEncParams and should be retrieved with + * av_video_enc_params_block(). + * + * sizeof(AVVideoBlockParams) is not a part of the ABI and new fields may be + * added to it. + */ +typedef struct AVVideoBlockParams { + /** + * Distance in luma pixels from the top-left corner of the visible frame + * to the top-left corner of the block. + * Can be negative if top/right padding is present on the coded frame. + */ + int src_x, src_y; + /** + * Width and height of the block in luma pixels. + */ + int w, h; + + /** + * Difference between this block's final quantization parameter and the + * corresponding per-frame value. + */ + int32_t delta_qp; +} AVVideoBlockParams; + +/* + * Get the block at the specified {@code idx}. Must be between 0 and nb_blocks. + */ +static av_always_inline AVVideoBlockParams* +av_video_enc_params_block(AVVideoEncParams *par, unsigned int idx) +{ + av_assert0(idx < par->nb_blocks); + return (AVVideoBlockParams *)((uint8_t *)par + par->blocks_offset + + idx * par->block_size); +} + +/** + * Allocates memory for AVVideoEncParams of the given type, plus an array of + * {@code nb_blocks} AVVideoBlockParams and initializes the variables. Can be + * freed with a normal av_free() call. + * + * @param out_size if non-NULL, the size in bytes of the resulting data array is + * written here. + */ +AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type, + unsigned int nb_blocks, size_t *out_size); + +/** + * Allocates memory for AVEncodeInfoFrame plus an array of + * {@code nb_blocks} AVEncodeInfoBlock in the given AVFrame {@code frame} + * as AVFrameSideData of type AV_FRAME_DATA_VIDEO_ENC_PARAMS + * and initializes the variables. + */ +AVVideoEncParams* +av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type, + unsigned int nb_blocks); + +#endif /* AVUTIL_VIDEO_ENC_PARAMS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan.c b/arm/raspi/third_party/ffmpeg/libavutil/vulkan.c new file mode 100644 index 00000000..403f0b1f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan.c @@ -0,0 +1,1406 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avassert.h" + +#include "vulkan.h" +#include "vulkan_loader.h" + +#if CONFIG_LIBGLSLANG +#include "vulkan_glslang.c" +#elif CONFIG_LIBSHADERC +#include "vulkan_shaderc.c" +#endif + +/* Generic macro for creating contexts which need to keep their addresses + * if another context is created. */ +#define FN_CREATING(ctx, type, shortname, array, num) \ +static av_always_inline type *create_ ##shortname(ctx *dctx) \ +{ \ + type **array, *sctx = av_mallocz(sizeof(*sctx)); \ + if (!sctx) \ + return NULL; \ + \ + array = av_realloc_array(dctx->array, sizeof(*dctx->array), dctx->num + 1);\ + if (!array) { \ + av_free(sctx); \ + return NULL; \ + } \ + \ + dctx->array = array; \ + dctx->array[dctx->num++] = sctx; \ + \ + return sctx; \ +} + +const VkComponentMapping ff_comp_identity_map = { + .r = VK_COMPONENT_SWIZZLE_IDENTITY, + .g = VK_COMPONENT_SWIZZLE_IDENTITY, + .b = VK_COMPONENT_SWIZZLE_IDENTITY, + .a = VK_COMPONENT_SWIZZLE_IDENTITY, +}; + +/* Converts return values to strings */ +const char *ff_vk_ret2str(VkResult res) +{ +#define CASE(VAL) case VAL: return #VAL + switch (res) { + CASE(VK_SUCCESS); + CASE(VK_NOT_READY); + CASE(VK_TIMEOUT); + CASE(VK_EVENT_SET); + CASE(VK_EVENT_RESET); + CASE(VK_INCOMPLETE); + CASE(VK_ERROR_OUT_OF_HOST_MEMORY); + CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY); + CASE(VK_ERROR_INITIALIZATION_FAILED); + CASE(VK_ERROR_DEVICE_LOST); + CASE(VK_ERROR_MEMORY_MAP_FAILED); + CASE(VK_ERROR_LAYER_NOT_PRESENT); + CASE(VK_ERROR_EXTENSION_NOT_PRESENT); + CASE(VK_ERROR_FEATURE_NOT_PRESENT); + CASE(VK_ERROR_INCOMPATIBLE_DRIVER); + CASE(VK_ERROR_TOO_MANY_OBJECTS); + CASE(VK_ERROR_FORMAT_NOT_SUPPORTED); + CASE(VK_ERROR_FRAGMENTED_POOL); + CASE(VK_ERROR_SURFACE_LOST_KHR); + CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); + CASE(VK_SUBOPTIMAL_KHR); + CASE(VK_ERROR_OUT_OF_DATE_KHR); + CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); + CASE(VK_ERROR_VALIDATION_FAILED_EXT); + CASE(VK_ERROR_INVALID_SHADER_NV); + CASE(VK_ERROR_OUT_OF_POOL_MEMORY); + CASE(VK_ERROR_INVALID_EXTERNAL_HANDLE); + CASE(VK_ERROR_NOT_PERMITTED_EXT); + default: return "Unknown error"; + } +#undef CASE +} + +void ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf, + VkQueueFlagBits dev_family, int nb_queues) +{ + switch (dev_family) { + case VK_QUEUE_GRAPHICS_BIT: + qf->queue_family = s->hwctx->queue_family_index; + qf->actual_queues = s->hwctx->nb_graphics_queues; + break; + case VK_QUEUE_COMPUTE_BIT: + qf->queue_family = s->hwctx->queue_family_comp_index; + qf->actual_queues = s->hwctx->nb_comp_queues; + break; + case VK_QUEUE_TRANSFER_BIT: + qf->queue_family = s->hwctx->queue_family_tx_index; + qf->actual_queues = s->hwctx->nb_tx_queues; + break; + case VK_QUEUE_VIDEO_ENCODE_BIT_KHR: + qf->queue_family = s->hwctx->queue_family_encode_index; + qf->actual_queues = s->hwctx->nb_encode_queues; + break; + case VK_QUEUE_VIDEO_DECODE_BIT_KHR: + qf->queue_family = s->hwctx->queue_family_decode_index; + qf->actual_queues = s->hwctx->nb_decode_queues; + break; + default: + av_assert0(0); /* Should never happen */ + } + + if (!nb_queues) + qf->nb_queues = qf->actual_queues; + else + qf->nb_queues = nb_queues; + + return; +} + +void ff_vk_qf_rotate(FFVkQueueFamilyCtx *qf) +{ + qf->cur_queue = (qf->cur_queue + 1) % qf->nb_queues; +} + +static int vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req, + VkMemoryPropertyFlagBits req_flags, void *alloc_extension, + VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem) +{ + VkResult ret; + int index = -1; + FFVulkanFunctions *vk = &s->vkfn; + + VkMemoryAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = alloc_extension, + }; + + /* Align if we need to */ + if (req_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + req->size = FFALIGN(req->size, s->props.limits.minMemoryMapAlignment); + + alloc_info.allocationSize = req->size; + + /* The vulkan spec requires memory types to be sorted in the "optimal" + * order, so the first matching type we find will be the best/fastest one */ + for (int i = 0; i < s->mprops.memoryTypeCount; i++) { + /* The memory type must be supported by the requirements (bitfield) */ + if (!(req->memoryTypeBits & (1 << i))) + continue; + + /* The memory type flags must include our properties */ + if ((s->mprops.memoryTypes[i].propertyFlags & req_flags) != req_flags) + continue; + + /* Found a suitable memory type */ + index = i; + break; + } + + if (index < 0) { + av_log(s, AV_LOG_ERROR, "No memory type found for flags 0x%x\n", + req_flags); + return AVERROR(EINVAL); + } + + alloc_info.memoryTypeIndex = index; + + ret = vk->AllocateMemory(s->hwctx->act_dev, &alloc_info, + s->hwctx->alloc, mem); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to allocate memory: %s\n", + ff_vk_ret2str(ret)); + return AVERROR(ENOMEM); + } + + *mem_flags |= s->mprops.memoryTypes[index].propertyFlags; + + return 0; +} + +int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, + VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags) +{ + int err; + VkResult ret; + int use_ded_mem; + FFVulkanFunctions *vk = &s->vkfn; + + VkBufferCreateInfo buf_spawn = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = NULL, + .usage = usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .size = size, /* Gets FFALIGNED during alloc if host visible + but should be ok */ + }; + + VkBufferMemoryRequirementsInfo2 req_desc = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + }; + VkMemoryDedicatedAllocateInfo ded_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = NULL, + }; + VkMemoryDedicatedRequirements ded_req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + }; + VkMemoryRequirements2 req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &ded_req, + }; + + ret = vk->CreateBuffer(s->hwctx->act_dev, &buf_spawn, NULL, &buf->buf); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to create buffer: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + req_desc.buffer = buf->buf; + + vk->GetBufferMemoryRequirements2(s->hwctx->act_dev, &req_desc, &req); + + /* In case the implementation prefers/requires dedicated allocation */ + use_ded_mem = ded_req.prefersDedicatedAllocation | + ded_req.requiresDedicatedAllocation; + if (use_ded_mem) + ded_alloc.buffer = buf->buf; + + err = vk_alloc_mem(s, &req.memoryRequirements, flags, + use_ded_mem ? &ded_alloc : (void *)ded_alloc.pNext, + &buf->flags, &buf->mem); + if (err) + return err; + + ret = vk->BindBufferMemory(s->hwctx->act_dev, buf->buf, buf->mem, 0); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to bind memory to buffer: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer *buf, uint8_t *mem[], + int nb_buffers, int invalidate) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + VkMappedMemoryRange *inval_list = NULL; + int inval_count = 0; + + for (int i = 0; i < nb_buffers; i++) { + ret = vk->MapMemory(s->hwctx->act_dev, buf[i].mem, 0, + VK_WHOLE_SIZE, 0, (void **)&mem[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to map buffer memory: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + if (!invalidate) + return 0; + + for (int i = 0; i < nb_buffers; i++) { + const VkMappedMemoryRange ival_buf = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .memory = buf[i].mem, + .size = VK_WHOLE_SIZE, + }; + if (buf[i].flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + continue; + inval_list = av_fast_realloc(s->scratch, &s->scratch_size, + (++inval_count)*sizeof(*inval_list)); + if (!inval_list) + return AVERROR(ENOMEM); + inval_list[inval_count - 1] = ival_buf; + } + + if (inval_count) { + ret = vk->InvalidateMappedMemoryRanges(s->hwctx->act_dev, inval_count, + inval_list); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to invalidate memory: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + return 0; +} + +int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer *buf, int nb_buffers, + int flush) +{ + int err = 0; + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + VkMappedMemoryRange *flush_list = NULL; + int flush_count = 0; + + if (flush) { + for (int i = 0; i < nb_buffers; i++) { + const VkMappedMemoryRange flush_buf = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .memory = buf[i].mem, + .size = VK_WHOLE_SIZE, + }; + if (buf[i].flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + continue; + flush_list = av_fast_realloc(s->scratch, &s->scratch_size, + (++flush_count)*sizeof(*flush_list)); + if (!flush_list) + return AVERROR(ENOMEM); + flush_list[flush_count - 1] = flush_buf; + } + } + + if (flush_count) { + ret = vk->FlushMappedMemoryRanges(s->hwctx->act_dev, flush_count, + flush_list); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to flush memory: %s\n", + ff_vk_ret2str(ret)); + err = AVERROR_EXTERNAL; /* We still want to try to unmap them */ + } + } + + for (int i = 0; i < nb_buffers; i++) + vk->UnmapMemory(s->hwctx->act_dev, buf[i].mem); + + return err; +} + +void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf) +{ + FFVulkanFunctions *vk = &s->vkfn; + + if (!buf || !s->hwctx) + return; + + vk->DeviceWaitIdle(s->hwctx->act_dev); + + if (buf->buf != VK_NULL_HANDLE) + vk->DestroyBuffer(s->hwctx->act_dev, buf->buf, s->hwctx->alloc); + if (buf->mem != VK_NULL_HANDLE) + vk->FreeMemory(s->hwctx->act_dev, buf->mem, s->hwctx->alloc); +} + +int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size, + VkShaderStageFlagBits stage) +{ + VkPushConstantRange *pc; + + pl->push_consts = av_realloc_array(pl->push_consts, sizeof(*pl->push_consts), + pl->push_consts_num + 1); + if (!pl->push_consts) + return AVERROR(ENOMEM); + + pc = &pl->push_consts[pl->push_consts_num++]; + memset(pc, 0, sizeof(*pc)); + + pc->stageFlags = stage; + pc->offset = offset; + pc->size = size; + + return 0; +} + +FN_CREATING(FFVulkanContext, FFVkExecContext, exec_ctx, exec_ctx, exec_ctx_num) +int ff_vk_create_exec_ctx(FFVulkanContext *s, FFVkExecContext **ctx, + FFVkQueueFamilyCtx *qf) +{ + VkResult ret; + FFVkExecContext *e; + FFVulkanFunctions *vk = &s->vkfn; + + VkCommandPoolCreateInfo cqueue_create = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = qf->queue_family, + }; + VkCommandBufferAllocateInfo cbuf_create = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = qf->nb_queues, + }; + + e = create_exec_ctx(s); + if (!e) + return AVERROR(ENOMEM); + + e->qf = qf; + + e->queues = av_mallocz(qf->nb_queues * sizeof(*e->queues)); + if (!e->queues) + return AVERROR(ENOMEM); + + e->bufs = av_mallocz(qf->nb_queues * sizeof(*e->bufs)); + if (!e->bufs) + return AVERROR(ENOMEM); + + /* Create command pool */ + ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create, + s->hwctx->alloc, &e->pool); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + cbuf_create.commandPool = e->pool; + + /* Allocate command buffer */ + ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create, e->bufs); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + for (int i = 0; i < qf->nb_queues; i++) { + FFVkQueueCtx *q = &e->queues[i]; + vk->GetDeviceQueue(s->hwctx->act_dev, qf->queue_family, + i % qf->actual_queues, &q->queue); + } + + *ctx = e; + + return 0; +} + +void ff_vk_discard_exec_deps(FFVkExecContext *e) +{ + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; + + for (int j = 0; j < q->nb_buf_deps; j++) + av_buffer_unref(&q->buf_deps[j]); + q->nb_buf_deps = 0; + + for (int j = 0; j < q->nb_frame_deps; j++) + av_frame_free(&q->frame_deps[j]); + q->nb_frame_deps = 0; + + e->sem_wait_cnt = 0; + e->sem_sig_cnt = 0; +} + +int ff_vk_start_exec_recording(FFVulkanContext *s, FFVkExecContext *e) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; + + VkCommandBufferBeginInfo cmd_start = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + + /* Create the fence and don't wait for it initially */ + if (!q->fence) { + VkFenceCreateInfo fence_spawn = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + }; + ret = vk->CreateFence(s->hwctx->act_dev, &fence_spawn, s->hwctx->alloc, + &q->fence); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to queue frame fence: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } else { + vk->WaitForFences(s->hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vk->ResetFences(s->hwctx->act_dev, 1, &q->fence); + } + + /* Discard queue dependencies */ + ff_vk_discard_exec_deps(e); + + ret = vk->BeginCommandBuffer(e->bufs[e->qf->cur_queue], &cmd_start); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to start command recoding: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +VkCommandBuffer ff_vk_get_exec_buf(FFVkExecContext *e) +{ + return e->bufs[e->qf->cur_queue]; +} + +int ff_vk_add_exec_dep(FFVulkanContext *s, FFVkExecContext *e, AVFrame *frame, + VkPipelineStageFlagBits in_wait_dst_flag) +{ + AVFrame **dst; + AVVkFrame *f = (AVVkFrame *)frame->data[0]; + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; + AVHWFramesContext *fc = (AVHWFramesContext *)frame->hw_frames_ctx->data; + int planes = av_pix_fmt_count_planes(fc->sw_format); + + for (int i = 0; i < planes; i++) { + e->sem_wait = av_fast_realloc(e->sem_wait, &e->sem_wait_alloc, + (e->sem_wait_cnt + 1)*sizeof(*e->sem_wait)); + if (!e->sem_wait) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_wait_dst = av_fast_realloc(e->sem_wait_dst, &e->sem_wait_dst_alloc, + (e->sem_wait_cnt + 1)*sizeof(*e->sem_wait_dst)); + if (!e->sem_wait_dst) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_wait_val = av_fast_realloc(e->sem_wait_val, &e->sem_wait_val_alloc, + (e->sem_wait_cnt + 1)*sizeof(*e->sem_wait_val)); + if (!e->sem_wait_val) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_sig = av_fast_realloc(e->sem_sig, &e->sem_sig_alloc, + (e->sem_sig_cnt + 1)*sizeof(*e->sem_sig)); + if (!e->sem_sig) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_sig_val = av_fast_realloc(e->sem_sig_val, &e->sem_sig_val_alloc, + (e->sem_sig_cnt + 1)*sizeof(*e->sem_sig_val)); + if (!e->sem_sig_val) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_sig_val_dst = av_fast_realloc(e->sem_sig_val_dst, &e->sem_sig_val_dst_alloc, + (e->sem_sig_cnt + 1)*sizeof(*e->sem_sig_val_dst)); + if (!e->sem_sig_val_dst) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + e->sem_wait[e->sem_wait_cnt] = f->sem[i]; + e->sem_wait_dst[e->sem_wait_cnt] = in_wait_dst_flag; + e->sem_wait_val[e->sem_wait_cnt] = f->sem_value[i]; + e->sem_wait_cnt++; + + e->sem_sig[e->sem_sig_cnt] = f->sem[i]; + e->sem_sig_val[e->sem_sig_cnt] = f->sem_value[i] + 1; + e->sem_sig_val_dst[e->sem_sig_cnt] = &f->sem_value[i]; + e->sem_sig_cnt++; + } + + dst = av_fast_realloc(q->frame_deps, &q->frame_deps_alloc_size, + (q->nb_frame_deps + 1) * sizeof(*dst)); + if (!dst) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + + q->frame_deps = dst; + q->frame_deps[q->nb_frame_deps] = av_frame_clone(frame); + if (!q->frame_deps[q->nb_frame_deps]) { + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); + } + q->nb_frame_deps++; + + return 0; +} + +int ff_vk_submit_exec_queue(FFVulkanContext *s, FFVkExecContext *e) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; + + VkTimelineSemaphoreSubmitInfo s_timeline_sem_info = { + .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + .pWaitSemaphoreValues = e->sem_wait_val, + .pSignalSemaphoreValues = e->sem_sig_val, + .waitSemaphoreValueCount = e->sem_wait_cnt, + .signalSemaphoreValueCount = e->sem_sig_cnt, + }; + + VkSubmitInfo s_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = &s_timeline_sem_info, + + .commandBufferCount = 1, + .pCommandBuffers = &e->bufs[e->qf->cur_queue], + + .pWaitSemaphores = e->sem_wait, + .pWaitDstStageMask = e->sem_wait_dst, + .waitSemaphoreCount = e->sem_wait_cnt, + + .pSignalSemaphores = e->sem_sig, + .signalSemaphoreCount = e->sem_sig_cnt, + }; + + ret = vk->EndCommandBuffer(e->bufs[e->qf->cur_queue]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to finish command buffer: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + ret = vk->QueueSubmit(q->queue, 1, &s_info, q->fence); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to submit command buffer: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + for (int i = 0; i < e->sem_sig_cnt; i++) + *e->sem_sig_val_dst[i] += 1; + + return 0; +} + +int ff_vk_add_dep_exec_ctx(FFVulkanContext *s, FFVkExecContext *e, + AVBufferRef **deps, int nb_deps) +{ + AVBufferRef **dst; + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; + + if (!deps || !nb_deps) + return 0; + + dst = av_fast_realloc(q->buf_deps, &q->buf_deps_alloc_size, + (q->nb_buf_deps + nb_deps) * sizeof(*dst)); + if (!dst) + goto err; + + q->buf_deps = dst; + + for (int i = 0; i < nb_deps; i++) { + q->buf_deps[q->nb_buf_deps] = deps[i]; + if (!q->buf_deps[q->nb_buf_deps]) + goto err; + q->nb_buf_deps++; + } + + return 0; + +err: + ff_vk_discard_exec_deps(e); + return AVERROR(ENOMEM); +} + +FN_CREATING(FFVulkanContext, FFVkSampler, sampler, samplers, samplers_num) +FFVkSampler *ff_vk_init_sampler(FFVulkanContext *s, + int unnorm_coords, VkFilter filt) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + VkSamplerCreateInfo sampler_info = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = filt, + .minFilter = sampler_info.magFilter, + .mipmapMode = unnorm_coords ? VK_SAMPLER_MIPMAP_MODE_NEAREST : + VK_SAMPLER_MIPMAP_MODE_LINEAR, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = sampler_info.addressModeU, + .addressModeW = sampler_info.addressModeU, + .anisotropyEnable = VK_FALSE, + .compareOp = VK_COMPARE_OP_NEVER, + .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + .unnormalizedCoordinates = unnorm_coords, + }; + + FFVkSampler *sctx = create_sampler(s); + if (!sctx) + return NULL; + + ret = vk->CreateSampler(s->hwctx->act_dev, &sampler_info, + s->hwctx->alloc, &sctx->sampler[0]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init sampler: %s\n", + ff_vk_ret2str(ret)); + return NULL; + } + + for (int i = 1; i < 4; i++) + sctx->sampler[i] = sctx->sampler[0]; + + return sctx; +} + +int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt) +{ + if (pix_fmt == AV_PIX_FMT_ABGR || pix_fmt == AV_PIX_FMT_BGRA || + pix_fmt == AV_PIX_FMT_RGBA || pix_fmt == AV_PIX_FMT_RGB24 || + pix_fmt == AV_PIX_FMT_BGR24 || pix_fmt == AV_PIX_FMT_RGB48 || + pix_fmt == AV_PIX_FMT_RGBA64 || pix_fmt == AV_PIX_FMT_RGB565 || + pix_fmt == AV_PIX_FMT_BGR565 || pix_fmt == AV_PIX_FMT_BGR0 || + pix_fmt == AV_PIX_FMT_0BGR || pix_fmt == AV_PIX_FMT_RGB0) + return 1; + return 0; +} + +const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pixfmt); + const int high = desc->comp[0].depth > 8; + return high ? "rgba16f" : "rgba8"; +} + +typedef struct ImageViewCtx { + VkImageView view; +} ImageViewCtx; + +static void destroy_imageview(void *opaque, uint8_t *data) +{ + FFVulkanContext *s = opaque; + FFVulkanFunctions *vk = &s->vkfn; + ImageViewCtx *iv = (ImageViewCtx *)data; + + vk->DestroyImageView(s->hwctx->act_dev, iv->view, s->hwctx->alloc); + av_free(iv); +} + +int ff_vk_create_imageview(FFVulkanContext *s, FFVkExecContext *e, + VkImageView *v, VkImage img, VkFormat fmt, + const VkComponentMapping map) +{ + int err; + AVBufferRef *buf; + FFVulkanFunctions *vk = &s->vkfn; + + VkImageViewCreateInfo imgview_spawn = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = img, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = fmt, + .components = map, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + + ImageViewCtx *iv = av_mallocz(sizeof(*iv)); + + VkResult ret = vk->CreateImageView(s->hwctx->act_dev, &imgview_spawn, + s->hwctx->alloc, &iv->view); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Failed to create imageview: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + buf = av_buffer_create((uint8_t *)iv, sizeof(*iv), destroy_imageview, s, 0); + if (!buf) { + destroy_imageview(s, (uint8_t *)iv); + return AVERROR(ENOMEM); + } + + /* Add to queue dependencies */ + err = ff_vk_add_dep_exec_ctx(s, e, &buf, 1); + if (err) { + av_buffer_unref(&buf); + return err; + } + + *v = iv->view; + + return 0; +} + +FN_CREATING(FFVulkanPipeline, FFVkSPIRVShader, shader, shaders, shaders_num) +FFVkSPIRVShader *ff_vk_init_shader(FFVulkanPipeline *pl, const char *name, + VkShaderStageFlags stage) +{ + FFVkSPIRVShader *shd = create_shader(pl); + if (!shd) + return NULL; + + av_bprint_init(&shd->src, 0, AV_BPRINT_SIZE_UNLIMITED); + + shd->shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shd->shader.stage = stage; + + shd->name = name; + + GLSLF(0, #version %i ,460); + GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y)) ); + GLSLC(0, ); + + return shd; +} + +void ff_vk_set_compute_shader_sizes(FFVkSPIRVShader *shd, int local_size[3]) +{ + shd->local_size[0] = local_size[0]; + shd->local_size[1] = local_size[1]; + shd->local_size[2] = local_size[2]; + + av_bprintf(&shd->src, "layout (local_size_x = %i, " + "local_size_y = %i, local_size_z = %i) in;\n\n", + shd->local_size[0], shd->local_size[1], shd->local_size[2]); +} + +void ff_vk_print_shader(void *ctx, FFVkSPIRVShader *shd, int prio) +{ + int line = 0; + const char *p = shd->src.str; + const char *start = p; + const size_t len = strlen(p); + + AVBPrint buf; + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + + for (int i = 0; i < len; i++) { + if (p[i] == '\n') { + av_bprintf(&buf, "%i\t", ++line); + av_bprint_append_data(&buf, start, &p[i] - start + 1); + start = &p[i + 1]; + } + } + + av_log(ctx, prio, "Shader %s: \n%s", shd->name, buf.str); + av_bprint_finalize(&buf, NULL); +} + +int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, + const char *entrypoint) +{ + int err; + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + VkShaderModuleCreateInfo shader_create; + uint8_t *spirv; + size_t spirv_size; + void *priv; + + shd->shader.pName = entrypoint; + + if (!s->spirv_compiler) { +#if CONFIG_LIBGLSLANG + s->spirv_compiler = ff_vk_glslang_init(); +#elif CONFIG_LIBSHADERC + s->spirv_compiler = ff_vk_shaderc_init(); +#else + return AVERROR(ENOSYS); +#endif + if (!s->spirv_compiler) + return AVERROR(ENOMEM); + } + + err = s->spirv_compiler->compile_shader(s->spirv_compiler, s, shd, &spirv, + &spirv_size, entrypoint, &priv); + if (err < 0) + return err; + + av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n", + shd->name, spirv_size); + + shader_create.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_create.pNext = NULL; + shader_create.codeSize = spirv_size; + shader_create.flags = 0; + shader_create.pCode = (void *)spirv; + + ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL, + &shd->shader.module); + + s->spirv_compiler->free_shader(s->spirv_compiler, &priv); + + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to create shader module: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static const struct descriptor_props { + size_t struct_size; /* Size of the opaque which updates the descriptor */ + const char *type; + int is_uniform; + int mem_quali; /* Can use a memory qualifier */ + int dim_needed; /* Must indicate dimension */ + int buf_content; /* Must indicate buffer contents */ +} descriptor_props[] = { + [VK_DESCRIPTOR_TYPE_SAMPLER] = { sizeof(VkDescriptorImageInfo), "sampler", 1, 0, 0, 0, }, + [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE] = { sizeof(VkDescriptorImageInfo), "texture", 1, 0, 1, 0, }, + [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE] = { sizeof(VkDescriptorImageInfo), "image", 1, 1, 1, 0, }, + [VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT] = { sizeof(VkDescriptorImageInfo), "subpassInput", 1, 0, 0, 0, }, + [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = { sizeof(VkDescriptorImageInfo), "sampler", 1, 0, 1, 0, }, + [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER] = { sizeof(VkDescriptorBufferInfo), NULL, 1, 0, 0, 1, }, + [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER] = { sizeof(VkDescriptorBufferInfo), "buffer", 0, 1, 0, 1, }, + [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo), NULL, 1, 0, 0, 1, }, + [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo), "buffer", 0, 1, 0, 1, }, + [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER] = { sizeof(VkBufferView), "samplerBuffer", 1, 0, 0, 0, }, + [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = { sizeof(VkBufferView), "imageBuffer", 1, 0, 0, 0, }, +}; + +int ff_vk_add_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, + FFVkSPIRVShader *shd, FFVulkanDescriptorSetBinding *desc, + int num, int only_print_to_shader) +{ + VkResult ret; + VkDescriptorSetLayout *layout; + FFVulkanFunctions *vk = &s->vkfn; + + if (only_print_to_shader) + goto print; + + pl->desc_layout = av_realloc_array(pl->desc_layout, sizeof(*pl->desc_layout), + pl->desc_layout_num + pl->qf->nb_queues); + if (!pl->desc_layout) + return AVERROR(ENOMEM); + + pl->desc_set_initialized = av_realloc_array(pl->desc_set_initialized, + sizeof(*pl->desc_set_initialized), + pl->descriptor_sets_num + 1); + if (!pl->desc_set_initialized) + return AVERROR(ENOMEM); + + pl->desc_set_initialized[pl->descriptor_sets_num] = 0; + layout = &pl->desc_layout[pl->desc_layout_num]; + + { /* Create descriptor set layout descriptions */ + VkDescriptorSetLayoutCreateInfo desc_create_layout = { 0 }; + VkDescriptorSetLayoutBinding *desc_binding; + + desc_binding = av_mallocz(sizeof(*desc_binding)*num); + if (!desc_binding) + return AVERROR(ENOMEM); + + for (int i = 0; i < num; i++) { + desc_binding[i].binding = i; + desc_binding[i].descriptorType = desc[i].type; + desc_binding[i].descriptorCount = FFMAX(desc[i].elems, 1); + desc_binding[i].stageFlags = desc[i].stages; + desc_binding[i].pImmutableSamplers = desc[i].sampler ? + desc[i].sampler->sampler : + NULL; + } + + desc_create_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + desc_create_layout.pBindings = desc_binding; + desc_create_layout.bindingCount = num; + + for (int i = 0; i < pl->qf->nb_queues; i++) { + ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout, + s->hwctx->alloc, &layout[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init descriptor set " + "layout: %s\n", ff_vk_ret2str(ret)); + av_free(desc_binding); + return AVERROR_EXTERNAL; + } + } + + av_free(desc_binding); + } + + { /* Pool each descriptor by type and update pool counts */ + for (int i = 0; i < num; i++) { + int j; + for (j = 0; j < pl->pool_size_desc_num; j++) + if (pl->pool_size_desc[j].type == desc[i].type) + break; + if (j >= pl->pool_size_desc_num) { + pl->pool_size_desc = av_realloc_array(pl->pool_size_desc, + sizeof(*pl->pool_size_desc), + ++pl->pool_size_desc_num); + if (!pl->pool_size_desc) + return AVERROR(ENOMEM); + memset(&pl->pool_size_desc[j], 0, sizeof(VkDescriptorPoolSize)); + } + pl->pool_size_desc[j].type = desc[i].type; + pl->pool_size_desc[j].descriptorCount += FFMAX(desc[i].elems, 1)*pl->qf->nb_queues; + } + } + + { /* Create template creation struct */ + VkDescriptorUpdateTemplateCreateInfo *dt; + VkDescriptorUpdateTemplateEntry *des_entries; + + /* Freed after descriptor set initialization */ + des_entries = av_mallocz(num*sizeof(VkDescriptorUpdateTemplateEntry)); + if (!des_entries) + return AVERROR(ENOMEM); + + for (int i = 0; i < num; i++) { + des_entries[i].dstBinding = i; + des_entries[i].descriptorType = desc[i].type; + des_entries[i].descriptorCount = FFMAX(desc[i].elems, 1); + des_entries[i].dstArrayElement = 0; + des_entries[i].offset = ((uint8_t *)desc[i].updater) - (uint8_t *)s; + des_entries[i].stride = descriptor_props[desc[i].type].struct_size; + } + + pl->desc_template_info = av_realloc_array(pl->desc_template_info, + sizeof(*pl->desc_template_info), + pl->total_descriptor_sets + pl->qf->nb_queues); + if (!pl->desc_template_info) + return AVERROR(ENOMEM); + + dt = &pl->desc_template_info[pl->total_descriptor_sets]; + memset(dt, 0, sizeof(*dt)*pl->qf->nb_queues); + + for (int i = 0; i < pl->qf->nb_queues; i++) { + dt[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; + dt[i].templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; + dt[i].descriptorSetLayout = layout[i]; + dt[i].pDescriptorUpdateEntries = des_entries; + dt[i].descriptorUpdateEntryCount = num; + } + } + + pl->descriptor_sets_num++; + + pl->desc_layout_num += pl->qf->nb_queues; + pl->total_descriptor_sets += pl->qf->nb_queues; + +print: + /* Write shader info */ + for (int i = 0; i < num; i++) { + const struct descriptor_props *prop = &descriptor_props[desc[i].type]; + GLSLA("layout (set = %i, binding = %i", pl->descriptor_sets_num - 1, i); + + if (desc[i].mem_layout) + GLSLA(", %s", desc[i].mem_layout); + GLSLA(")"); + + if (prop->is_uniform) + GLSLA(" uniform"); + + if (prop->mem_quali && desc[i].mem_quali) + GLSLA(" %s", desc[i].mem_quali); + + if (prop->type) + GLSLA(" %s", prop->type); + + if (prop->dim_needed) + GLSLA("%iD", desc[i].dimensions); + + GLSLA(" %s", desc[i].name); + + if (prop->buf_content) + GLSLA(" {\n %s\n}", desc[i].buf_content); + else if (desc[i].elems > 0) + GLSLA("[%i]", desc[i].elems); + + GLSLA(";\n"); + } + GLSLA("\n"); + + return 0; +} + +void ff_vk_update_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, + int set_id) +{ + FFVulkanFunctions *vk = &s->vkfn; + + /* If a set has never been updated, update all queues' sets. */ + if (!pl->desc_set_initialized[set_id]) { + for (int i = 0; i < pl->qf->nb_queues; i++) { + int idx = set_id*pl->qf->nb_queues + i; + vk->UpdateDescriptorSetWithTemplate(s->hwctx->act_dev, + pl->desc_set[idx], + pl->desc_template[idx], + s); + } + pl->desc_set_initialized[set_id] = 1; + return; + } + + set_id = set_id*pl->qf->nb_queues + pl->qf->cur_queue; + + vk->UpdateDescriptorSetWithTemplate(s->hwctx->act_dev, + pl->desc_set[set_id], + pl->desc_template[set_id], + s); +} + +void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e, + VkShaderStageFlagBits stage, int offset, + size_t size, void *src) +{ + FFVulkanFunctions *vk = &s->vkfn; + + vk->CmdPushConstants(e->bufs[e->qf->cur_queue], e->bound_pl->pipeline_layout, + stage, offset, size, src); +} + +int ff_vk_init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + pl->desc_staging = av_malloc(pl->descriptor_sets_num*sizeof(*pl->desc_staging)); + if (!pl->desc_staging) + return AVERROR(ENOMEM); + + { /* Init descriptor set pool */ + VkDescriptorPoolCreateInfo pool_create_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = pl->pool_size_desc_num, + .pPoolSizes = pl->pool_size_desc, + .maxSets = pl->total_descriptor_sets, + }; + + ret = vk->CreateDescriptorPool(s->hwctx->act_dev, &pool_create_info, + s->hwctx->alloc, &pl->desc_pool); + av_freep(&pl->pool_size_desc); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init descriptor set " + "pool: %s\n", ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + { /* Allocate descriptor sets */ + VkDescriptorSetAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = pl->desc_pool, + .descriptorSetCount = pl->total_descriptor_sets, + .pSetLayouts = pl->desc_layout, + }; + + pl->desc_set = av_malloc(pl->total_descriptor_sets*sizeof(*pl->desc_set)); + if (!pl->desc_set) + return AVERROR(ENOMEM); + + ret = vk->AllocateDescriptorSets(s->hwctx->act_dev, &alloc_info, + pl->desc_set); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to allocate descriptor set: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + { /* Finally create the pipeline layout */ + VkPipelineLayoutCreateInfo spawn_pipeline_layout = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pSetLayouts = (VkDescriptorSetLayout *)pl->desc_staging, + .pushConstantRangeCount = pl->push_consts_num, + .pPushConstantRanges = pl->push_consts, + }; + + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) + pl->desc_staging[spawn_pipeline_layout.setLayoutCount++] = pl->desc_layout[i]; + + ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &spawn_pipeline_layout, + s->hwctx->alloc, &pl->pipeline_layout); + av_freep(&pl->push_consts); + pl->push_consts_num = 0; + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + { /* Descriptor template (for tightly packed descriptors) */ + VkDescriptorUpdateTemplateCreateInfo *dt; + + pl->desc_template = av_malloc(pl->total_descriptor_sets*sizeof(*pl->desc_template)); + if (!pl->desc_template) + return AVERROR(ENOMEM); + + /* Create update templates for the descriptor sets */ + for (int i = 0; i < pl->total_descriptor_sets; i++) { + dt = &pl->desc_template_info[i]; + dt->pipelineLayout = pl->pipeline_layout; + ret = vk->CreateDescriptorUpdateTemplate(s->hwctx->act_dev, + dt, s->hwctx->alloc, + &pl->desc_template[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init descriptor " + "template: %s\n", ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + } + + /* Free the duplicated memory used for the template entries */ + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) { + dt = &pl->desc_template_info[i]; + av_free((void *)dt->pDescriptorUpdateEntries); + } + + av_freep(&pl->desc_template_info); + } + + return 0; +} + +FN_CREATING(FFVulkanContext, FFVulkanPipeline, pipeline, pipelines, pipelines_num) +FFVulkanPipeline *ff_vk_create_pipeline(FFVulkanContext *s, FFVkQueueFamilyCtx *qf) +{ + FFVulkanPipeline *pl = create_pipeline(s); + if (pl) + pl->qf = qf; + + return pl; +} + +int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl) +{ + int i; + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + VkComputePipelineCreateInfo pipe = { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .layout = pl->pipeline_layout, + }; + + for (i = 0; i < pl->shaders_num; i++) { + if (pl->shaders[i]->shader.stage & VK_SHADER_STAGE_COMPUTE_BIT) { + pipe.stage = pl->shaders[i]->shader; + break; + } + } + if (i == pl->shaders_num) { + av_log(s, AV_LOG_ERROR, "Can't init compute pipeline, no shader\n"); + return AVERROR(EINVAL); + } + + ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1, &pipe, + s->hwctx->alloc, &pl->pipeline); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + pl->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; + + return 0; +} + +void ff_vk_bind_pipeline_exec(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanPipeline *pl) +{ + FFVulkanFunctions *vk = &s->vkfn; + + vk->CmdBindPipeline(e->bufs[e->qf->cur_queue], pl->bind_point, pl->pipeline); + + for (int i = 0; i < pl->descriptor_sets_num; i++) + pl->desc_staging[i] = pl->desc_set[i*pl->qf->nb_queues + pl->qf->cur_queue]; + + vk->CmdBindDescriptorSets(e->bufs[e->qf->cur_queue], pl->bind_point, + pl->pipeline_layout, 0, + pl->descriptor_sets_num, + (VkDescriptorSet *)pl->desc_staging, + 0, NULL); + + e->bound_pl = pl; +} + +static void free_exec_ctx(FFVulkanContext *s, FFVkExecContext *e) +{ + FFVulkanFunctions *vk = &s->vkfn; + + /* Make sure all queues have finished executing */ + for (int i = 0; i < e->qf->nb_queues; i++) { + FFVkQueueCtx *q = &e->queues[i]; + + if (q->fence) { + vk->WaitForFences(s->hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX); + vk->ResetFences(s->hwctx->act_dev, 1, &q->fence); + } + + /* Free the fence */ + if (q->fence) + vk->DestroyFence(s->hwctx->act_dev, q->fence, s->hwctx->alloc); + + /* Free buffer dependencies */ + for (int j = 0; j < q->nb_buf_deps; j++) + av_buffer_unref(&q->buf_deps[j]); + av_free(q->buf_deps); + + /* Free frame dependencies */ + for (int j = 0; j < q->nb_frame_deps; j++) + av_frame_free(&q->frame_deps[j]); + av_free(q->frame_deps); + } + + if (e->bufs) + vk->FreeCommandBuffers(s->hwctx->act_dev, e->pool, e->qf->nb_queues, e->bufs); + if (e->pool) + vk->DestroyCommandPool(s->hwctx->act_dev, e->pool, s->hwctx->alloc); + + av_freep(&e->bufs); + av_freep(&e->queues); + av_freep(&e->sem_sig); + av_freep(&e->sem_sig_val); + av_freep(&e->sem_sig_val_dst); + av_freep(&e->sem_wait); + av_freep(&e->sem_wait_dst); + av_freep(&e->sem_wait_val); + av_free(e); +} + +static void free_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl) +{ + FFVulkanFunctions *vk = &s->vkfn; + + for (int i = 0; i < pl->shaders_num; i++) { + FFVkSPIRVShader *shd = pl->shaders[i]; + av_bprint_finalize(&shd->src, NULL); + vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, + s->hwctx->alloc); + av_free(shd); + } + + vk->DestroyPipeline(s->hwctx->act_dev, pl->pipeline, s->hwctx->alloc); + vk->DestroyPipelineLayout(s->hwctx->act_dev, pl->pipeline_layout, + s->hwctx->alloc); + + for (int i = 0; i < pl->desc_layout_num; i++) { + if (pl->desc_template && pl->desc_template[i]) + vk->DestroyDescriptorUpdateTemplate(s->hwctx->act_dev, pl->desc_template[i], + s->hwctx->alloc); + if (pl->desc_layout && pl->desc_layout[i]) + vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, pl->desc_layout[i], + s->hwctx->alloc); + } + + /* Also frees the descriptor sets */ + if (pl->desc_pool) + vk->DestroyDescriptorPool(s->hwctx->act_dev, pl->desc_pool, + s->hwctx->alloc); + + av_freep(&pl->desc_staging); + av_freep(&pl->desc_set); + av_freep(&pl->shaders); + av_freep(&pl->desc_layout); + av_freep(&pl->desc_template); + av_freep(&pl->desc_set_initialized); + av_freep(&pl->push_consts); + pl->push_consts_num = 0; + + /* Only freed in case of failure */ + av_freep(&pl->pool_size_desc); + if (pl->desc_template_info) { + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) { + VkDescriptorUpdateTemplateCreateInfo *dt = &pl->desc_template_info[i]; + av_free((void *)dt->pDescriptorUpdateEntries); + } + av_freep(&pl->desc_template_info); + } + + av_free(pl); +} + +void ff_vk_uninit(FFVulkanContext *s) +{ + FFVulkanFunctions *vk = &s->vkfn; + + if (s->spirv_compiler) + s->spirv_compiler->uninit(&s->spirv_compiler); + + for (int i = 0; i < s->exec_ctx_num; i++) + free_exec_ctx(s, s->exec_ctx[i]); + av_freep(&s->exec_ctx); + + for (int i = 0; i < s->samplers_num; i++) { + vk->DestroySampler(s->hwctx->act_dev, s->samplers[i]->sampler[0], + s->hwctx->alloc); + av_free(s->samplers[i]); + } + av_freep(&s->samplers); + + for (int i = 0; i < s->pipelines_num; i++) + free_pipeline(s, s->pipelines[i]); + av_freep(&s->pipelines); + + av_freep(&s->scratch); + s->scratch_size = 0; + + av_buffer_unref(&s->device_ref); + av_buffer_unref(&s->frames_ref); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan.h b/arm/raspi/third_party/ffmpeg/libavutil/vulkan.h new file mode 100644 index 00000000..d1ea1e24 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan.h @@ -0,0 +1,422 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VULKAN_H +#define AVUTIL_VULKAN_H + +#include "pixdesc.h" +#include "bprint.h" +#include "hwcontext.h" +#include "vulkan_functions.h" +#include "hwcontext_vulkan.h" +#include "vulkan_loader.h" + +#define FF_VK_DEFAULT_USAGE_FLAGS (VK_IMAGE_USAGE_SAMPLED_BIT | \ + VK_IMAGE_USAGE_STORAGE_BIT | \ + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | \ + VK_IMAGE_USAGE_TRANSFER_DST_BIT) + +/* GLSL management macros */ +#define INDENT(N) INDENT_##N +#define INDENT_0 +#define INDENT_1 INDENT_0 " " +#define INDENT_2 INDENT_1 INDENT_1 +#define INDENT_3 INDENT_2 INDENT_1 +#define INDENT_4 INDENT_3 INDENT_1 +#define INDENT_5 INDENT_4 INDENT_1 +#define INDENT_6 INDENT_5 INDENT_1 +#define C(N, S) INDENT(N) #S "\n" +#define GLSLC(N, S) av_bprintf(&shd->src, C(N, S)) +#define GLSLA(...) av_bprintf(&shd->src, __VA_ARGS__) +#define GLSLF(N, S, ...) av_bprintf(&shd->src, C(N, S), __VA_ARGS__) +#define GLSLD(D) GLSLC(0, ); \ + av_bprint_append_data(&shd->src, D, strlen(D)); \ + GLSLC(0, ) + +/* Helper, pretty much every Vulkan return value needs to be checked */ +#define RET(x) \ + do { \ + if ((err = (x)) < 0) \ + goto fail; \ + } while (0) + +typedef struct FFVkSPIRVShader { + const char *name; /* Name for id/debugging purposes */ + AVBPrint src; + int local_size[3]; /* Compute shader workgroup sizes */ + VkPipelineShaderStageCreateInfo shader; +} FFVkSPIRVShader; + +typedef struct FFVkSPIRVCompiler { + void *priv; + int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, + struct FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, void **opaque); + void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque); + void (*uninit)(struct FFVkSPIRVCompiler **ctx); +} FFVkSPIRVCompiler; + +typedef struct FFVkSampler { + VkSampler sampler[4]; +} FFVkSampler; + +typedef struct FFVulkanDescriptorSetBinding { + const char *name; + VkDescriptorType type; + const char *mem_layout; /* Storage images (rgba8, etc.) and buffers (std430, etc.) */ + const char *mem_quali; /* readonly, writeonly, etc. */ + const char *buf_content; /* For buffers */ + uint32_t dimensions; /* Needed for e.g. sampler%iD */ + uint32_t elems; /* 0 - scalar, 1 or more - vector */ + VkShaderStageFlags stages; + FFVkSampler *sampler; /* Sampler to use for all elems */ + void *updater; /* Pointer to VkDescriptor*Info */ +} FFVulkanDescriptorSetBinding; + +typedef struct FFVkBuffer { + VkBuffer buf; + VkDeviceMemory mem; + VkMemoryPropertyFlagBits flags; +} FFVkBuffer; + +typedef struct FFVkQueueFamilyCtx { + int queue_family; + int nb_queues; + int cur_queue; + int actual_queues; +} FFVkQueueFamilyCtx; + +typedef struct FFVulkanPipeline { + FFVkQueueFamilyCtx *qf; + + VkPipelineBindPoint bind_point; + + /* Contexts */ + VkPipelineLayout pipeline_layout; + VkPipeline pipeline; + + /* Shaders */ + FFVkSPIRVShader **shaders; + int shaders_num; + + /* Push consts */ + VkPushConstantRange *push_consts; + int push_consts_num; + + /* Descriptors */ + VkDescriptorSetLayout *desc_layout; + VkDescriptorPool desc_pool; + VkDescriptorSet *desc_set; + void **desc_staging; + VkDescriptorSetLayoutBinding **desc_binding; + VkDescriptorUpdateTemplate *desc_template; + int *desc_set_initialized; + int desc_layout_num; + int descriptor_sets_num; + int total_descriptor_sets; + int pool_size_desc_num; + + /* Temporary, used to store data in between initialization stages */ + VkDescriptorUpdateTemplateCreateInfo *desc_template_info; + VkDescriptorPoolSize *pool_size_desc; +} FFVulkanPipeline; + +typedef struct FFVkQueueCtx { + VkFence fence; + VkQueue queue; + + /* Buffer dependencies */ + AVBufferRef **buf_deps; + int nb_buf_deps; + int buf_deps_alloc_size; + + /* Frame dependencies */ + AVFrame **frame_deps; + int nb_frame_deps; + int frame_deps_alloc_size; +} FFVkQueueCtx; + +typedef struct FFVkExecContext { + FFVkQueueFamilyCtx *qf; + + VkCommandPool pool; + VkCommandBuffer *bufs; + FFVkQueueCtx *queues; + + AVBufferRef ***deps; + int *nb_deps; + int *dep_alloc_size; + + FFVulkanPipeline *bound_pl; + + VkSemaphore *sem_wait; + int sem_wait_alloc; /* Allocated sem_wait */ + int sem_wait_cnt; + + uint64_t *sem_wait_val; + int sem_wait_val_alloc; + + VkPipelineStageFlagBits *sem_wait_dst; + int sem_wait_dst_alloc; /* Allocated sem_wait_dst */ + + VkSemaphore *sem_sig; + int sem_sig_alloc; /* Allocated sem_sig */ + int sem_sig_cnt; + + uint64_t *sem_sig_val; + int sem_sig_val_alloc; + + uint64_t **sem_sig_val_dst; + int sem_sig_val_dst_alloc; +} FFVkExecContext; + +typedef struct FFVulkanContext { + const AVClass *class; /* Filters and encoders use this */ + + FFVulkanFunctions vkfn; + FFVulkanExtensions extensions; + VkPhysicalDeviceProperties props; + VkPhysicalDeviceMemoryProperties mprops; + + AVBufferRef *device_ref; + AVHWDeviceContext *device; + AVVulkanDeviceContext *hwctx; + + AVBufferRef *frames_ref; + AVHWFramesContext *frames; + AVVulkanFramesContext *hwfc; + + FFVkSPIRVCompiler *spirv_compiler; + + /* Properties */ + int output_width; + int output_height; + enum AVPixelFormat output_format; + enum AVPixelFormat input_format; + + /* Samplers */ + FFVkSampler **samplers; + int samplers_num; + + /* Exec contexts */ + FFVkExecContext **exec_ctx; + int exec_ctx_num; + + /* Pipelines (each can have 1 shader of each type) */ + FFVulkanPipeline **pipelines; + int pipelines_num; + + void *scratch; /* Scratch memory used only in functions */ + unsigned int scratch_size; +} FFVulkanContext; + +/* Identity mapping - r = r, b = b, g = g, a = a */ +extern const VkComponentMapping ff_comp_identity_map; + +/** + * Converts Vulkan return values to strings + */ +const char *ff_vk_ret2str(VkResult res); + +/** + * Returns 1 if the image is any sort of supported RGB + */ +int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt); + +/** + * Gets the glsl format string for a pixel format + */ +const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt); + +/** + * Initialize a queue family with a specific number of queues. + * If nb_queues == 0, use however many queues the queue family has. + */ +void ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf, + VkQueueFlagBits dev_family, int nb_queues); + +/** + * Rotate through the queues in a queue family. + */ +void ff_vk_qf_rotate(FFVkQueueFamilyCtx *qf); + +/** + * Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit() + */ +FFVkSampler *ff_vk_init_sampler(FFVulkanContext *s, int unnorm_coords, + VkFilter filt); + +/** + * Create an imageview. + * Guaranteed to remain alive until the queue submission has finished executing, + * and will be destroyed after that. + */ +int ff_vk_create_imageview(FFVulkanContext *s, FFVkExecContext *e, + VkImageView *v, VkImage img, VkFormat fmt, + const VkComponentMapping map); + +/** + * Define a push constant for a given stage into a pipeline. + * Must be called before the pipeline layout has been initialized. + */ +int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size, + VkShaderStageFlagBits stage); + +/** + * Inits a pipeline. Everything in it will be auto-freed when calling + * ff_vk_filter_uninit(). + */ +FFVulkanPipeline *ff_vk_create_pipeline(FFVulkanContext *s, FFVkQueueFamilyCtx *qf); + +/** + * Inits a shader for a specific pipeline. Will be auto-freed on uninit. + */ +FFVkSPIRVShader *ff_vk_init_shader(FFVulkanPipeline *pl, const char *name, + VkShaderStageFlags stage); + +/** + * Writes the workgroup size for a shader. + */ +void ff_vk_set_compute_shader_sizes(FFVkSPIRVShader *shd, int local_size[3]); + +/** + * Adds a descriptor set to the shader and registers them in the pipeline. + */ +int ff_vk_add_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, + FFVkSPIRVShader *shd, FFVulkanDescriptorSetBinding *desc, + int num, int only_print_to_shader); + +/** + * Compiles the shader, entrypoint must be set to "main". + */ +int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, + const char *entrypoint); + +/** + * Pretty print shader, mainly used by shader compilers. + */ +void ff_vk_print_shader(void *ctx, FFVkSPIRVShader *shd, int prio); + +/** + * Initializes the pipeline layout after all shaders and descriptor sets have + * been finished. + */ +int ff_vk_init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl); + +/** + * Initializes a compute pipeline. Will pick the first shader with the + * COMPUTE flag set. + */ +int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl); + +/** + * Updates a descriptor set via the updaters defined. + * Can be called immediately after pipeline creation, but must be called + * at least once before queue submission. + */ +void ff_vk_update_descriptor_set(FFVulkanContext *s, FFVulkanPipeline *pl, + int set_id); + +/** + * Init an execution context for command recording and queue submission. + * WIll be auto-freed on uninit. + */ +int ff_vk_create_exec_ctx(FFVulkanContext *s, FFVkExecContext **ctx, + FFVkQueueFamilyCtx *qf); + +/** + * Begin recording to the command buffer. Previous execution must have been + * completed, which ff_vk_submit_exec_queue() will ensure. + */ +int ff_vk_start_exec_recording(FFVulkanContext *s, FFVkExecContext *e); + +/** + * Add a command to bind the completed pipeline and its descriptor sets. + * Must be called after ff_vk_start_exec_recording() and before submission. + */ +void ff_vk_bind_pipeline_exec(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanPipeline *pl); + +/** + * Updates push constants. + * Must be called after binding a pipeline if any push constants were defined. + */ +void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e, + VkShaderStageFlagBits stage, int offset, + size_t size, void *src); + +/** + * Gets the command buffer to use for this submission from the exe context. + */ +VkCommandBuffer ff_vk_get_exec_buf(FFVkExecContext *e); + +/** + * Adds a generic AVBufferRef as a queue depenency. + */ +int ff_vk_add_dep_exec_ctx(FFVulkanContext *s, FFVkExecContext *e, + AVBufferRef **deps, int nb_deps); + +/** + * Discards all queue dependencies + */ +void ff_vk_discard_exec_deps(FFVkExecContext *e); + +/** + * Adds a frame as a queue dependency. This also manages semaphore signalling. + * Must be called before submission. + */ +int ff_vk_add_exec_dep(FFVulkanContext *s, FFVkExecContext *e, AVFrame *frame, + VkPipelineStageFlagBits in_wait_dst_flag); + +/** + * Submits a command buffer to the queue for execution. + * Will block until execution has finished in order to simplify resource + * management. + */ +int ff_vk_submit_exec_queue(FFVulkanContext *s, FFVkExecContext *e); + +/** + * Create a VkBuffer with the specified parameters. + */ +int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, + VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags); + +/** + * Maps the buffer to userspace. Set invalidate to 1 if reading the contents + * is necessary. + */ +int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer *buf, uint8_t *mem[], + int nb_buffers, int invalidate); + +/** + * Unmaps the buffer from userspace. Set flush to 1 to write and sync. + */ +int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer *buf, int nb_buffers, + int flush); + +/** + * Frees a buffer. + */ +void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf); + +/** + * Frees the main Vulkan context. + */ +void ff_vk_uninit(FFVulkanContext *s); + +#endif /* AVUTIL_VULKAN_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan_functions.h b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_functions.h new file mode 100644 index 00000000..d15a5d9a --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_functions.h @@ -0,0 +1,182 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VULKAN_FUNCTIONS_H +#define AVUTIL_VULKAN_FUNCTIONS_H + +#define VK_NO_PROTOTYPES +#define VK_ENABLE_BETA_EXTENSIONS + +#include "hwcontext.h" +#include "hwcontext_vulkan.h" + +/* An enum of bitflags for every optional extension we need */ +typedef enum FFVulkanExtensions { + FF_VK_EXT_EXTERNAL_DMABUF_MEMORY = 1ULL << 0, /* VK_EXT_external_memory_dma_buf */ + FF_VK_EXT_DRM_MODIFIER_FLAGS = 1ULL << 1, /* VK_EXT_image_drm_format_modifier */ + FF_VK_EXT_EXTERNAL_FD_MEMORY = 1ULL << 2, /* VK_KHR_external_memory_fd */ + FF_VK_EXT_EXTERNAL_FD_SEM = 1ULL << 3, /* VK_KHR_external_semaphore_fd */ + FF_VK_EXT_EXTERNAL_HOST_MEMORY = 1ULL << 4, /* VK_EXT_external_memory_host */ + FF_VK_EXT_DEBUG_UTILS = 1ULL << 5, /* VK_EXT_debug_utils */ +#ifdef _WIN32 + FF_VK_EXT_EXTERNAL_WIN32_MEMORY = 1ULL << 6, /* VK_KHR_external_memory_win32 */ + FF_VK_EXT_EXTERNAL_WIN32_SEM = 1ULL << 7, /* VK_KHR_external_semaphore_win32 */ +#endif + + FF_VK_EXT_NO_FLAG = 1ULL << 31, +} FFVulkanExtensions; + +/* Macro containing every function that we utilize in our codebase */ +#define FN_LIST(MACRO) \ + /* Instance */ \ + MACRO(0, 0, FF_VK_EXT_NO_FLAG, EnumerateInstanceExtensionProperties) \ + MACRO(0, 0, FF_VK_EXT_NO_FLAG, EnumerateInstanceLayerProperties) \ + MACRO(0, 0, FF_VK_EXT_NO_FLAG, CreateInstance) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyInstance) \ + \ + /* Debug */ \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDebugUtilsMessengerEXT) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyDebugUtilsMessengerEXT) \ + \ + /* Device */ \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetDeviceProcAddr) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDevice) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFeatures2) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, DeviceWaitIdle) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyDevice) \ + \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, EnumeratePhysicalDevices) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, EnumerateDeviceExtensionProperties) \ + \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties2) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceMemoryProperties) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFormatProperties2) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceImageFormatProperties2) \ + MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceQueueFamilyProperties) \ + \ + /* Command pool */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateCommandPool) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyCommandPool) \ + \ + /* Command buffer */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateCommandBuffers) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, BeginCommandBuffer) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, EndCommandBuffer) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, FreeCommandBuffers) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdDispatch) \ + \ + /* Queue */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetDeviceQueue) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, QueueSubmit) \ + \ + /* Fences */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateFence) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, WaitForFences) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, ResetFences) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyFence) \ + \ + /* Semaphores */ \ + MACRO(1, 1, FF_VK_EXT_EXTERNAL_FD_SEM, GetSemaphoreFdKHR) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateSemaphore) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, WaitSemaphores) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroySemaphore) \ + \ + /* Memory */ \ + MACRO(1, 1, FF_VK_EXT_EXTERNAL_FD_MEMORY, GetMemoryFdKHR) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetMemoryFdPropertiesKHR) \ + MACRO(1, 1, FF_VK_EXT_EXTERNAL_HOST_MEMORY, GetMemoryHostPointerPropertiesEXT) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateMemory) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, MapMemory) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, FlushMappedMemoryRanges) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, InvalidateMappedMemoryRanges) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, UnmapMemory) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, FreeMemory) \ + \ + /* Commands */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdBindDescriptorSets) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdPushConstants) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdBindPipeline) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdPipelineBarrier) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdCopyBufferToImage) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdCopyImageToBuffer) \ + \ + /* Buffer */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetBufferMemoryRequirements2) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateBuffer) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, BindBufferMemory) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyBuffer) \ + \ + /* Image */ \ + MACRO(1, 1, FF_VK_EXT_DRM_MODIFIER_FLAGS, GetImageDrmFormatModifierPropertiesEXT) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetImageMemoryRequirements2) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateImage) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, BindImageMemory2) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetImageSubresourceLayout) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyImage) \ + \ + /* ImageView */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateImageView) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyImageView) \ + \ + /* DescriptorSet */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorSetLayout) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateDescriptorSets) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorPool) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorPool) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorSetLayout) \ + \ + /* DescriptorUpdateTemplate */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, UpdateDescriptorSetWithTemplate) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorUpdateTemplate) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorUpdateTemplate) \ + \ + /* Pipeline */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreatePipelineLayout) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyPipelineLayout) \ + \ + /* PipelineLayout */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateComputePipelines) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyPipeline) \ + \ + /* Sampler */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateSampler) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroySampler) \ + \ + /* Shaders */ \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateShaderModule) \ + MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyShaderModule) + +/* Macro containing every win32 specific function that we utilize in our codebase */ +#define FN_LIST_WIN32(MACRO) \ + MACRO(1, 1, FF_VK_EXT_EXTERNAL_WIN32_SEM, GetSemaphoreWin32HandleKHR) \ + MACRO(1, 1, FF_VK_EXT_EXTERNAL_WIN32_MEMORY, GetMemoryWin32HandleKHR) + +/* Macro to turn a function name into a definition */ +#define PFN_DEF(req_inst, req_dev, ext_flag, name) \ + PFN_vk##name name; + +/* Structure with the definition of all listed functions */ +typedef struct FFVulkanFunctions { + FN_LIST(PFN_DEF) +#ifdef _WIN32 + FN_LIST_WIN32(PFN_DEF) +#endif +} FFVulkanFunctions; + +#endif /* AVUTIL_VULKAN_FUNCTIONS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan_glslang.c b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_glslang.c new file mode 100644 index 00000000..e7785f6d --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_glslang.c @@ -0,0 +1,280 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "mem.h" +#include "avassert.h" + +static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER; +static int glslc_refcount = 0; + +static const glslang_resource_t glslc_resource_limits = { + .max_lights = 32, + .max_clip_planes = 6, + .max_texture_units = 32, + .max_texture_coords = 32, + .max_vertex_attribs = 64, + .max_vertex_uniform_components = 4096, + .max_varying_floats = 64, + .max_vertex_texture_image_units = 32, + .max_combined_texture_image_units = 80, + .max_texture_image_units = 32, + .max_fragment_uniform_components = 4096, + .max_draw_buffers = 32, + .max_vertex_uniform_vectors = 128, + .max_varying_vectors = 8, + .max_fragment_uniform_vectors = 16, + .max_vertex_output_vectors = 16, + .max_fragment_input_vectors = 15, + .min_program_texel_offset = -8, + .max_program_texel_offset = 7, + .max_clip_distances = 8, + .max_compute_work_group_count_x = 65535, + .max_compute_work_group_count_y = 65535, + .max_compute_work_group_count_z = 65535, + .max_compute_work_group_size_x = 1024, + .max_compute_work_group_size_y = 1024, + .max_compute_work_group_size_z = 64, + .max_compute_uniform_components = 1024, + .max_compute_texture_image_units = 16, + .max_compute_image_uniforms = 8, + .max_compute_atomic_counters = 8, + .max_compute_atomic_counter_buffers = 1, + .max_varying_components = 60, + .max_vertex_output_components = 64, + .max_geometry_input_components = 64, + .max_geometry_output_components = 128, + .max_fragment_input_components = 128, + .max_image_units = 8, + .max_combined_image_units_and_fragment_outputs = 8, + .max_combined_shader_output_resources = 8, + .max_image_samples = 0, + .max_vertex_image_uniforms = 0, + .max_tess_control_image_uniforms = 0, + .max_tess_evaluation_image_uniforms = 0, + .max_geometry_image_uniforms = 0, + .max_fragment_image_uniforms = 8, + .max_combined_image_uniforms = 8, + .max_geometry_texture_image_units = 16, + .max_geometry_output_vertices = 256, + .max_geometry_total_output_components = 1024, + .max_geometry_uniform_components = 1024, + .max_geometry_varying_components = 64, + .max_tess_control_input_components = 128, + .max_tess_control_output_components = 128, + .max_tess_control_texture_image_units = 16, + .max_tess_control_uniform_components = 1024, + .max_tess_control_total_output_components = 4096, + .max_tess_evaluation_input_components = 128, + .max_tess_evaluation_output_components = 128, + .max_tess_evaluation_texture_image_units = 16, + .max_tess_evaluation_uniform_components = 1024, + .max_tess_patch_components = 120, + .max_patch_vertices = 32, + .max_tess_gen_level = 64, + .max_viewports = 16, + .max_vertex_atomic_counters = 0, + .max_tess_control_atomic_counters = 0, + .max_tess_evaluation_atomic_counters = 0, + .max_geometry_atomic_counters = 0, + .max_fragment_atomic_counters = 8, + .max_combined_atomic_counters = 8, + .max_atomic_counter_bindings = 1, + .max_vertex_atomic_counter_buffers = 0, + .max_tess_control_atomic_counter_buffers = 0, + .max_tess_evaluation_atomic_counter_buffers = 0, + .max_geometry_atomic_counter_buffers = 0, + .max_fragment_atomic_counter_buffers = 1, + .max_combined_atomic_counter_buffers = 1, + .max_atomic_counter_buffer_size = 16384, + .max_transform_feedback_buffers = 4, + .max_transform_feedback_interleaved_components = 64, + .max_cull_distances = 8, + .max_combined_clip_and_cull_distances = 8, + .max_samples = 4, + .max_mesh_output_vertices_nv = 256, + .max_mesh_output_primitives_nv = 512, + .max_mesh_work_group_size_x_nv = 32, + .max_mesh_work_group_size_y_nv = 1, + .max_mesh_work_group_size_z_nv = 1, + .max_task_work_group_size_x_nv = 32, + .max_task_work_group_size_y_nv = 1, + .max_task_work_group_size_z_nv = 1, + .max_mesh_view_count_nv = 4, + .maxDualSourceDrawBuffersEXT = 1, + + .limits = { + .non_inductive_for_loops = 1, + .while_loops = 1, + .do_while_loops = 1, + .general_uniform_indexing = 1, + .general_attribute_matrix_vector_indexing = 1, + .general_varying_indexing = 1, + .general_sampler_indexing = 1, + .general_variable_indexing = 1, + .general_constant_matrix_vector_indexing = 1, + } +}; + +static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, + FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, + void **opaque) +{ + const char *messages; + glslang_shader_t *glslc_shader; + glslang_program_t *glslc_program; + + static const glslang_stage_t glslc_stage[] = { + [VK_SHADER_STAGE_VERTEX_BIT] = GLSLANG_STAGE_VERTEX, + [VK_SHADER_STAGE_FRAGMENT_BIT] = GLSLANG_STAGE_FRAGMENT, + [VK_SHADER_STAGE_COMPUTE_BIT] = GLSLANG_STAGE_COMPUTE, + }; + + const glslang_input_t glslc_input = { + .language = GLSLANG_SOURCE_GLSL, + .stage = glslc_stage[shd->shader.stage], + .client = GLSLANG_CLIENT_VULKAN, + /* GLSLANG_TARGET_VULKAN_1_2 before 11.6 resulted in targeting 1.0 */ +#if (((GLSLANG_VERSION_MAJOR) > 11) || ((GLSLANG_VERSION_MAJOR) == 11 && \ + (((GLSLANG_VERSION_MINOR) > 6) || ((GLSLANG_VERSION_MINOR) == 6 && \ + ((GLSLANG_VERSION_PATCH) > 0))))) + .client_version = GLSLANG_TARGET_VULKAN_1_2, + .target_language_version = GLSLANG_TARGET_SPV_1_5, +#else + .client_version = GLSLANG_TARGET_VULKAN_1_1, + .target_language_version = GLSLANG_TARGET_SPV_1_3, +#endif + .target_language = GLSLANG_TARGET_SPV, + .code = shd->src.str, + .default_version = 460, + .default_profile = GLSLANG_NO_PROFILE, + .force_default_version_and_profile = false, + .forward_compatible = false, + .messages = GLSLANG_MSG_DEFAULT_BIT, + .resource = &glslc_resource_limits, + }; + + av_assert0(glslc_refcount); + + if (!(glslc_shader = glslang_shader_create(&glslc_input))) + return AVERROR(ENOMEM); + + if (!glslang_shader_preprocess(glslc_shader, &glslc_input)) { + ff_vk_print_shader(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to preprocess shader: %s (%s)!\n", + glslang_shader_get_info_log(glslc_shader), + glslang_shader_get_info_debug_log(glslc_shader)); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + if (!glslang_shader_parse(glslc_shader, &glslc_input)) { + ff_vk_print_shader(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to parse shader: %s (%s)!\n", + glslang_shader_get_info_log(glslc_shader), + glslang_shader_get_info_debug_log(glslc_shader)); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + if (!(glslc_program = glslang_program_create())) { + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + glslang_program_add_shader(glslc_program, glslc_shader); + + if (!glslang_program_link(glslc_program, GLSLANG_MSG_SPV_RULES_BIT | + GLSLANG_MSG_VULKAN_RULES_BIT)) { + ff_vk_print_shader(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to link shader: %s (%s)!\n", + glslang_program_get_info_log(glslc_program), + glslang_program_get_info_debug_log(glslc_program)); + glslang_program_delete(glslc_program); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + glslang_program_SPIRV_generate(glslc_program, glslc_input.stage); + + messages = glslang_program_SPIRV_get_messages(glslc_program); + if (messages) { + ff_vk_print_shader(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_WARNING, "%s\n", messages); + } else { + ff_vk_print_shader(avctx, shd, AV_LOG_VERBOSE); + } + + glslang_shader_delete(glslc_shader); + + *size = glslang_program_SPIRV_get_size(glslc_program) * sizeof(unsigned int); + *data = (void *)glslang_program_SPIRV_get_ptr(glslc_program); + *opaque = glslc_program; + + return 0; +} + +static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) +{ + if (!opaque || !*opaque) + return; + + av_assert0(glslc_refcount); + glslang_program_delete(*opaque); + *opaque = NULL; +} + +static void glslc_uninit(FFVkSPIRVCompiler **ctx) +{ + if (!ctx || !*ctx) + return; + + pthread_mutex_lock(&glslc_mutex); + if (glslc_refcount && (--glslc_refcount == 0)) + glslang_finalize_process(); + pthread_mutex_unlock(&glslc_mutex); + + av_freep(ctx); +} + +static FFVkSPIRVCompiler *ff_vk_glslang_init(void) +{ + FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->compile_shader = glslc_shader_compile; + ret->free_shader = glslc_shader_free; + ret->uninit = glslc_uninit; + + pthread_mutex_lock(&glslc_mutex); + if (!glslc_refcount++) { + if (!glslang_initialize_process()) { + av_freep(&ret); + glslc_refcount--; + } + } + pthread_mutex_unlock(&glslc_mutex); + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan_loader.h b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_loader.h new file mode 100644 index 00000000..3f1ee6aa --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_loader.h @@ -0,0 +1,135 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VULKAN_LOADER_H +#define AVUTIL_VULKAN_LOADER_H + +#include "vulkan_functions.h" + +/* Macro to turn a function name into a loader struct */ +#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \ + { \ + req_inst, \ + req_dev, \ + offsetof(FFVulkanFunctions, name), \ + ext_flag, \ + { "vk"#name, "vk"#name"EXT", "vk"#name"KHR" } \ + }, + +static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions, + int nb_extensions) +{ + static const struct ExtensionMap { + const char *name; + FFVulkanExtensions flag; + } extension_map[] = { + { VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY }, + { VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS }, + { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY }, + { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM }, + { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY }, + { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS }, +#ifdef _WIN32 + { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY }, + { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM }, +#endif + }; + + FFVulkanExtensions mask = 0x0; + + for (int i = 0; i < nb_extensions; i++) { + for (int j = 0; j < FF_ARRAY_ELEMS(extension_map); j++) { + if (!strcmp(extensions[i], extension_map[j].name)) { + mask |= extension_map[j].flag; + continue; + } + } + } + + return mask; +} + +/** + * Function loader. + * Vulkan function from scratch loading happens in 3 stages - the first one + * is before any initialization has happened, and you have neither an instance + * structure nor a device structure. At this stage, you can only get the bare + * minimals to initialize an instance. + * The second stage is when you have an instance. At this stage, you can + * initialize a VkDevice, and have an idea of what extensions each device + * supports. + * Finally, in the third stage, you can proceed and load all core functions, + * plus you can be sure that any extensions you've enabled during device + * initialization will be available. + */ +static inline int ff_vk_load_functions(AVHWDeviceContext *ctx, + FFVulkanFunctions *vk, + uint64_t extensions_mask, + int has_inst, int has_dev) +{ + AVVulkanDeviceContext *hwctx = ctx->hwctx; + + static const struct FunctionLoadInfo { + int req_inst; + int req_dev; + size_t struct_offset; + FFVulkanExtensions ext_flag; + const char *names[3]; + } vk_load_info[] = { + FN_LIST(PFN_LOAD_INFO) +#ifdef _WIN32 + FN_LIST_WIN32(PFN_LOAD_INFO) +#endif + }; + + for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) { + const struct FunctionLoadInfo *load = &vk_load_info[i]; + PFN_vkVoidFunction fn; + + if (load->req_dev && !has_dev) + continue; + if (load->req_inst && !has_inst) + continue; + + for (int j = 0; j < FF_ARRAY_ELEMS(load->names); j++) { + const char *name = load->names[j]; + + if (load->req_dev) + fn = vk->GetDeviceProcAddr(hwctx->act_dev, name); + else if (load->req_inst) + fn = hwctx->get_proc_addr(hwctx->inst, name); + else + fn = hwctx->get_proc_addr(NULL, name); + + if (fn) + break; + } + + if (!fn && ((extensions_mask &~ FF_VK_EXT_NO_FLAG) & load->ext_flag)) { + av_log(ctx, AV_LOG_ERROR, "Loader error, function \"%s\" indicated " + "as supported, but got NULL function pointer!\n", load->names[0]); + return AVERROR_EXTERNAL; + } + + *(PFN_vkVoidFunction *)((uint8_t *)vk + load->struct_offset) = fn; + } + + return 0; +} + +#endif /* AVUTIL_VULKAN_LOADER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/vulkan_shaderc.c b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_shaderc.c new file mode 100644 index 00000000..bd40edf1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/vulkan_shaderc.c @@ -0,0 +1,122 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "mem.h" + +static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, + FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, + void **opaque) +{ + int loglevel, err, warn, ret; + const char *status, *message; + shaderc_compilation_result_t res; + static const char *shdc_result[] = { + [shaderc_compilation_status_success] = "success", + [shaderc_compilation_status_invalid_stage] = "invalid stage", + [shaderc_compilation_status_compilation_error] = "error", + [shaderc_compilation_status_internal_error] = "internal error", + [shaderc_compilation_status_null_result_object] = "no result", + [shaderc_compilation_status_invalid_assembly] = "invalid assembly", + }; + static const shaderc_shader_kind shdc_kind[] = { + [VK_SHADER_STAGE_VERTEX_BIT] = shaderc_glsl_vertex_shader, + [VK_SHADER_STAGE_FRAGMENT_BIT] = shaderc_glsl_fragment_shader, + [VK_SHADER_STAGE_COMPUTE_BIT] = shaderc_glsl_compute_shader, + }; + + shaderc_compile_options_t opts = shaderc_compile_options_initialize(); + if (!opts) + return AVERROR(ENOMEM); + + shaderc_compile_options_set_target_env(opts, shaderc_target_env_vulkan, + shaderc_env_version_vulkan_1_2); + shaderc_compile_options_set_target_spirv(opts, shaderc_spirv_version_1_5); + shaderc_compile_options_set_optimization_level(opts, + shaderc_optimization_level_performance); + + res = shaderc_compile_into_spv((shaderc_compiler_t)ctx->priv, + shd->src.str, strlen(shd->src.str), + shdc_kind[shd->shader.stage], + shd->name, entrypoint, opts); + shaderc_compile_options_release(opts); + + ret = shaderc_result_get_compilation_status(res); + err = shaderc_result_get_num_errors(res); + warn = shaderc_result_get_num_warnings(res); + message = shaderc_result_get_error_message(res); + + loglevel = err ? AV_LOG_ERROR : warn ? AV_LOG_WARNING : AV_LOG_VERBOSE; + + ff_vk_print_shader(avctx, shd, loglevel); + if (message && (err || warn)) + av_log(avctx, loglevel, "%s\n", message); + status = ret < FF_ARRAY_ELEMS(shdc_result) ? shdc_result[ret] : "unknown"; + av_log(avctx, loglevel, "shaderc compile status '%s' (%d errors, %d warnings)\n", + status, err, warn); + + if (err > 0) + return AVERROR(EINVAL); + + *data = (uint8_t *)shaderc_result_get_bytes(res); + *size = shaderc_result_get_length(res); + *opaque = res; + + return 0; +} + +static void shdc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) +{ + if (!opaque || !*opaque) + return; + + shaderc_result_release((shaderc_compilation_result_t)*opaque); + *opaque = NULL; +} + +static void shdc_uninit(FFVkSPIRVCompiler **ctx) +{ + FFVkSPIRVCompiler *s; + + if (!ctx || !*ctx) + return; + + s = *ctx; + + shaderc_compiler_release((shaderc_compiler_t)s->priv); + av_freep(ctx); +} + +static FFVkSPIRVCompiler *ff_vk_shaderc_init(void) +{ + FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->compile_shader = shdc_shader_compile; + ret->free_shader = shdc_shader_free; + ret->uninit = shdc_uninit; + + ret->priv = (void *)shaderc_compiler_initialize(); + if (!ret->priv) + av_freep(&ret); + + return ret; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/wchar_filename.h b/arm/raspi/third_party/ffmpeg/libavutil/wchar_filename.h new file mode 100644 index 00000000..9a04a069 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/wchar_filename.h @@ -0,0 +1,278 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_WCHAR_FILENAME_H +#define AVUTIL_WCHAR_FILENAME_H + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include +#include "mem.h" + +av_warn_unused_result +static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w) +{ + int num_chars; + num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0); + if (num_chars <= 0) { + *filename_w = NULL; + return 0; + } + *filename_w = (wchar_t *)av_calloc(num_chars, sizeof(wchar_t)); + if (!*filename_w) { + errno = ENOMEM; + return -1; + } + MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars); + return 0; +} + +av_warn_unused_result +static inline int wchartocp(unsigned int code_page, const wchar_t *filename_w, + char **filename) +{ + DWORD flags = code_page == CP_UTF8 ? WC_ERR_INVALID_CHARS : 0; + int num_chars = WideCharToMultiByte(code_page, flags, filename_w, -1, + NULL, 0, NULL, NULL); + if (num_chars <= 0) { + *filename = NULL; + return 0; + } + *filename = (char*)av_malloc_array(num_chars, sizeof *filename); + if (!*filename) { + errno = ENOMEM; + return -1; + } + WideCharToMultiByte(code_page, flags, filename_w, -1, + *filename, num_chars, NULL, NULL); + return 0; +} + +av_warn_unused_result +static inline int wchartoutf8(const wchar_t *filename_w, char **filename) +{ + return wchartocp(CP_UTF8, filename_w, filename); +} + +av_warn_unused_result +static inline int wchartoansi(const wchar_t *filename_w, char **filename) +{ + return wchartocp(CP_ACP, filename_w, filename); +} + +av_warn_unused_result +static inline int utf8toansi(const char *filename_utf8, char **filename) +{ + wchar_t *filename_w = NULL; + int ret = -1; + if (utf8towchar(filename_utf8, &filename_w)) + return -1; + + if (!filename_w) { + *filename = NULL; + return 0; + } + + ret = wchartoansi(filename_w, filename); + av_free(filename_w); + return ret; +} + +/** + * Checks for extended path prefixes for which normalization needs to be skipped. + * see .NET6: PathInternal.IsExtended() + * https://github.com/dotnet/runtime/blob/9260c249140ef90b4299d0fe1aa3037e25228518/src/libraries/Common/src/System/IO/PathInternal.Windows.cs#L165 + */ +static inline int path_is_extended(const wchar_t *path) +{ + if (path[0] == L'\\' && (path[1] == L'\\' || path[1] == L'?') && path[2] == L'?' && path[3] == L'\\') + return 1; + + return 0; +} + +/** + * Checks for a device path prefix. + * see .NET6: PathInternal.IsDevice() + * we don't check forward slashes and extended paths (as already done) + * https://github.com/dotnet/runtime/blob/9260c249140ef90b4299d0fe1aa3037e25228518/src/libraries/Common/src/System/IO/PathInternal.Windows.cs#L132 + */ +static inline int path_is_device_path(const wchar_t *path) +{ + if (path[0] == L'\\' && path[1] == L'\\' && path[2] == L'.' && path[3] == L'\\') + return 1; + + return 0; +} + +/** + * Performs path normalization by calling GetFullPathNameW(). + * see .NET6: PathHelper.GetFullPathName() + * https://github.com/dotnet/runtime/blob/2a99e18eedabcf1add064c099da59d9301ce45e0/src/libraries/System.Private.CoreLib/src/System/IO/PathHelper.Windows.cs#L70 + */ +static inline int get_full_path_name(wchar_t **ppath_w) +{ + int num_chars; + wchar_t *temp_w; + + num_chars = GetFullPathNameW(*ppath_w, 0, NULL, NULL); + if (num_chars <= 0) { + errno = EINVAL; + return -1; + } + + temp_w = (wchar_t *)av_calloc(num_chars, sizeof(wchar_t)); + if (!temp_w) { + errno = ENOMEM; + return -1; + } + + num_chars = GetFullPathNameW(*ppath_w, num_chars, temp_w, NULL); + if (num_chars <= 0) { + av_free(temp_w); + errno = EINVAL; + return -1; + } + + av_freep(ppath_w); + *ppath_w = temp_w; + + return 0; +} + +/** + * Normalizes a Windows file or folder path. + * Expansion of short paths (with 8.3 path components) is currently omitted + * as it is not required for accessing long paths. + * see .NET6: PathHelper.Normalize() + * https://github.com/dotnet/runtime/blob/2a99e18eedabcf1add064c099da59d9301ce45e0/src/libraries/System.Private.CoreLib/src/System/IO/PathHelper.Windows.cs#L25 + */ +static inline int path_normalize(wchar_t **ppath_w) +{ + int ret; + + if ((ret = get_full_path_name(ppath_w)) < 0) + return ret; + + /* What .NET does at this point is to call PathHelper.TryExpandShortFileName() + * in case the path contains a '~' character. + * We don't need to do this as we don't need to normalize the file name + * for presentation, and the extended path prefix works with 8.3 path + * components as well + */ + return 0; +} + +/** + * Adds an extended path or UNC prefix to longs paths or paths ending + * with a space or a dot. (' ' or '.'). + * This function expects that the path has been normalized before by + * calling path_normalize() and it doesn't check whether the path is + * actually long (> MAX_PATH). + * see .NET6: PathInternal.EnsureExtendedPrefix() + * https://github.com/dotnet/runtime/blob/9260c249140ef90b4299d0fe1aa3037e25228518/src/libraries/Common/src/System/IO/PathInternal.Windows.cs#L107 + */ +static inline int add_extended_prefix(wchar_t **ppath_w) +{ + const wchar_t *unc_prefix = L"\\\\?\\UNC\\"; + const wchar_t *extended_path_prefix = L"\\\\?\\"; + const wchar_t *path_w = *ppath_w; + const size_t len = wcslen(path_w); + wchar_t *temp_w; + + /* We're skipping the check IsPartiallyQualified() because + * we expect to have called GetFullPathNameW() already. */ + if (len < 2 || path_is_extended(*ppath_w) || path_is_device_path(*ppath_w)) { + return 0; + } + + if (path_w[0] == L'\\' && path_w[1] == L'\\') { + /* unc_prefix length is 8 plus 1 for terminating zeros, + * we subtract 2 for the leading '\\' of the original path */ + temp_w = (wchar_t *)av_calloc(len - 2 + 8 + 1, sizeof(wchar_t)); + if (!temp_w) { + errno = ENOMEM; + return -1; + } + wcscpy(temp_w, unc_prefix); + wcscat(temp_w, path_w + 2); + } else { + // The length of extended_path_prefix is 4 plus 1 for terminating zeros + temp_w = (wchar_t *)av_calloc(len + 4 + 1, sizeof(wchar_t)); + if (!temp_w) { + errno = ENOMEM; + return -1; + } + wcscpy(temp_w, extended_path_prefix); + wcscat(temp_w, path_w); + } + + av_freep(ppath_w); + *ppath_w = temp_w; + + return 0; +} + +/** + * Converts a file or folder path to wchar_t for use with Windows file + * APIs. Paths with extended path prefix (either '\\?\' or \??\') are + * left unchanged. + * All other paths are normalized and converted to absolute paths. + * Longs paths (>= MAX_PATH) are prefixed with the extended path or extended + * UNC path prefix. + * see .NET6: Path.GetFullPath() and Path.GetFullPathInternal() + * https://github.com/dotnet/runtime/blob/2a99e18eedabcf1add064c099da59d9301ce45e0/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs#L126 + */ +static inline int get_extended_win32_path(const char *path, wchar_t **ppath_w) +{ + int ret; + size_t len; + + if ((ret = utf8towchar(path, ppath_w)) < 0) + return ret; + + if (path_is_extended(*ppath_w)) { + /* Paths prefixed with '\\?\' or \??\' are considered normalized by definition. + * Windows doesn't normalize those paths and neither should we. + */ + return 0; + } + + if ((ret = path_normalize(ppath_w)) < 0) { + av_freep(ppath_w); + return ret; + } + + /* see .NET6: PathInternal.EnsureExtendedPrefixIfNeeded() + * https://github.com/dotnet/runtime/blob/9260c249140ef90b4299d0fe1aa3037e25228518/src/libraries/Common/src/System/IO/PathInternal.Windows.cs#L92 + */ + len = wcslen(*ppath_w); + if (len >= MAX_PATH) { + if ((ret = add_extended_prefix(ppath_w)) < 0) { + av_freep(ppath_w); + return ret; + } + } + + return 0; +} + +#endif + +#endif /* AVUTIL_WCHAR_FILENAME_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/Makefile b/arm/raspi/third_party/ffmpeg/libavutil/x86/Makefile new file mode 100644 index 00000000..d66839e3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/Makefile @@ -0,0 +1,21 @@ +OBJS += x86/cpu.o \ + x86/fixed_dsp_init.o \ + x86/float_dsp_init.o \ + x86/imgutils_init.o \ + x86/lls_init.o \ + +OBJS-$(HAVE_X86ASM) += x86/tx_float_init.o \ + +OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils_init.o \ + +EMMS_OBJS_$(HAVE_MMX_INLINE)_$(HAVE_MMX_EXTERNAL)_$(HAVE_MM_EMPTY) = x86/emms.o + +X86ASM-OBJS += x86/cpuid.o \ + $(EMMS_OBJS__yes_) \ + x86/fixed_dsp.o \ + x86/float_dsp.o \ + x86/imgutils.o \ + x86/lls.o \ + x86/tx_float.o \ + +X86ASM-OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils.o \ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/asm.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/asm.h new file mode 100644 index 00000000..9bff42d6 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/asm.h @@ -0,0 +1,154 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_ASM_H +#define AVUTIL_X86_ASM_H + +#include +#include "config.h" + +typedef struct xmm_reg { uint64_t a, b; } xmm_reg; +typedef struct ymm_reg { uint64_t a, b, c, d; } ymm_reg; + +#if ARCH_X86_64 +# define FF_OPSIZE "q" +# define FF_REG_a "rax" +# define FF_REG_b "rbx" +# define FF_REG_c "rcx" +# define FF_REG_d "rdx" +# define FF_REG_D "rdi" +# define FF_REG_S "rsi" +# define FF_PTR_SIZE "8" +typedef int64_t x86_reg; + +/* FF_REG_SP is defined in Solaris sys headers, so use FF_REG_sp */ +# define FF_REG_sp "rsp" +# define FF_REG_BP "rbp" +# define FF_REGBP rbp +# define FF_REGa rax +# define FF_REGb rbx +# define FF_REGc rcx +# define FF_REGd rdx +# define FF_REGSP rsp + +#elif ARCH_X86_32 + +# define FF_OPSIZE "l" +# define FF_REG_a "eax" +# define FF_REG_b "ebx" +# define FF_REG_c "ecx" +# define FF_REG_d "edx" +# define FF_REG_D "edi" +# define FF_REG_S "esi" +# define FF_PTR_SIZE "4" +typedef int32_t x86_reg; + +# define FF_REG_sp "esp" +# define FF_REG_BP "ebp" +# define FF_REGBP ebp +# define FF_REGa eax +# define FF_REGb ebx +# define FF_REGc ecx +# define FF_REGd edx +# define FF_REGSP esp +#else +typedef int x86_reg; +#endif + +#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE)) +#define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE)) + +#if ARCH_X86_64 && defined(PIC) +# define BROKEN_RELOCATIONS 1 +#endif + +/* + * If gcc is not set to support sse (-msse) it will not accept xmm registers + * in the clobber list for inline asm. XMM_CLOBBERS takes a list of xmm + * registers to be marked as clobbered and evaluates to nothing if they are + * not supported, or to the list itself if they are supported. Since a clobber + * list may not be empty, XMM_CLOBBERS_ONLY should be used if the xmm + * registers are the only in the clobber list. + * For example a list with "eax" and "xmm0" as clobbers should become: + * : XMM_CLOBBERS("xmm0",) "eax" + * and a list with only "xmm0" should become: + * XMM_CLOBBERS_ONLY("xmm0") + */ +#if HAVE_XMM_CLOBBERS +# define XMM_CLOBBERS(...) __VA_ARGS__ +# define XMM_CLOBBERS_ONLY(...) : __VA_ARGS__ +#else +# define XMM_CLOBBERS(...) +# define XMM_CLOBBERS_ONLY(...) +#endif + +/* Use to export labels from asm. */ +#define LABEL_MANGLE(a) EXTERN_PREFIX #a + +// Use rip-relative addressing if compiling PIC code on x86-64. +#if ARCH_X86_64 && defined(PIC) +# define LOCAL_MANGLE(a) #a "(%%rip)" +#else +# define LOCAL_MANGLE(a) #a +#endif + +#if HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS +# define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a) +# define NAMED_CONSTRAINTS_ADD(...) +# define NAMED_CONSTRAINTS(...) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) +# define NAMED_CONSTRAINTS_ARRAY(...) +#else + /* When direct symbol references are used in code passed to a compiler that does not support them + * then these references need to be converted to named asm constraints instead. + * Instead of returning a direct symbol MANGLE now returns a named constraint for that specific symbol. + * In order for this to work there must also be a corresponding entry in the asm-interface. To add this + * entry use the macro NAMED_CONSTRAINTS() and pass in a list of each symbol reference used in the + * corresponding block of code. (e.g. NAMED_CONSTRAINTS(var1,var2,var3) where var1 is the first symbol etc. ). + * If there are already existing constraints then use NAMED_CONSTRAINTS_ADD to add to the existing constraint list. + */ +# define MANGLE(a) "%["#a"]" + // Intel/MSVC does not correctly expand va-args so we need a rather ugly hack in order to get it to work +# define FE_0(P,X) P(X) +# define FE_1(P,X,X1) P(X), FE_0(P,X1) +# define FE_2(P,X,X1,X2) P(X), FE_1(P,X1,X2) +# define FE_3(P,X,X1,X2,X3) P(X), FE_2(P,X1,X2,X3) +# define FE_4(P,X,X1,X2,X3,X4) P(X), FE_3(P,X1,X2,X3,X4) +# define FE_5(P,X,X1,X2,X3,X4,X5) P(X), FE_4(P,X1,X2,X3,X4,X5) +# define FE_6(P,X,X1,X2,X3,X4,X5,X6) P(X), FE_5(P,X1,X2,X3,X4,X5,X6) +# define FE_7(P,X,X1,X2,X3,X4,X5,X6,X7) P(X), FE_6(P,X1,X2,X3,X4,X5,X6,X7) +# define FE_8(P,X,X1,X2,X3,X4,X5,X6,X7,X8) P(X), FE_7(P,X1,X2,X3,X4,X5,X6,X7,X8) +# define FE_9(P,X,X1,X2,X3,X4,X5,X6,X7,X8,X9) P(X), FE_8(P,X1,X2,X3,X4,X5,X6,X7,X8,X9) +# define GET_FE_IMPL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME +# define GET_FE(A) GET_FE_IMPL A +# define GET_FE_GLUE(x, y) x y +# define FOR_EACH_VA(P,...) GET_FE_GLUE(GET_FE((__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)), (P,__VA_ARGS__)) +# define NAME_CONSTRAINT(x) [x] "m"(x) + // Parameters are a list of each symbol reference required +# define NAMED_CONSTRAINTS_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same but without comma for when there are no previously defined constraints +# define NAMED_CONSTRAINTS(...) FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same as above NAMED_CONSTRAINTS except used for passing arrays/pointers instead of normal variables +# define NAME_CONSTRAINT_ARRAY(x) [x] "m"(*x) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +# define NAMED_CONSTRAINTS_ARRAY(...) FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +#endif + +#endif /* AVUTIL_X86_ASM_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_cpu.c new file mode 100644 index 00000000..3adbdc6f --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_cpu.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "cpu.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_float_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_float_dsp_init.c new file mode 100644 index 00000000..2982badd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_float_dsp_init.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "float_dsp_init.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_tx_float_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_tx_float_init.c new file mode 100644 index 00000000..2963b864 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/autorename_libavutil_x86_tx_float_init.c @@ -0,0 +1,2 @@ +// File automatically generated. See crbug.com/495833. +#include "tx_float_init.c" diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/bswap.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/bswap.h new file mode 100644 index 00000000..b2f18b6c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/bswap.h @@ -0,0 +1,88 @@ +/* + * 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 + * byte swapping routines + */ + +#ifndef AVUTIL_X86_BSWAP_H +#define AVUTIL_X86_BSWAP_H + +#include +#if defined(_MSC_VER) +#include +#include +#endif +#include "config.h" +#include "libavutil/attributes.h" + +#if defined(_MSC_VER) + +#define av_bswap16 av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + return _rotr16(x, 8); +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return _byteswap_ulong(x); +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return _byteswap_uint64(x); +} +#endif + + +#elif HAVE_INLINE_ASM + +#if AV_GCC_VERSION_AT_MOST(4,0) +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + __asm__("rorw $8, %w0" : "+r"(x)); + return x; +} +#endif /* AV_GCC_VERSION_AT_MOST(4,0) */ + +#if AV_GCC_VERSION_AT_MOST(4,4) || defined(__INTEL_COMPILER) +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__("bswap %0" : "+r" (x)); + return x; +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + __asm__("bswap %0": "=r" (x) : "0" (x)); + return x; +} +#endif +#endif /* AV_GCC_VERSION_AT_MOST(4,4) */ + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVUTIL_X86_BSWAP_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.c new file mode 100644 index 00000000..d6cd4fab --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.c @@ -0,0 +1,284 @@ +/* + * CPU detection code, extracted from mmx.h + * (c)1997-99 by H. Dietz and R. Fisher + * Converted to C and improved by Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#if HAVE_X86ASM + +#define cpuid(index, eax, ebx, ecx, edx) \ + ff_cpu_cpuid(index, &eax, &ebx, &ecx, &edx) + +#define xgetbv(index, eax, edx) \ + ff_cpu_xgetbv(index, &eax, &edx) + +#elif HAVE_INLINE_ASM + +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */ +#define cpuid(index, eax, ebx, ecx, edx) \ + __asm__ volatile ( \ + "mov %%"FF_REG_b", %%"FF_REG_S" \n\t" \ + "cpuid \n\t" \ + "xchg %%"FF_REG_b", %%"FF_REG_S \ + : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \ + : "0" (index), "2"(0)) + +#define xgetbv(index, eax, edx) \ + __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index)) + +#define get_eflags(x) \ + __asm__ volatile ("pushfl \n" \ + "pop %0 \n" \ + : "=r"(x)) + +#define set_eflags(x) \ + __asm__ volatile ("push %0 \n" \ + "popfl \n" \ + :: "r"(x)) + +#endif /* HAVE_INLINE_ASM */ + +#if ARCH_X86_64 + +#define cpuid_test() 1 + +#elif HAVE_X86ASM + +#define cpuid_test ff_cpu_cpuid_test + +#elif HAVE_INLINE_ASM + +static int cpuid_test(void) +{ + x86_reg a, c; + + /* Check if CPUID is supported by attempting to toggle the ID bit in + * the EFLAGS register. */ + get_eflags(a); + set_eflags(a ^ 0x200000); + get_eflags(c); + + return a != c; +} +#endif + +/* Function to test if multimedia instructions are supported... */ +int ff_get_cpu_flags_x86(void) +{ + int rval = 0; + +#ifdef cpuid + + int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0; + int family = 0, model = 0; + union { int i[3]; char c[12]; } vendor; + int xcr0_lo = 0, xcr0_hi = 0; + + if (!cpuid_test()) + return 0; /* CPUID not supported */ + + cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]); + + if (max_std_level >= 1) { + cpuid(1, eax, ebx, ecx, std_caps); + family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); + model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0); + if (std_caps & (1 << 15)) + rval |= AV_CPU_FLAG_CMOV; + if (std_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_MMXEXT; +#if HAVE_SSE + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_SSE; + if (std_caps & (1 << 26)) + rval |= AV_CPU_FLAG_SSE2; + if (ecx & 1) + rval |= AV_CPU_FLAG_SSE3; + if (ecx & 0x00000200 ) + rval |= AV_CPU_FLAG_SSSE3; + if (ecx & 0x00080000 ) + rval |= AV_CPU_FLAG_SSE4; + if (ecx & 0x00100000 ) + rval |= AV_CPU_FLAG_SSE42; + if (ecx & 0x02000000 ) + rval |= AV_CPU_FLAG_AESNI; +#if HAVE_AVX + /* Check OXSAVE and AVX bits */ + if ((ecx & 0x18000000) == 0x18000000) { + /* Check for OS support */ + xgetbv(0, xcr0_lo, xcr0_hi); + if ((xcr0_lo & 0x6) == 0x6) { + rval |= AV_CPU_FLAG_AVX; + if (ecx & 0x00001000) + rval |= AV_CPU_FLAG_FMA3; + } + } +#endif /* HAVE_AVX */ +#endif /* HAVE_SSE */ + } + if (max_std_level >= 7) { + cpuid(7, eax, ebx, ecx, edx); +#if HAVE_AVX2 + if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020)) + rval |= AV_CPU_FLAG_AVX2; +#if HAVE_AVX512 /* F, CD, BW, DQ, VL */ + if ((xcr0_lo & 0xe0) == 0xe0) { /* OPMASK/ZMM state */ + if ((rval & AV_CPU_FLAG_AVX2) && (ebx & 0xd0030000) == 0xd0030000) { + rval |= AV_CPU_FLAG_AVX512; +#if HAVE_AVX512ICL + if ((ebx & 0xd0200000) == 0xd0200000 && (ecx & 0x5f42) == 0x5f42) + rval |= AV_CPU_FLAG_AVX512ICL; +#endif /* HAVE_AVX512ICL */ + } + } +#endif /* HAVE_AVX512 */ +#endif /* HAVE_AVX2 */ + /* BMI1/2 don't need OS support */ + if (ebx & 0x00000008) { + rval |= AV_CPU_FLAG_BMI1; + if (ebx & 0x00000100) + rval |= AV_CPU_FLAG_BMI2; + } + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if (max_ext_level >= 0x80000001) { + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + if (ext_caps & (1U << 31)) + rval |= AV_CPU_FLAG_3DNOW; + if (ext_caps & (1 << 30)) + rval |= AV_CPU_FLAG_3DNOWEXT; + if (ext_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (ext_caps & (1 << 22)) + rval |= AV_CPU_FLAG_MMXEXT; + + if (!strncmp(vendor.c, "AuthenticAMD", 12)) { + /* Allow for selectively disabling SSE2 functions on AMD processors + with SSE2 support but not SSE4a. This includes Athlon64, some + Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster + than SSE2 often enough to utilize this special-case flag. + AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case + so that SSE2 is used unless explicitly disabled by checking + AV_CPU_FLAG_SSE2SLOW. */ + if (rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040)) + rval |= AV_CPU_FLAG_SSE2SLOW; + + /* Similar to the above but for AVX functions on AMD processors. + This is necessary only for functions using YMM registers on Bulldozer + and Jaguar based CPUs as they lack 256-bit execution units. SSE/AVX + functions using XMM registers are always faster on them. + AV_CPU_FLAG_AVX and AV_CPU_FLAG_AVXSLOW are both set so that AVX is + used unless explicitly disabled by checking AV_CPU_FLAG_AVXSLOW. */ + if ((family == 0x15 || family == 0x16) && (rval & AV_CPU_FLAG_AVX)) + rval |= AV_CPU_FLAG_AVXSLOW; + + /* Zen 3 and earlier have slow gather */ + if ((family <= 0x19) && (rval & AV_CPU_FLAG_AVX2)) + rval |= AV_CPU_FLAG_SLOW_GATHER; + } + + /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be + * used unless the OS has AVX support. */ + if (rval & AV_CPU_FLAG_AVX) { + if (ecx & 0x00000800) + rval |= AV_CPU_FLAG_XOP; + if (ecx & 0x00010000) + rval |= AV_CPU_FLAG_FMA4; + } + } + + if (!strncmp(vendor.c, "GenuineIntel", 12)) { + if (family == 6 && (model == 9 || model == 13 || model == 14)) { + /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and + * 6/14 (core1 "yonah") theoretically support sse2, but it's + * usually slower than mmx, so let's just pretend they don't. + * AV_CPU_FLAG_SSE2 is disabled and AV_CPU_FLAG_SSE2SLOW is + * enabled so that SSE2 is not used unless explicitly enabled + * by checking AV_CPU_FLAG_SSE2SLOW. The same situation + * applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */ + if (rval & AV_CPU_FLAG_SSE2) + rval ^= AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE2; + if (rval & AV_CPU_FLAG_SSE3) + rval ^= AV_CPU_FLAG_SSE3SLOW | AV_CPU_FLAG_SSE3; + } + /* The Atom processor has SSSE3 support, which is useful in many cases, + * but sometimes the SSSE3 version is slower than the SSE2 equivalent + * on the Atom, but is generally faster on other processors supporting + * SSSE3. This flag allows for selectively disabling certain SSSE3 + * functions on the Atom. */ + if (family == 6 && model == 28) + rval |= AV_CPU_FLAG_ATOM; + + /* Conroe has a slow shuffle unit. Check the model number to ensure not + * to include crippled low-end Penryns and Nehalems that lack SSE4. */ + if ((rval & AV_CPU_FLAG_SSSE3) && !(rval & AV_CPU_FLAG_SSE4) && + family == 6 && model < 23) + rval |= AV_CPU_FLAG_SSSE3SLOW; + + /* Haswell has slow gather */ + if ((rval & AV_CPU_FLAG_AVX2) && family == 6 && model < 70) + rval |= AV_CPU_FLAG_SLOW_GATHER; + } + +#endif /* cpuid */ + + return rval; +} + +size_t ff_get_cpu_max_align_x86(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_AVX512) + return 64; + if (flags & (AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_AVXSLOW)) + return 32; + if (flags & (AV_CPU_FLAG_AESNI | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_ATOM | + AV_CPU_FLAG_SSSE3SLOW | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSE2SLOW)) + return 16; + + return 8; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.h new file mode 100644 index 00000000..40a1eef0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpu.h @@ -0,0 +1,114 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_CPU_H +#define AVUTIL_X86_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define AV_CPU_FLAG_AMD3DNOW AV_CPU_FLAG_3DNOW +#define AV_CPU_FLAG_AMD3DNOWEXT AV_CPU_FLAG_3DNOWEXT + +#define X86_AMD3DNOW(flags) CPUEXT(flags, AMD3DNOW) +#define X86_AMD3DNOWEXT(flags) CPUEXT(flags, AMD3DNOWEXT) +#define X86_MMX(flags) CPUEXT(flags, MMX) +#define X86_MMXEXT(flags) CPUEXT(flags, MMXEXT) +#define X86_SSE(flags) CPUEXT(flags, SSE) +#define X86_SSE2(flags) CPUEXT(flags, SSE2) +#define X86_SSE2_FAST(flags) CPUEXT_FAST(flags, SSE2) +#define X86_SSE2_SLOW(flags) CPUEXT_SLOW(flags, SSE2) +#define X86_SSE3(flags) CPUEXT(flags, SSE3) +#define X86_SSE3_FAST(flags) CPUEXT_FAST(flags, SSE3) +#define X86_SSE3_SLOW(flags) CPUEXT_SLOW(flags, SSE3) +#define X86_SSSE3(flags) CPUEXT(flags, SSSE3) +#define X86_SSSE3_FAST(flags) CPUEXT_FAST(flags, SSSE3) +#define X86_SSSE3_SLOW(flags) CPUEXT_SLOW(flags, SSSE3) +#define X86_SSE4(flags) CPUEXT(flags, SSE4) +#define X86_SSE42(flags) CPUEXT(flags, SSE42) +#define X86_AVX(flags) CPUEXT(flags, AVX) +#define X86_AVX_FAST(flags) CPUEXT_FAST(flags, AVX) +#define X86_AVX_SLOW(flags) CPUEXT_SLOW(flags, AVX) +#define X86_XOP(flags) CPUEXT(flags, XOP) +#define X86_FMA3(flags) CPUEXT(flags, FMA3) +#define X86_FMA4(flags) CPUEXT(flags, FMA4) +#define X86_AVX2(flags) CPUEXT(flags, AVX2) +#define X86_AESNI(flags) CPUEXT(flags, AESNI) +#define X86_AVX512(flags) CPUEXT(flags, AVX512) + +#define EXTERNAL_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW) +#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT) +#define EXTERNAL_MMX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMX) +#define EXTERNAL_MMXEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMXEXT) +#define EXTERNAL_SSE(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE) +#define EXTERNAL_SSE2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSE4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE4) +#define EXTERNAL_SSE42(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE42) +#define EXTERNAL_AVX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, AVX) +#define EXTERNAL_XOP(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, XOP) +#define EXTERNAL_FMA3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA3) +#define EXTERNAL_FMA3_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA3_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA4) +#define EXTERNAL_AVX2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX2) +#define EXTERNAL_AVX2_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AVX2_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AESNI(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AESNI) +#define EXTERNAL_AVX512(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX512) +#define EXTERNAL_AVX512ICL(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX512ICL) + +#define INLINE_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW) +#define INLINE_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT) +#define INLINE_MMX(flags) CPUEXT_SUFFIX(flags, _INLINE, MMX) +#define INLINE_MMXEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, MMXEXT) +#define INLINE_SSE(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE) +#define INLINE_SSE2(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE2) +#define INLINE_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE2) +#define INLINE_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE2) +#define INLINE_SSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE3) +#define INLINE_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE3) +#define INLINE_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE3) +#define INLINE_SSSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSSE3) +#define INLINE_SSE4(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE4) +#define INLINE_SSE42(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE42) +#define INLINE_AVX(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX) +#define INLINE_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, AVX) +#define INLINE_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, AVX) +#define INLINE_XOP(flags) CPUEXT_SUFFIX(flags, _INLINE, XOP) +#define INLINE_FMA3(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA3) +#define INLINE_FMA4(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA4) +#define INLINE_AVX2(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX2) +#define INLINE_AESNI(flags) CPUEXT_SUFFIX(flags, _INLINE, AESNI) + +void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx); +void ff_cpu_xgetbv(int op, int *eax, int *edx); +int ff_cpu_cpuid_test(void); + +#endif /* AVUTIL_X86_CPU_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/cpuid.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpuid.asm new file mode 100644 index 00000000..766f77fc --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/cpuid.asm @@ -0,0 +1,91 @@ +;***************************************************************************** +;* Copyright (C) 2005-2010 x264 project +;* +;* Authors: Loren Merritt +;* Fiona Glaser +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_cpuid, 5,7 + push rbx + push r4 + push r3 + push r2 + push r1 + mov eax, r0d + xor ecx, ecx + cpuid + pop r4 + mov [r4], eax + pop r4 + mov [r4], ebx + pop r4 + mov [r4], ecx + pop r4 + mov [r4], edx + pop rbx + RET + +;----------------------------------------------------------------------------- +; void ff_cpu_xgetbv(int op, int *eax, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_xgetbv, 3,7 + push r2 + push r1 + mov ecx, r0d + xgetbv + pop r4 + mov [r4], eax + pop r4 + mov [r4], edx + RET + +%if ARCH_X86_64 == 0 +;----------------------------------------------------------------------------- +; int ff_cpu_cpuid_test(void) +; return 0 if unsupported +;----------------------------------------------------------------------------- +cglobal cpu_cpuid_test + pushfd + push ebx + push ebp + push esi + push edi + pushfd + pop eax + mov ebx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ebx + pop edi + pop esi + pop ebp + pop ebx + popfd + ret +%endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.asm new file mode 100644 index 00000000..df84f222 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.asm @@ -0,0 +1,30 @@ +;***************************************************************************** +;* Copyright (C) 2013 Martin Storsjo +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void avpriv_emms_asm(void) +;----------------------------------------------------------------------------- +cvisible emms_asm, 0, 0 + emms + RET diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.h new file mode 100644 index 00000000..8ceec110 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/emms.h @@ -0,0 +1,58 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_EMMS_H +#define AVUTIL_X86_EMMS_H + +#include "config.h" +#include "libavutil/attributes.h" + +void avpriv_emms_asm(void); + +#if HAVE_MMX_INLINE +#ifndef __MMX__ +#include "libavutil/cpu.h" +#endif + +# define emms_c emms_c +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + * Note, *alloc() and *free() also use float code in some libc implementations + * thus this also applies to them or any function using them. + */ +static av_always_inline void emms_c(void) +{ +/* Some inlined functions may also use mmx instructions regardless of + * runtime cpuflags. With that in mind, we unconditionally empty the + * mmx state if the target cpu chosen at configure time supports it. + */ +#if !defined(__MMX__) + if(av_get_cpu_flags() & AV_CPU_FLAG_MMX) +#endif + __asm__ volatile ("emms" ::: "memory"); +} +#elif HAVE_MMX && HAVE_MM_EMPTY +# include +# define emms_c _mm_empty +#elif HAVE_MMX_EXTERNAL +# define emms_c avpriv_emms_asm +#endif /* HAVE_MMX_INLINE */ + +#endif /* AVUTIL_X86_EMMS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp.asm new file mode 100644 index 00000000..2f411850 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp.asm @@ -0,0 +1,48 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2016 James Almer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_butterflies_fixed(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal butterflies_fixed, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq + +align 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + mova m2, m0 + paddd m0, m1 + psubd m2, m1 + mova [src0q + lenq], m0 + mova [src1q + lenq], m2 + add lenq, mmsize + jl .loop + RET diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp_init.c new file mode 100644 index 00000000..d3f4b2e3 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/fixed_dsp_init.c @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/fixed_dsp.h" +#include "cpu.h" + +void ff_butterflies_fixed_sse2(int *av_restrict src0, int *av_restrict src1, int len); + +av_cold void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->butterflies_fixed = ff_butterflies_fixed_sse2; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp.asm new file mode 100644 index 00000000..e84ba525 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp.asm @@ -0,0 +1,588 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2006 Loren Merritt +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 +pd_reverse: dd 7, 6, 5, 4, 3, 2, 1, 0 + +SECTION .text + +;----------------------------------------------------------------------------- +; void vector_fmul(float *dst, const float *src0, const float *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL 0 +cglobal vector_fmul, 4,4,2, dst, src0, src1, len + lea lenq, [lend*4 - 64] +ALIGN 16 +.loop: +%assign a 0 +%rep 32/mmsize + mova m0, [src0q + lenq + (a+0)*mmsize] + mova m1, [src0q + lenq + (a+1)*mmsize] + mulps m0, m0, [src1q + lenq + (a+0)*mmsize] + mulps m1, m1, [src1q + lenq + (a+1)*mmsize] + mova [dstq + lenq + (a+0)*mmsize], m0 + mova [dstq + lenq + (a+1)*mmsize], m1 +%assign a a+2 +%endrep + + sub lenq, 64 + jge .loop + RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL +%endif + +;----------------------------------------------------------------------------- +; void vector_dmul(double *dst, const double *src0, const double *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_DMUL 0 +cglobal vector_dmul, 4,4,4, dst, src0, src1, len + lea lend, [lenq*8 - mmsize*4] +ALIGN 16 +.loop: + movaps m0, [src0q + lenq + 0*mmsize] + movaps m1, [src0q + lenq + 1*mmsize] + movaps m2, [src0q + lenq + 2*mmsize] + movaps m3, [src0q + lenq + 3*mmsize] + mulpd m0, m0, [src1q + lenq + 0*mmsize] + mulpd m1, m1, [src1q + lenq + 1*mmsize] + mulpd m2, m2, [src1q + lenq + 2*mmsize] + mulpd m3, m3, [src1q + lenq + 3*mmsize] + movaps [dstq + lenq + 0*mmsize], m0 + movaps [dstq + lenq + 1*mmsize], m1 + movaps [dstq + lenq + 2*mmsize], m2 + movaps [dstq + lenq + 3*mmsize], m3 + + sub lenq, mmsize*4 + jge .loop + RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMAC_SCALAR 0 +%if UNIX64 +cglobal vector_fmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_fmac_scalar, 4,4,5, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSS m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + shufps xm0, xm0, 0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*4-64] +.loop: +%if cpuflag(fma3) + mova m1, [dstq+lenq] + mova m2, [dstq+lenq+1*mmsize] + fmaddps m1, m0, [srcq+lenq], m1 + fmaddps m2, m0, [srcq+lenq+1*mmsize], m2 +%else ; cpuflag + mulps m1, m0, [srcq+lenq] + mulps m2, m0, [srcq+lenq+1*mmsize] +%if mmsize < 32 + mulps m3, m0, [srcq+lenq+2*mmsize] + mulps m4, m0, [srcq+lenq+3*mmsize] +%endif ; mmsize + addps m1, m1, [dstq+lenq] + addps m2, m2, [dstq+lenq+1*mmsize] +%if mmsize < 32 + addps m3, m3, [dstq+lenq+2*mmsize] + addps m4, m4, [dstq+lenq+3*mmsize] +%endif ; mmsize +%endif ; cpuflag + mova [dstq+lenq], m1 + mova [dstq+lenq+1*mmsize], m2 +%if mmsize < 32 + mova [dstq+lenq+2*mmsize], m3 + mova [dstq+lenq+3*mmsize], m4 +%endif ; mmsize + sub lenq, 64 + jge .loop + RET +%endmacro + +INIT_XMM sse +VECTOR_FMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmul_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMUL_SCALAR 0 +%if UNIX64 +cglobal vector_fmul_scalar, 3,3,2, dst, src, len +%else +cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + movss m0, mulm +%elif WIN64 + SWAP 0, 2 +%endif + shufps m0, m0, 0 + lea lenq, [lend*4-mmsize] +.loop: + mova m1, [srcq+lenq] + mulps m1, m0 + mova [dstq+lenq], m1 + sub lenq, mmsize + jge .loop + RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_SCALAR + +;------------------------------------------------------------------------------ +; void ff_vector_dmac_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMAC_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmac_scalar, 2,4,5, dst, src, mul, len, lenaddr + mov lenq, lenaddrm + VBROADCASTSD m0, mulm +%else +%if UNIX64 +cglobal vector_dmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_dmac_scalar, 4,4,5, dst, src, mul, len + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-mmsize*4] +.loop: +%if cpuflag(fma3) + movaps m1, [dstq+lenq] + movaps m2, [dstq+lenq+1*mmsize] + movaps m3, [dstq+lenq+2*mmsize] + movaps m4, [dstq+lenq+3*mmsize] + fmaddpd m1, m0, [srcq+lenq], m1 + fmaddpd m2, m0, [srcq+lenq+1*mmsize], m2 + fmaddpd m3, m0, [srcq+lenq+2*mmsize], m3 + fmaddpd m4, m0, [srcq+lenq+3*mmsize], m4 +%else ; cpuflag + mulpd m1, m0, [srcq+lenq] + mulpd m2, m0, [srcq+lenq+1*mmsize] + mulpd m3, m0, [srcq+lenq+2*mmsize] + mulpd m4, m0, [srcq+lenq+3*mmsize] + addpd m1, m1, [dstq+lenq] + addpd m2, m2, [dstq+lenq+1*mmsize] + addpd m3, m3, [dstq+lenq+2*mmsize] + addpd m4, m4, [dstq+lenq+3*mmsize] +%endif ; cpuflag + movaps [dstq+lenq], m1 + movaps [dstq+lenq+1*mmsize], m2 + movaps [dstq+lenq+2*mmsize], m3 + movaps [dstq+lenq+3*mmsize], m4 + sub lenq, mmsize*4 + jge .loop + RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_DMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_dmul_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMUL_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr + mov lenq, lenaddrm +%elif UNIX64 +cglobal vector_dmul_scalar, 3,3,3, dst, src, len +%else +cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSD m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 ym0, ym0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-2*mmsize] +.loop: + mulpd m1, m0, [srcq+lenq ] + mulpd m2, m0, [srcq+lenq+mmsize] + movaps [dstq+lenq ], m1 + movaps [dstq+lenq+mmsize], m2 + sub lenq, 2*mmsize + jge .loop + RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL_SCALAR +%endif + +;----------------------------------------------------------------------------- +; vector_fmul_window(float *dst, const float *src0, +; const float *src1, const float *win, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse +cglobal vector_fmul_window, 5, 6, 6, dst, src0, src1, win, len, len1 + shl lend, 2 + lea len1q, [lenq - mmsize] + add src0q, lenq + add dstq, lenq + add winq, lenq + neg lenq +.loop: + mova m0, [winq + lenq] + mova m4, [src0q + lenq] + mova m1, [winq + len1q] + mova m5, [src1q + len1q] + shufps m1, m1, 0x1b + shufps m5, m5, 0x1b + mova m2, m0 + mova m3, m1 + mulps m2, m4 + mulps m3, m5 + mulps m1, m4 + mulps m0, m5 + addps m2, m3 + subps m1, m0 + shufps m2, m2, 0x1b + mova [dstq + lenq], m1 + mova [dstq + len1q], m2 + sub len1q, mmsize + add lenq, mmsize + jl .loop + RET + +;----------------------------------------------------------------------------- +; vector_fmul_add(float *dst, const float *src0, const float *src1, +; const float *src2, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_ADD 0 +cglobal vector_fmul_add, 5,5,4, dst, src0, src1, src2, len + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src0q + lenq + mmsize] +%if cpuflag(fma3) + mova m2, [src2q + lenq] + mova m3, [src2q + lenq + mmsize] + fmaddps m0, m0, [src1q + lenq], m2 + fmaddps m1, m1, [src1q + lenq + mmsize], m3 +%else + mulps m0, m0, [src1q + lenq] + mulps m1, m1, [src1q + lenq + mmsize] + addps m0, m0, [src2q + lenq] + addps m1, m1, [src2q + lenq + mmsize] +%endif + mova [dstq + lenq], m0 + mova [dstq + lenq + mmsize], m1 + + sub lenq, 2*mmsize + jge .loop + RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_ADD +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_ADD +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMUL_ADD +%endif + +;----------------------------------------------------------------------------- +; void vector_fmul_reverse(float *dst, const float *src0, const float *src1, +; int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_REVERSE 0 +cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len +%if cpuflag(avx2) + movaps m2, [pd_reverse] +%endif + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: +%if cpuflag(avx2) + vpermps m0, m2, [src1q] + vpermps m1, m2, [src1q+mmsize] +%elif cpuflag(avx) + vmovaps xmm0, [src1q + 16] + vinsertf128 m0, m0, [src1q], 1 + vshufps m0, m0, m0, q0123 + vmovaps xmm1, [src1q + mmsize + 16] + vinsertf128 m1, m1, [src1q + mmsize], 1 + vshufps m1, m1, m1, q0123 +%else + mova m0, [src1q] + mova m1, [src1q + mmsize] + shufps m0, m0, q0123 + shufps m1, m1, q0123 +%endif + mulps m0, m0, [src0q + lenq + mmsize] + mulps m1, m1, [src0q + lenq] + movaps [dstq + lenq + mmsize], m0 + movaps [dstq + lenq], m1 + add src1q, 2*mmsize + sub lenq, 2*mmsize + jge .loop + RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_REVERSE +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_REVERSE +%endif +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +VECTOR_FMUL_REVERSE +%endif + +; float scalarproduct_float_sse(const float *v1, const float *v2, int len) +INIT_XMM sse +cglobal scalarproduct_float, 3,3,2, v1, v2, offset + shl offsetd, 2 + add v1q, offsetq + add v2q, offsetq + neg offsetq + xorps xmm0, xmm0 +.loop: + movaps xmm1, [v1q+offsetq] + mulps xmm1, [v2q+offsetq] + addps xmm0, xmm1 + add offsetq, 16 + js .loop + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xmm0 + fld dword r0m +%endif + RET + +INIT_YMM fma3 +cglobal scalarproduct_float, 3,5,8, v1, v2, size, len, offset + xor offsetq, offsetq + xorps m0, m0, m0 + shl sized, 2 + mov lenq, sizeq + cmp lenq, 32 + jl .l16 + cmp lenq, 64 + jl .l32 + xorps m1, m1, m1 + cmp lenq, 128 + jl .l64 + and lenq, ~127 + xorps m2, m2, m2 + xorps m3, m3, m3 +.loop128: + movups m4, [v1q+offsetq] + movups m5, [v1q+offsetq + 32] + movups m6, [v1q+offsetq + 64] + movups m7, [v1q+offsetq + 96] + fmaddps m0, m4, [v2q+offsetq ], m0 + fmaddps m1, m5, [v2q+offsetq + 32], m1 + fmaddps m2, m6, [v2q+offsetq + 64], m2 + fmaddps m3, m7, [v2q+offsetq + 96], m3 + add offsetq, 128 + cmp offsetq, lenq + jl .loop128 + addps m0, m0, m2 + addps m1, m1, m3 + mov lenq, sizeq + and lenq, 127 + cmp lenq, 64 + jge .l64 + addps m0, m0, m1 + cmp lenq, 32 + jge .l32 + vextractf128 xmm2, m0, 1 + addps xmm0, xmm2 + cmp lenq, 16 + jge .l16 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xm0 + fld dword r0m +%endif + RET +.l64: + and lenq, ~63 + add lenq, offsetq +.loop64: + movups m4, [v1q+offsetq] + movups m5, [v1q+offsetq + 32] + fmaddps m0, m4, [v2q+offsetq], m0 + fmaddps m1, m5, [v2q+offsetq + 32], m1 + add offsetq, 64 + cmp offsetq, lenq + jl .loop64 + addps m0, m0, m1 + mov lenq, sizeq + and lenq, 63 + cmp lenq, 32 + jge .l32 + vextractf128 xmm2, m0, 1 + addps xmm0, xmm2 + cmp lenq, 16 + jge .l16 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xm0 + fld dword r0m +%endif + RET +.l32: + and lenq, ~31 + add lenq, offsetq +.loop32: + movups m4, [v1q+offsetq] + fmaddps m0, m4, [v2q+offsetq], m0 + add offsetq, 32 + cmp offsetq, lenq + jl .loop32 + vextractf128 xmm2, m0, 1 + addps xmm0, xmm2 + mov lenq, sizeq + and lenq, 31 + cmp lenq, 16 + jge .l16 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xm0 + fld dword r0m +%endif + RET +.l16: + and lenq, ~15 + add lenq, offsetq +.loop16: + movaps xmm1, [v1q+offsetq] + mulps xmm1, [v2q+offsetq] + addps xmm0, xmm1 + add offsetq, 16 + cmp offsetq, lenq + jl .loop16 + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xm0 + fld dword r0m +%endif + RET + +;----------------------------------------------------------------------------- +; void ff_butterflies_float(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse +cglobal butterflies_float, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + subps m2, m0, m1 + addps m0, m0, m1 + mova [src1q + lenq], m2 + mova [src0q + lenq], m0 + add lenq, mmsize + jl .loop + RET diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp_init.c new file mode 100644 index 00000000..ad6b5062 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/float_dsp_init.c @@ -0,0 +1,118 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "asm.h" + +void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1, + int len); +void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_dmul_sse2(double *dst, const double *src0, const double *src1, + int len); +void ff_vector_dmul_avx(double *dst, const double *src0, const double *src1, + int len); + +void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_fma3(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul, + int len); + +void ff_vector_dmac_scalar_sse2(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_avx(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_fma3(double *dst, const double *src, double mul, + int len); + +void ff_vector_dmul_scalar_sse2(double *dst, const double *src, + double mul, int len); +void ff_vector_dmul_scalar_avx(double *dst, const double *src, + double mul, int len); + +void ff_vector_fmul_window_sse(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_fma3(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_sse(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx2(float *dst, const float *src0, + const float *src1, int len); + +float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); +float ff_scalarproduct_float_fma3(const float *v1, const float *v2, int order); + +void ff_butterflies_float_sse(float *av_restrict src0, float *av_restrict src1, int len); + +av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_sse; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; + fdsp->vector_fmul_window = ff_vector_fmul_window_sse; + fdsp->vector_fmul_add = ff_vector_fmul_add_sse; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse; + fdsp->scalarproduct_float = ff_scalarproduct_float_sse; + fdsp->butterflies_float = ff_butterflies_float_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->vector_dmul = ff_vector_dmul_sse2; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_sse2; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_avx; + fdsp->vector_dmul = ff_vector_dmul_avx; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_avx; + fdsp->vector_fmul_add = ff_vector_fmul_add_avx; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx2; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_fma3; + fdsp->vector_fmul_add = ff_vector_fmul_add_fma3; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_fma3; + fdsp->scalarproduct_float = ff_scalarproduct_float_fma3; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils.asm new file mode 100644 index 00000000..3cca56cd --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils.asm @@ -0,0 +1,53 @@ +;***************************************************************************** +;* Copyright 2016 Anton Khirnov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, bw, height, rowpos + add dstq, bwq + add srcq, bwq + neg bwq + +.row_start: + mov rowposq, bwq + +.loop: + movntdqa m0, [srcq + rowposq + 0 * mmsize] + movntdqa m1, [srcq + rowposq + 1 * mmsize] + movntdqa m2, [srcq + rowposq + 2 * mmsize] + movntdqa m3, [srcq + rowposq + 3 * mmsize] + + mova [dstq + rowposq + 0 * mmsize], m0 + mova [dstq + rowposq + 1 * mmsize], m1 + mova [dstq + rowposq + 2 * mmsize], m2 + mova [dstq + rowposq + 3 * mmsize], m3 + + add rowposq, 4 * mmsize + jnz .loop + + add srcq, src_linesizeq + add dstq, dst_linesizeq + dec heightd + jnz .row_start + + RET diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils_init.c new file mode 100644 index 00000000..91a16cf5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/imgutils_init.c @@ -0,0 +1,48 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/cpu.h" +#include "libavutil/error.h" +#include "libavutil/imgutils_internal.h" +#include "libavutil/macros.h" + +#include "cpu.h" + +void ff_image_copy_plane_uc_from_sse4(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int cpu_flags = av_get_cpu_flags(); + ptrdiff_t bw_aligned = FFALIGN(bytewidth, 64); + + if (EXTERNAL_SSE4(cpu_flags) && + bw_aligned <= dst_linesize && bw_aligned <= src_linesize) + ff_image_copy_plane_uc_from_sse4(dst, dst_linesize, src, src_linesize, + bw_aligned, height); + else + return AVERROR(ENOSYS); + + return 0; +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/intmath.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/intmath.h new file mode 100644 index 00000000..8a6b5ae2 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/intmath.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2015 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_INTMATH_H +#define AVUTIL_X86_INTMATH_H + +#include +#include +#if HAVE_FAST_CLZ +#if defined(_MSC_VER) +#include +#elif defined(__INTEL_COMPILER) +#include +#endif +#endif +#include "config.h" + +#if HAVE_FAST_CLZ +#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER>=1216)) || defined(_MSC_VER) +# if defined(__INTEL_COMPILER) +# define ff_log2(x) (_bit_scan_reverse((x)|1)) +# else +# define ff_log2 ff_log2_x86 +static av_always_inline av_const int ff_log2_x86(unsigned int v) +{ + unsigned long n; + _BitScanReverse(&n, v|1); + return n; +} +# endif +# define ff_log2_16bit av_log2 + +#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1700) && \ + (defined(__BMI__) || !defined(__clang__))) +# define ff_ctz(v) _tzcnt_u32(v) + +# if ARCH_X86_64 +# define ff_ctzll(v) _tzcnt_u64(v) +# else +# define ff_ctzll ff_ctzll_x86 +static av_always_inline av_const int ff_ctzll_x86(long long v) +{ + return ((uint32_t)v == 0) ? _tzcnt_u32((uint32_t)(v >> 32)) + 32 : _tzcnt_u32((uint32_t)v); +} +# endif +#endif /* _MSC_VER */ + +#endif /* __INTEL_COMPILER */ + +#endif /* HAVE_FAST_CLZ */ + +#if defined(__GNUC__) + +/* Our generic version of av_popcount is faster than GCC's built-in on + * CPUs that don't support the popcnt instruction. + */ +#if defined(__POPCNT__) + #define av_popcount __builtin_popcount +#if ARCH_X86_64 + #define av_popcount64 __builtin_popcountll +#endif + +#endif /* __POPCNT__ */ + +#if defined(__BMI2__) + +#if AV_GCC_VERSION_AT_LEAST(5,1) +#define av_mod_uintp2 __builtin_ia32_bzhi_si +#elif HAVE_INLINE_ASM +/* GCC releases before 5.1.0 have a broken bzhi builtin, so for those we + * implement it using inline assembly + */ +#define av_mod_uintp2 av_mod_uintp2_bmi2 +static av_always_inline av_const unsigned av_mod_uintp2_bmi2(unsigned a, unsigned p) +{ + if (av_builtin_constant_p(p)) + return a & ((1 << p) - 1); + else { + unsigned x; + __asm__ ("bzhi %2, %1, %0 \n\t" : "=r"(x) : "rm"(a), "r"(p)); + return x; + } +} +#endif /* AV_GCC_VERSION_AT_LEAST */ + +#endif /* __BMI2__ */ + +#if defined(__SSE2__) && !defined(__INTEL_COMPILER) + +#define av_clipd av_clipd_sse2 +static av_always_inline av_const double av_clipd_sse2(double a, double amin, double amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("maxsd %1, %0 \n\t" + "minsd %2, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE2__ */ + +#if defined(__SSE__) && !defined(__INTEL_COMPILER) + +#define av_clipf av_clipf_sse +static av_always_inline av_const float av_clipf_sse(float a, float amin, float amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("maxss %1, %0 \n\t" + "minss %2, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE__ */ + +#if defined(__AVX__) && !defined(__INTEL_COMPILER) + +#undef av_clipd +#define av_clipd av_clipd_avx +static av_always_inline av_const double av_clipd_avx(double a, double amin, double amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("vmaxsd %1, %0, %0 \n\t" + "vminsd %2, %0, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#undef av_clipf +#define av_clipf av_clipf_avx +static av_always_inline av_const float av_clipf_avx(float a, float amin, float amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("vmaxss %1, %0, %0 \n\t" + "vminss %2, %0, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __AVX__ */ + +#endif /* __GNUC__ */ + +#endif /* AVUTIL_X86_INTMATH_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/intreadwrite.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/intreadwrite.h new file mode 100644 index 00000000..40f375b0 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/intreadwrite.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010 Alexander Strange + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_INTREADWRITE_H +#define AVUTIL_X86_INTREADWRITE_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_MMX + +#if !HAVE_FAST_64BIT && defined(__MMX__) + +#define FF_COPY_SWAP_ZERO_USES_MMX + +#define AV_COPY64 AV_COPY64 +static av_always_inline void AV_COPY64(void *d, const void *s) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + : "m" (*(const uint64_t*)s) + : "mm0"); +} + +#define AV_SWAP64 AV_SWAP64 +static av_always_inline void AV_SWAP64(void *a, void *b) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %0, %%mm1 \n\t" + "movq %%mm0, %0 \n\t" + "movq %%mm1, %1 \n\t" + : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b) + ::"mm0", "mm1"); +} + +#define AV_ZERO64 AV_ZERO64 +static av_always_inline void AV_ZERO64(void *d) +{ + __asm__("pxor %%mm0, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + :: "mm0"); +} + +#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */ + +#ifdef __SSE__ + +#define AV_COPY128 AV_COPY128 +static av_always_inline void AV_COPY128(void *d, const void *s) +{ + struct v {uint64_t v[2];}; + + __asm__("movaps %1, %%xmm0 \n\t" + "movaps %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + : "m" (*(const struct v*)s) + : "xmm0"); +} + +#endif /* __SSE__ */ + +#ifdef __SSE2__ + +#define AV_ZERO128 AV_ZERO128 +static av_always_inline void AV_ZERO128(void *d) +{ + struct v {uint64_t v[2];}; + + __asm__("pxor %%xmm0, %%xmm0 \n\t" + "movdqa %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + :: "xmm0"); +} + +#endif /* __SSE2__ */ + +#endif /* HAVE_MMX */ + +#endif /* AVUTIL_X86_INTREADWRITE_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/lls.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/lls.asm new file mode 100644 index 00000000..e8141e6c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/lls.asm @@ -0,0 +1,290 @@ +;****************************************************************************** +;* linear least squares model +;* +;* Copyright (c) 2013 Loren Merritt +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +%define MAX_VARS 32 +%define MAX_VARS_ALIGN (MAX_VARS+4) +%define COVAR_STRIDE MAX_VARS_ALIGN*8 +%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE] + +struc LLSModel + .covariance: resq MAX_VARS_ALIGN*MAX_VARS_ALIGN + .coeff: resq MAX_VARS*MAX_VARS + .variance: resq MAX_VARS + .indep_count: resd 1 +endstruc + +%macro ADDPD_MEM 2 +%if cpuflag(avx) + vaddpd %2, %2, %1 +%else + addpd %2, %1 +%endif + mova %1, %2 +%endmacro + +INIT_XMM sse2 +%define movdqa movaps +cglobal update_lls, 2,5,8, ctx, var, i, j, covar2 + %define covarq ctxq + mov id, [ctxq + LLSModel.indep_count] + lea varq, [varq + iq*8] + neg iq + mov covar2q, covarq +.loopi: + ; Compute all 3 pairwise products of a 2x2 block that lies on the diagonal + mova m1, [varq + iq*8] + mova m3, [varq + iq*8 + 16] + pshufd m4, m1, q1010 + pshufd m5, m1, q3232 + pshufd m6, m3, q1010 + pshufd m7, m3, q3232 + mulpd m0, m1, m4 + mulpd m1, m1, m5 + lea covarq, [covar2q + 16] + ADDPD_MEM COVAR(-2,0), m0 + ADDPD_MEM COVAR(-2,1), m1 + lea jq, [iq + 2] + cmp jd, -2 + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(0,0), m0 + ADDPD_MEM COVAR(0,1), m1 + ADDPD_MEM COVAR(0,2), m2 + ADDPD_MEM COVAR(0,3), m3 + mova m3, [varq + jq*8 + 16] + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(2,0), m0 + ADDPD_MEM COVAR(2,1), m1 + ADDPD_MEM COVAR(2,2), m2 + ADDPD_MEM COVAR(2,3), m3 + mova m3, [varq + jq*8 + 32] + add covarq, 32 + add jq, 4 + cmp jd, -2 + jle .loop4x4 +.skip4x4: + test jd, jd + jg .skip2x4 + mulpd m4, m3 + mulpd m5, m3 + mulpd m6, m3 + mulpd m7, m3 + ADDPD_MEM COVAR(0,0), m4 + ADDPD_MEM COVAR(0,1), m5 + ADDPD_MEM COVAR(0,2), m6 + ADDPD_MEM COVAR(0,3), m7 +.skip2x4: + add iq, 4 + add covar2q, 4*COVAR_STRIDE+32 + cmp id, -2 + jle .loopi + test id, id + jg .ret + mov jq, iq + %define covarq covar2q +.loop2x1: + movsd m0, [varq + iq*8] + movlhps m0, m0 + mulpd m0, [varq + jq*8] + ADDPD_MEM COVAR(0,0), m0 + inc iq + add covarq, COVAR_STRIDE + test id, id + jle .loop2x1 +.ret: + RET + +%macro UPDATE_LLS 0 +cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2 + %define covarq ctxq + mov countd, [ctxq + LLSModel.indep_count] + lea count2d, [countq-2] + xor id, id +.loopi: + ; Compute all 10 pairwise products of a 4x4 block that lies on the diagonal + mova ymm1, [varq + iq*8] + vbroadcastsd ymm4, [varq + iq*8] + vbroadcastsd ymm5, [varq + iq*8 + 8] + vbroadcastsd ymm6, [varq + iq*8 + 16] + vbroadcastsd ymm7, [varq + iq*8 + 24] + vextractf128 xmm3, ymm1, 1 +%if cpuflag(fma3) + mova ymm0, COVAR(iq ,0) + mova xmm2, COVAR(iq+2,2) + fmaddpd ymm0, ymm1, ymm4, ymm0 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd ymm1, ymm5, ymm1, COVAR(iq ,1) + fmaddpd xmm3, xmm7, xmm3, COVAR(iq+2,3) + mova COVAR(iq ,0), ymm0 + mova COVAR(iq ,1), ymm1 + mova COVAR(iq+2,2), xmm2 + mova COVAR(iq+2,3), xmm3 +%else + vmulpd ymm0, ymm1, ymm4 + vmulpd ymm1, ymm1, ymm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(iq ,0), ymm0 + ADDPD_MEM COVAR(iq ,1), ymm1 + ADDPD_MEM COVAR(iq+2,2), xmm2 + ADDPD_MEM COVAR(iq+2,3), xmm3 +%endif ; cpuflag(fma3) + lea jd, [iq + 4] + cmp jd, count2d + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mova ymm3, [varq + jq*8] +%if cpuflag(fma3) + mova ymm0, COVAR(jq, 0) + mova ymm1, COVAR(jq, 1) + mova ymm2, COVAR(jq, 2) + fmaddpd ymm0, ymm3, ymm4, ymm0 + fmaddpd ymm1, ymm3, ymm5, ymm1 + fmaddpd ymm2, ymm3, ymm6, ymm2 + fmaddpd ymm3, ymm7, ymm3, COVAR(jq,3) + mova COVAR(jq, 0), ymm0 + mova COVAR(jq, 1), ymm1 + mova COVAR(jq, 2), ymm2 + mova COVAR(jq, 3), ymm3 +%else + vmulpd ymm0, ymm3, ymm4 + vmulpd ymm1, ymm3, ymm5 + vmulpd ymm2, ymm3, ymm6 + vmulpd ymm3, ymm3, ymm7 + ADDPD_MEM COVAR(jq,0), ymm0 + ADDPD_MEM COVAR(jq,1), ymm1 + ADDPD_MEM COVAR(jq,2), ymm2 + ADDPD_MEM COVAR(jq,3), ymm3 +%endif ; cpuflag(fma3) + add jd, 4 + cmp jd, count2d + jle .loop4x4 +.skip4x4: + cmp jd, countd + jg .skip2x4 + mova xmm3, [varq + jq*8] +%if cpuflag(fma3) + mova xmm0, COVAR(jq, 0) + mova xmm1, COVAR(jq, 1) + mova xmm2, COVAR(jq, 2) + fmaddpd xmm0, xmm3, xmm4, xmm0 + fmaddpd xmm1, xmm3, xmm5, xmm1 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd xmm3, xmm7, xmm3, COVAR(jq,3) + mova COVAR(jq, 0), xmm0 + mova COVAR(jq, 1), xmm1 + mova COVAR(jq, 2), xmm2 + mova COVAR(jq, 3), xmm3 +%else + vmulpd xmm0, xmm3, xmm4 + vmulpd xmm1, xmm3, xmm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(jq,0), xmm0 + ADDPD_MEM COVAR(jq,1), xmm1 + ADDPD_MEM COVAR(jq,2), xmm2 + ADDPD_MEM COVAR(jq,3), xmm3 +%endif ; cpuflag(fma3) +.skip2x4: + add id, 4 + add covarq, 4*COVAR_STRIDE + cmp id, count2d + jle .loopi + cmp id, countd + jg .ret + mov jd, id +.loop2x1: + vmovddup xmm0, [varq + iq*8] +%if cpuflag(fma3) + mova xmm1, [varq + jq*8] + fmaddpd xmm0, xmm1, xmm0, COVAR(jq,0) + mova COVAR(jq,0), xmm0 +%else + vmulpd xmm0, [varq + jq*8] + ADDPD_MEM COVAR(jq,0), xmm0 +%endif ; cpuflag(fma3) + inc id + add covarq, COVAR_STRIDE + cmp id, countd + jle .loop2x1 +.ret: + RET +%endmacro ; UPDATE_LLS + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +UPDATE_LLS +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +UPDATE_LLS +%endif + +INIT_XMM sse2 +cglobal evaluate_lls, 3,4,2, ctx, var, order, i + ; This function is often called on the same buffer as update_lls, but with + ; an offset. They can't both be aligned. + ; Load halves rather than movu to avoid store-forwarding stalls, since the + ; input was initialized immediately prior to this function using scalar math. + %define coefsq ctxq + mov id, orderd + imul orderd, MAX_VARS + lea coefsq, [ctxq + LLSModel.coeff + orderq*8] + movsd m0, [varq] + movhpd m0, [varq + 8] + mulpd m0, [coefsq] + lea coefsq, [coefsq + iq*8] + lea varq, [varq + iq*8] + neg iq + add iq, 2 +.loop: + movsd m1, [varq + iq*8] + movhpd m1, [varq + iq*8 + 8] + mulpd m1, [coefsq + iq*8] + addpd m0, m1 + add iq, 2 + jl .loop + jg .skip1 + movsd m1, [varq + iq*8] + mulsd m1, [coefsq + iq*8] + addpd m0, m1 +.skip1: + movhlps m1, m0 + addsd m0, m1 +%if ARCH_X86_32 + movsd r0m, m0 + fld qword r0m +%endif + RET diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/lls_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/lls_init.c new file mode 100644 index 00000000..c7863769 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/lls_init.c @@ -0,0 +1,46 @@ +/* + * linear least squares model + * + * Copyright (c) 2013 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/lls.h" +#include "libavutil/x86/cpu.h" + +void ff_update_lls_sse2(LLSModel *m, const double *var); +void ff_update_lls_avx(LLSModel *m, const double *var); +void ff_update_lls_fma3(LLSModel *m, const double *var); +double ff_evaluate_lls_sse2(LLSModel *m, const double *var, int order); + +av_cold void ff_init_lls_x86(LLSModel *m) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE2(cpu_flags)) { + m->update_lls = ff_update_lls_sse2; + if (m->indep_count >= 4) + m->evaluate_lls = ff_evaluate_lls_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_avx; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_fma3; + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.asm new file mode 100644 index 00000000..fbe9b459 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.asm @@ -0,0 +1,328 @@ +;****************************************************************************** +;* Pixel utilities SIMD +;* +;* Copyright (C) 2002-2004 Michael Niedermayer +;* Copyright (C) 2014 Clément Bœsch +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_8x8_mmxext(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pixelutils_sad_8x8, 4,4,0, src1, stride1, src2, stride2 + pxor m2, m2 +%rep 4 + mova m0, [src1q] + mova m1, [src1q + stride1q] + psadbw m0, [src2q] + psadbw m1, [src2q + stride2q] + paddw m2, m0 + paddw m2, m1 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] +%endrep + movd eax, m2 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pixelutils_sad_16x16, 4,4,5, src1, stride1, src2, stride2 + movu m4, [src1q] + movu m2, [src2q] + movu m1, [src1q + stride1q] + movu m3, [src2q + stride2q] + psadbw m4, m2 + psadbw m1, m3 + paddw m4, m1 +%rep 7 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] + movu m0, [src1q] + movu m2, [src2q] + movu m1, [src1q + stride1q] + movu m3, [src2q + stride2q] + psadbw m0, m2 + psadbw m1, m3 + paddw m4, m0 + paddw m4, m1 +%endrep + movhlps m0, m4 + paddw m4, m0 + movd eax, m4 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_XMM_16x16 1 +INIT_XMM sse2 +cglobal pixelutils_sad_%1_16x16, 4,4,3, src1, stride1, src2, stride2 + mov%1 m2, [src2q] + psadbw m2, [src1q] + mov%1 m1, [src2q + stride2q] + psadbw m1, [src1q + stride1q] + paddw m2, m1 +%rep 7 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] + mov%1 m0, [src2q] + psadbw m0, [src1q] + mov%1 m1, [src2q + stride2q] + psadbw m1, [src1q + stride1q] + paddw m2, m0 + paddw m2, m1 +%endrep + movhlps m0, m2 + paddw m2, m0 + movd eax, m2 + RET +%endmacro + +SAD_XMM_16x16 a +SAD_XMM_16x16 u + + +%macro PROCESS_SAD_32x4_U 0 + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] +%endmacro + +%macro PROCESS_SAD_32x4 1 + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] +%endmacro + +;----------------------------------------------------------------------------- +; int ff_pixelutils_sad_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pixelutils_sad_32x32, 4,5,5, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 4 +.loop: + PROCESS_SAD_32x4_U + PROCESS_SAD_32x4_U + dec r4d + jnz .loop + + movhlps m1, m0 + paddd m0, m1 + movd eax, m0 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_XMM_32x32 1 +INIT_XMM sse2 +cglobal pixelutils_sad_%1_32x32, 4,5,3, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 4 +.loop: + PROCESS_SAD_32x4 %1 + PROCESS_SAD_32x4 %1 + dec r4d + jnz .loop + + movhlps m1, m0 + paddd m0, m1 + movd eax, m0 + RET +%endmacro + +SAD_XMM_32x32 a +SAD_XMM_32x32 u + +%if HAVE_AVX2_EXTERNAL +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_YMM avx2 +cglobal pixelutils_sad_32x32, 4,7,5, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 32/4 + lea r5, [stride1q * 3] + lea r6, [stride2q * 3] + +.loop: + movu m1, [src1q] ; row 0 of pix0 + movu m2, [src2q] ; row 0 of pix1 + movu m3, [src1q + stride1q] ; row 1 of pix0 + movu m4, [src2q + stride2q] ; row 1 of pix1 + + psadbw m1, m2 + psadbw m3, m4 + paddd m0, m1 + paddd m0, m3 + + movu m1, [src1q + 2 * stride1q] ; row 2 of pix0 + movu m2, [src2q + 2 * stride2q] ; row 2 of pix1 + movu m3, [src1q + r5] ; row 3 of pix0 + movu m4, [src2q + r6] ; row 3 of pix1 + + psadbw m1, m2 + psadbw m3, m4 + paddd m0, m1 + paddd m0, m3 + + lea src2q, [src2q + 4 * stride2q] + lea src1q, [src1q + 4 * stride1q] + + dec r4d + jnz .loop + + vextracti128 xm1, m0, 1 + paddd xm0, xm1 + pshufd xm1, xm0, 2 + paddd xm0, xm1 + movd eax, xm0 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_AVX2_32x32 1 +INIT_YMM avx2 +cglobal pixelutils_sad_%1_32x32, 4,7,3, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 32/4 + lea r5, [stride1q * 3] + lea r6, [stride2q * 3] + +.loop: + mov%1 m1, [src2q] ; row 0 of pix1 + psadbw m1, [src1q] + mov%1 m2, [src2q + stride2q] ; row 1 of pix1 + psadbw m2, [src1q + stride1q] + + paddd m0, m1 + paddd m0, m2 + + mov%1 m1, [src2q + 2 * stride2q] ; row 2 of pix1 + psadbw m1, [src1q + 2 * stride1q] + mov%1 m2, [src2q + r6] ; row 3 of pix1 + psadbw m2, [src1q + r5] + + paddd m0, m1 + paddd m0, m2 + + lea src2q, [src2q + 4 * stride2q] + lea src1q, [src1q + 4 * stride1q] + + dec r4d + jnz .loop + + vextracti128 xm1, m0, 1 + paddd xm0, xm1 + pshufd xm1, xm0, 2 + paddd xm0, xm1 + movd eax, xm0 + RET +%endmacro + +SAD_AVX2_32x32 a +SAD_AVX2_32x32 u +%endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.h new file mode 100644 index 00000000..876cf460 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils.h @@ -0,0 +1,26 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_PIXELUTILS_H +#define AVUTIL_X86_PIXELUTILS_H + +#include "libavutil/pixelutils.h" + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned); + +#endif /* AVUTIL_X86_PIXELUTILS_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils_init.c new file mode 100644 index 00000000..c3c06624 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/pixelutils_init.c @@ -0,0 +1,85 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "pixelutils.h" +#include "cpu.h" + +int ff_pixelutils_sad_8x8_mmxext(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned) +{ + int cpu_flags = av_get_cpu_flags(); + + // The best way to use SSE2 would be to do 2 SADs in parallel, + // but we'd have to modify the pixelutils API to return SIMD functions. + + // It's probably not faster to shuffle data around + // to get two lines of 8 pixels into a single 16byte register, + // so just use the MMX 8x8 version even when SSE2 is available. + if (EXTERNAL_MMXEXT(cpu_flags)) { + sad[2] = ff_pixelutils_sad_8x8_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[3] = ff_pixelutils_sad_16x16_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[3] = ff_pixelutils_sad_u_16x16_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[3] = ff_pixelutils_sad_a_16x16_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_avx2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_avx2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_avx2; break; // src1 aligned, src2 aligned + } + } +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/timer.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/timer.h new file mode 100644 index 00000000..4d1e88de --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/timer.h @@ -0,0 +1,50 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_TIMER_H +#define AVUTIL_X86_TIMER_H + +#include + +#if HAVE_INLINE_ASM + +#define FF_TIMER_UNITS "decicycles" +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint32_t a, d; + __asm__ volatile( +#if ARCH_X86_64 || defined(__SSE2__) + "lfence \n\t" +#endif + "rdtsc \n\t" + : "=a" (a), "=d" (d)); + return ((uint64_t)d << 32) + a; +} + +#elif HAVE_RDTSC + +#include +#define AV_READ_TIME __rdtsc + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_X86_TIMER_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float.asm new file mode 100644 index 00000000..e1533a85 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float.asm @@ -0,0 +1,1936 @@ +;****************************************************************************** +;* Copyright (c) Lynne +;* +;* 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 +;****************************************************************************** + +; Open `doc/transforms.md` to see the code upon which the transforms here were +; based upon and compare. + +; Intra-asm call convention: +; 320 bytes of stack available +; 14 GPRs available (last 4 must not be clobbered) +; Additionally, don't clobber ctx, in, out, stride, len, lut +; All vector regs available + +; TODO: +; carry over registers from smaller transforms to save on ~8 loads/stores +; check if vinsertf could be faster than verpm2f128 for duplication +; even faster FFT8 (current one is very #instructions optimized) +; replace some xors with blends + addsubs? +; replace some shuffles with vblends? +; avx512 split-radix + +%include "libavutil/x86/x86util.asm" + +%define private_prefix ff_tx + +%if ARCH_X86_64 +%define ptr resq +%else +%define ptr resd +%endif + +%assign i 16 +%rep 14 +cextern tab_ %+ i %+ _float ; ff_tab_i_float... +%assign i (i << 1) +%endrep + +cextern tab_53_float + +struc AVTXContext + .len: resd 1 ; Length + .inv resd 1 ; Inverse flag + .map: ptr 1 ; Lookup table(s) + .exp: ptr 1 ; Exponentiation factors + .tmp: ptr 1 ; Temporary data + + .sub: ptr 1 ; Subcontexts + .fn: ptr 4 ; Subcontext functions + .nb_sub: resd 1 ; Subcontext count + + ; Everything else is inaccessible +endstruc + +SECTION_RODATA 32 + +%define POS 0x00000000 +%define NEG 0x80000000 + +%define M_SQRT1_2 0.707106781186547524401 +%define COS16_1 0.92387950420379638671875 +%define COS16_3 0.3826834261417388916015625 + +d8_mult_odd: dd M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, \ + M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2 + +s8_mult_odd: dd 1.0, 1.0, -1.0, 1.0, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2 +s8_perm_even: dd 1, 3, 0, 2, 1, 3, 2, 0 +s8_perm_odd1: dd 3, 3, 1, 1, 1, 1, 3, 3 +s8_perm_odd2: dd 1, 2, 0, 3, 1, 0, 0, 1 + +s16_mult_even: dd 1.0, 1.0, M_SQRT1_2, M_SQRT1_2, 1.0, -1.0, M_SQRT1_2, -M_SQRT1_2 +s16_mult_odd1: dd COS16_1, COS16_1, COS16_3, COS16_3, COS16_1, -COS16_1, COS16_3, -COS16_3 +s16_mult_odd2: dd COS16_3, -COS16_3, COS16_1, -COS16_1, -COS16_3, -COS16_3, -COS16_1, -COS16_1 +s16_perm: dd 0, 1, 2, 3, 1, 0, 3, 2 + +s15_perm: dd 0, 6, 5, 3, 2, 4, 7, 1 + +mask_mmppmmmm: dd NEG, NEG, POS, POS, NEG, NEG, NEG, NEG +mask_mmmmpppm: dd NEG, NEG, NEG, NEG, POS, POS, POS, NEG +mask_ppmpmmpm: dd POS, POS, NEG, POS, NEG, NEG, POS, NEG +mask_mppmmpmp: dd NEG, POS, POS, NEG, NEG, POS, NEG, POS +mask_mpmppmpm: dd NEG, POS, NEG, POS, POS, NEG, POS, NEG +mask_pmmppmmp: dd POS, NEG, NEG, POS, POS, NEG, NEG, POS +mask_pmpmpmpm: times 4 dd POS, NEG + +SECTION .text + +; Load complex values (64 bits) via a lookup table +; %1 - output register +; %2 - GRP of base input memory address +; %3 - GPR of LUT (int32_t indices) address +; %4 - LUT offset +; %5 - temporary GPR (only used if vgather is not used) +; %6 - temporary register (for avx only) +; %7 - temporary register (for avx only, enables vgatherdpd (AVX2) if FMA3 is set) +%macro LOAD64_LUT 5-7 +%if %0 > 6 && cpuflag(avx2) + pcmpeqd %7, %7 ; pcmpeqq has a 0.5 throughput on Zen 3, this has 0.25 + movupd xmm%6, [%3 + %4] ; float mov since vgatherdpd is a float instruction + vgatherdpd %1, [%2 + xmm%6*8], %7 ; must use separate registers for args +%else + mov %5d, [%3 + %4 + 0] + movsd xmm%1, [%2 + %5q*8] +%if sizeof%1 > 16 && %0 > 5 + mov %5d, [%3 + %4 + 8] + movsd xmm%6, [%2 + %5q*8] +%endif + mov %5d, [%3 + %4 + 4] + movhps xmm%1, [%2 + %5q*8] +%if sizeof%1 > 16 && %0 > 5 + mov %5d, [%3 + %4 + 12] + movhps xmm%6, [%2 + %5q*8] + vinsertf128 %1, %1, xmm%6, 1 +%endif +%endif +%endmacro + +; Single 2-point in-place complex FFT (will do 2 transforms at once in AVX mode) +; %1 - coefficients (r0.reim, r1.reim) +; %2 - temporary +%macro FFT2 2 + shufps %2, %1, %1, q3322 + shufps %1, %1, %1, q1100 + + addsubps %1, %1, %2 + + shufps %1, %1, %1, q2031 +%endmacro + +; Single 4-point in-place complex FFT (will do 2 transforms at once in [AVX] mode) +; %1 - even coefficients (r0.reim, r2.reim, r4.reim, r6.reim) +; %2 - odd coefficients (r1.reim, r3.reim, r5.reim, r7.reim) +; %3 - temporary +%macro FFT4 3 + subps %3, %1, %2 ; r1234, [r5678] + addps %1, %1, %2 ; t1234, [t5678] + + shufps %2, %1, %3, q1010 ; t12, r12 + shufps %1, %1, %3, q2332 ; t34, r43 + + subps %3, %2, %1 ; a34, b32 + addps %2, %2, %1 ; a12, b14 + + shufps %1, %2, %3, q1010 ; a1234 even + + shufps %2, %2, %3, q2332 ; b1423 + shufps %2, %2, %2, q1320 ; b1234 odd +%endmacro + +; Single/Dual 8-point in-place complex FFT (will do 2 transforms in [AVX] mode) +; %1 - even coefficients (a0.reim, a2.reim, [b0.reim, b2.reim]) +; %2 - even coefficients (a4.reim, a6.reim, [b4.reim, b6.reim]) +; %3 - odd coefficients (a1.reim, a3.reim, [b1.reim, b3.reim]) +; %4 - odd coefficients (a5.reim, a7.reim, [b5.reim, b7.reim]) +; %5 - temporary +; %6 - temporary +%macro FFT8 6 + addps %5, %1, %3 ; q1-8 + addps %6, %2, %4 ; k1-8 + + subps %1, %1, %3 ; r1-8 + subps %2, %2, %4 ; j1-8 + + shufps %4, %1, %1, q2323 ; r4343 + shufps %3, %5, %6, q3032 ; q34, k14 + + shufps %1, %1, %1, q1010 ; r1212 + shufps %5, %5, %6, q1210 ; q12, k32 + + xorps %4, %4, [mask_pmmppmmp] ; r4343 * pmmp + addps %6, %5, %3 ; s12, g12 + + mulps %2, %2, [d8_mult_odd] ; r8 * d8_mult_odd + subps %5, %5, %3 ; s34, g43 + + addps %3, %1, %4 ; z1234 + unpcklpd %1, %6, %5 ; s1234 + + shufps %4, %2, %2, q2301 ; j2143 + shufps %6, %6, %5, q2332 ; g1234 + + addsubps %2, %2, %4 ; l2143 + shufps %5, %2, %2, q0123 ; l3412 + addsubps %5, %5, %2 ; t1234 + + subps %2, %1, %6 ; h1234 even + subps %4, %3, %5 ; u1234 odd + + addps %1, %1, %6 ; w1234 even + addps %3, %3, %5 ; o1234 odd +%endmacro + +; Single 8-point in-place complex FFT in 20 instructions +; %1 - even coefficients (r0.reim, r2.reim, r4.reim, r6.reim) +; %2 - odd coefficients (r1.reim, r3.reim, r5.reim, r7.reim) +; %3 - temporary +; %4 - temporary +%macro FFT8_AVX 4 + subps %3, %1, %2 ; r1234, r5678 + addps %1, %1, %2 ; q1234, q5678 + + vpermilps %2, %3, [s8_perm_odd1] ; r4422, r6688 + shufps %4, %1, %1, q3322 ; q1122, q5566 + + movsldup %3, %3 ; r1133, r5577 + shufps %1, %1, %1, q1100 ; q3344, q7788 + + addsubps %3, %3, %2 ; z1234, z5678 + addsubps %1, %1, %4 ; s3142, s7586 + + mulps %3, %3, [s8_mult_odd] ; z * s8_mult_odd + vpermilps %1, %1, [s8_perm_even] ; s1234, s5687 ! + + shufps %2, %3, %3, q2332 ; junk, z7887 + xorps %4, %1, [mask_mmmmpppm] ; e1234, e5687 ! + + vpermilps %3, %3, [s8_perm_odd2] ; z2314, z6556 + vperm2f128 %1, %1, %4, 0x03 ; e5687, s1234 + + addsubps %2, %2, %3 ; junk, t5678 + subps %1, %1, %4 ; w1234, w5678 even + + vperm2f128 %2, %2, %2, 0x11 ; t5678, t5678 + vperm2f128 %3, %3, %3, 0x00 ; z2314, z2314 + + xorps %2, %2, [mask_ppmpmmpm] ; t * ppmpmmpm + addps %2, %3, %2 ; u1234, u5678 odd +%endmacro + +; Single 16-point in-place complex FFT +; %1 - even coefficients (r0.reim, r2.reim, r4.reim, r6.reim) +; %2 - even coefficients (r8.reim, r10.reim, r12.reim, r14.reim) +; %3 - odd coefficients (r1.reim, r3.reim, r5.reim, r7.reim) +; %4 - odd coefficients (r9.reim, r11.reim, r13.reim, r15.reim) +; %5, %6 - temporary +; %7, %8 - temporary (optional) +%macro FFT16 6-8 + FFT4 %3, %4, %5 +%if %0 > 7 + FFT8_AVX %1, %2, %6, %7 + movaps %8, [mask_mpmppmpm] + movaps %7, [s16_perm] +%define mask %8 +%define perm %7 +%elif %0 > 6 + FFT8_AVX %1, %2, %6, %7 + movaps %7, [s16_perm] +%define mask [mask_mpmppmpm] +%define perm %7 +%else + FFT8_AVX %1, %2, %6, %5 +%define mask [mask_mpmppmpm] +%define perm [s16_perm] +%endif + xorps %5, %5, %5 ; 0 + + shufps %6, %4, %4, q2301 ; z12.imre, z13.imre... + shufps %5, %5, %3, q2301 ; 0, 0, z8.imre... + + mulps %4, %4, [s16_mult_odd1] ; z.reim * costab + xorps %5, %5, [mask_mppmmpmp] +%if cpuflag(fma3) + fmaddps %6, %6, [s16_mult_odd2], %4 ; s[8..15] + addps %5, %3, %5 ; s[0...7] +%else + mulps %6, %6, [s16_mult_odd2] ; z.imre * costab + + addps %5, %3, %5 ; s[0...7] + addps %6, %4, %6 ; s[8..15] +%endif + mulps %5, %5, [s16_mult_even] ; s[0...7]*costab + + xorps %4, %6, mask ; s[8..15]*mpmppmpm + xorps %3, %5, mask ; s[0...7]*mpmppmpm + + vperm2f128 %4, %4, %4, 0x01 ; s[12..15, 8..11] + vperm2f128 %3, %3, %3, 0x01 ; s[4..7, 0..3] + + addps %6, %6, %4 ; y56, u56, y34, u34 + addps %5, %5, %3 ; w56, x56, w34, x34 + + vpermilps %6, %6, perm ; y56, u56, y43, u43 + vpermilps %5, %5, perm ; w56, x56, w43, x43 + + subps %4, %2, %6 ; odd part 2 + addps %3, %2, %6 ; odd part 1 + + subps %2, %1, %5 ; even part 2 + addps %1, %1, %5 ; even part 1 +%undef mask +%undef perm +%endmacro + +; Single 15-point complex FFT +; Input: +; xm0 must contain in[0,1].reim +; m2 - in[3-6].reim +; m3 - in[7-11].reim +; m4 - in[12-15].reim +; xm5 must contain in[2].reimreim +; +; Output: +; m0, m1, m2 - ACs +; xm14 - out[0] +; xm15 - out[10, 5] +%macro FFT15 0 + shufps xm1, xm0, xm0, q3223 ; in[1].imrereim + shufps xm0, xm0, xm0, q1001 ; in[0].imrereim + + xorps xm1, xm11 + addps xm1, xm0 ; pc[0,1].imre + + shufps xm0, xm1, xm1, q3232 ; pc[1].reimreim + addps xm0, xm5 ; dc[0].reimreim + + mulps xm1, xm9 ; tab[0123]*pc[01] + + shufpd xm6, xm1, xm1, 01b ; pc[1,0].reim + xorps xm1, xm11 + addps xm1, xm1, xm6 + addsubps xm1, xm5, xm1 ; dc[1,2].reim + + subps m7, m2, m3 ; q[0-3].imre + addps m6, m2, m3 ; q[4-7] + shufps m7, m7, m7, q2301 ; q[0-3].reim + + addps m5, m4, m6 ; y[0-3] + + vperm2f128 m14, m9, m9, 0x11 ; tab[23232323] + vbroadcastsd m15, xm9 ; tab[01010101] + + mulps m6, m14 + mulps m7, m15 + + subps m2, m6, m7 ; k[0-3] + addps m3, m6, m7 ; k[4-7] + + shufps m12, m11, m11, q3232 ; ppppmmmm + + addsubps m6, m4, m2 ; k[0-3] + addsubps m7, m4, m3 ; k[4-7] + + ; 15pt from here on + vpermpd m2, m5, q0123 ; y[3-0] + vpermpd m3, m6, q0123 ; k[3-0] + vpermpd m4, m7, q0123 ; k[7-4] + + xorps m5, m12 + xorps m6, m12 + xorps m7, m12 + + addps m2, m5 ; t[0-3] + addps m3, m6 ; t[4-7] + addps m4, m7 ; t[8-11] + + movlhps xm14, xm2 ; out[0] + unpcklpd xm15, xm3, xm4 ; out[10,5] + unpckhpd xm5, xm3, xm4 ; out[10,5] + + addps xm14, xm2 ; out[0] + addps xm15, xm5 ; out[10,5] + addps xm14, xm0 ; out[0] + addps xm15, xm1 ; out[10,5] + + shufps m12, m10, m10, q3232 ; tab5 4 5 4 5 8 9 8 9 + shufps m13, m10, m10, q1010 ; tab5 6 7 6 7 10 11 10 11 + + mulps m5, m2, m12 ; t[0-3] + mulps m6, m3, m12 ; t[4-7] + mulps m7, m4, m12 ; t[8-11] + + mulps m2, m13 ; r[0-3] + mulps m3, m13 ; r[4-7] + mulps m4, m13 ; r[8-11] + + shufps m5, m5, m5, q1032 ; t[1,0,3,2].reim + shufps m6, m6, m6, q1032 ; t[5,4,7,6].reim + shufps m7, m7, m7, q1032 ; t[9,8,11,10].reim + + vperm2f128 m13, m11, m11, 0x01 ; mmmmmmpp + shufps m12, m11, m11, q3232 ; ppppmmmm + + xorps m5, m13 + xorps m6, m13 + xorps m7, m13 + + addps m2, m5 ; r[0,1,2,3] + addps m3, m6 ; r[4,5,6,7] + addps m4, m7 ; r[8,9,10,11] + + shufps m5, m2, m2, q2301 + shufps m6, m3, m3, q2301 + shufps m7, m4, m4, q2301 + + xorps m2, m12 + xorps m3, m12 + xorps m4, m12 + + vpermpd m5, m5, q0123 + vpermpd m6, m6, q0123 + vpermpd m7, m7, q0123 + + addps m5, m2 + addps m6, m3 + addps m7, m4 + + vpermps m5, m8, m5 + vpermps m6, m8, m6 + vpermps m7, m8, m7 + + vbroadcastsd m0, xm0 ; dc[0] + vpermpd m2, m1, q1111 ; dc[2] + vbroadcastsd m1, xm1 ; dc[1] + + addps m0, m5 + addps m1, m6 + addps m2, m7 +%endmacro + +; Cobmines m0...m8 (tx1[even, even, odd, odd], tx2,3[even], tx2,3[odd]) coeffs +; Uses all 16 of registers. +; Output is slightly permuted such that tx2,3's coefficients are interleaved +; on a 2-point basis (look at `doc/transforms.md`) +%macro SPLIT_RADIX_COMBINE 17 +%if %1 && mmsize == 32 + vperm2f128 %14, %6, %7, 0x20 ; m2[0], m2[1], m3[0], m3[1] even + vperm2f128 %16, %9, %8, 0x20 ; m2[0], m2[1], m3[0], m3[1] odd + vperm2f128 %15, %6, %7, 0x31 ; m2[2], m2[3], m3[2], m3[3] even + vperm2f128 %17, %9, %8, 0x31 ; m2[2], m2[3], m3[2], m3[3] odd +%endif + + shufps %12, %10, %10, q2200 ; cos00224466 + shufps %13, %11, %11, q1133 ; wim77553311 + movshdup %10, %10 ; cos11335577 + shufps %11, %11, %11, q0022 ; wim66442200 + +%if %1 && mmsize == 32 + shufps %6, %14, %14, q2301 ; m2[0].imre, m2[1].imre, m2[2].imre, m2[3].imre even + shufps %8, %16, %16, q2301 ; m2[0].imre, m2[1].imre, m2[2].imre, m2[3].imre odd + shufps %7, %15, %15, q2301 ; m3[0].imre, m3[1].imre, m3[2].imre, m3[3].imre even + shufps %9, %17, %17, q2301 ; m3[0].imre, m3[1].imre, m3[2].imre, m3[3].imre odd + + mulps %14, %14, %13 ; m2[0123]reim * wim7531 even + mulps %16, %16, %11 ; m2[0123]reim * wim7531 odd + mulps %15, %15, %13 ; m3[0123]reim * wim7531 even + mulps %17, %17, %11 ; m3[0123]reim * wim7531 odd +%else + mulps %14, %6, %13 ; m2,3[01]reim * wim7531 even + mulps %16, %8, %11 ; m2,3[01]reim * wim7531 odd + mulps %15, %7, %13 ; m2,3[23]reim * wim7531 even + mulps %17, %9, %11 ; m2,3[23]reim * wim7531 odd + ; reorder the multiplies to save movs reg, reg in the %if above + shufps %6, %6, %6, q2301 ; m2[0].imre, m2[1].imre, m3[0].imre, m3[1].imre even + shufps %8, %8, %8, q2301 ; m2[0].imre, m2[1].imre, m3[0].imre, m3[1].imre odd + shufps %7, %7, %7, q2301 ; m2[2].imre, m2[3].imre, m3[2].imre, m3[3].imre even + shufps %9, %9, %9, q2301 ; m2[2].imre, m2[3].imre, m3[2].imre, m3[3].imre odd +%endif + +%if cpuflag(fma3) ; 11 - 5 = 6 instructions saved through FMA! + fmaddsubps %6, %6, %12, %14 ; w[0..8] even + fmaddsubps %8, %8, %10, %16 ; w[0..8] odd + fmsubaddps %7, %7, %12, %15 ; j[0..8] even + fmsubaddps %9, %9, %10, %17 ; j[0..8] odd + movaps %13, [mask_pmpmpmpm] ; "subaddps? pfft, who needs that!" +%else + mulps %6, %6, %12 ; m2,3[01]imre * cos0246 + mulps %8, %8, %10 ; m2,3[01]imre * cos0246 + movaps %13, [mask_pmpmpmpm] ; "subaddps? pfft, who needs that!" + mulps %7, %7, %12 ; m2,3[23]reim * cos0246 + mulps %9, %9, %10 ; m2,3[23]reim * cos0246 + addsubps %6, %6, %14 ; w[0..8] + addsubps %8, %8, %16 ; w[0..8] + xorps %15, %15, %13 ; +-m2,3[23]imre * wim7531 + xorps %17, %17, %13 ; +-m2,3[23]imre * wim7531 + addps %7, %7, %15 ; j[0..8] + addps %9, %9, %17 ; j[0..8] +%endif + + addps %14, %6, %7 ; t10235476 even + addps %16, %8, %9 ; t10235476 odd + subps %15, %6, %7 ; +-r[0..7] even + subps %17, %8, %9 ; +-r[0..7] odd + + shufps %14, %14, %14, q2301 ; t[0..7] even + shufps %16, %16, %16, q2301 ; t[0..7] odd + xorps %15, %15, %13 ; r[0..7] even + xorps %17, %17, %13 ; r[0..7] odd + + subps %6, %2, %14 ; m2,3[01] even + subps %8, %4, %16 ; m2,3[01] odd + subps %7, %3, %15 ; m2,3[23] even + subps %9, %5, %17 ; m2,3[23] odd + + addps %2, %2, %14 ; m0 even + addps %4, %4, %16 ; m0 odd + addps %3, %3, %15 ; m1 even + addps %5, %5, %17 ; m1 odd +%endmacro + +; Same as above, only does one parity at a time, takes 3 temporary registers, +; however, if the twiddles aren't needed after this, the registers they use +; can be used as any of the temporary registers. +%macro SPLIT_RADIX_COMBINE_HALF 10 +%if %1 + shufps %8, %6, %6, q2200 ; cos00224466 + shufps %9, %7, %7, q1133 ; wim77553311 +%else + shufps %8, %6, %6, q3311 ; cos11335577 + shufps %9, %7, %7, q0022 ; wim66442200 +%endif + + mulps %10, %4, %9 ; m2,3[01]reim * wim7531 even + mulps %9, %9, %5 ; m2,3[23]reim * wim7531 even + + shufps %4, %4, %4, q2301 ; m2[0].imre, m2[1].imre, m3[0].imre, m3[1].imre even + shufps %5, %5, %5, q2301 ; m2[2].imre, m2[3].imre, m3[2].imre, m3[3].imre even + +%if cpuflag(fma3) + fmaddsubps %4, %4, %8, %10 ; w[0..8] even + fmsubaddps %5, %5, %8, %9 ; j[0..8] even + movaps %10, [mask_pmpmpmpm] +%else + mulps %4, %4, %8 ; m2,3[01]imre * cos0246 + mulps %5, %5, %8 ; m2,3[23]reim * cos0246 + addsubps %4, %4, %10 ; w[0..8] + movaps %10, [mask_pmpmpmpm] + xorps %9, %9, %10 ; +-m2,3[23]imre * wim7531 + addps %5, %5, %9 ; j[0..8] +%endif + + addps %8, %4, %5 ; t10235476 + subps %9, %4, %5 ; +-r[0..7] + + shufps %8, %8, %8, q2301 ; t[0..7] + xorps %9, %9, %10 ; r[0..7] + + subps %4, %2, %8 ; %3,3[01] + subps %5, %3, %9 ; %3,3[23] + + addps %2, %2, %8 ; m0 + addps %3, %3, %9 ; m1 +%endmacro + +; Same as above, tries REALLY hard to use 2 temporary registers. +%macro SPLIT_RADIX_COMBINE_LITE 9 +%if %1 + shufps %8, %6, %6, q2200 ; cos00224466 + shufps %9, %7, %7, q1133 ; wim77553311 +%else + shufps %8, %6, %6, q3311 ; cos11335577 + shufps %9, %7, %7, q0022 ; wim66442200 +%endif + + mulps %9, %9, %4 ; m2,3[01]reim * wim7531 even + shufps %4, %4, %4, q2301 ; m2[0].imre, m2[1].imre, m3[0].imre, m3[1].imre even + +%if cpuflag(fma3) + fmaddsubps %4, %4, %8, %9 ; w[0..8] even +%else + mulps %4, %4, %8 ; m2,3[01]imre * cos0246 + addsubps %4, %4, %9 ; w[0..8] +%endif + +%if %1 + shufps %9, %7, %7, q1133 ; wim77553311 +%else + shufps %9, %7, %7, q0022 ; wim66442200 +%endif + + mulps %9, %9, %5 ; m2,3[23]reim * wim7531 even + shufps %5, %5, %5, q2301 ; m2[2].imre, m2[3].imre, m3[2].imre, m3[3].imre even +%if cpuflag (fma3) + fmsubaddps %5, %5, %8, %9 ; j[0..8] even +%else + mulps %5, %5, %8 ; m2,3[23]reim * cos0246 + xorps %9, %9, [mask_pmpmpmpm] ; +-m2,3[23]imre * wim7531 + addps %5, %5, %9 ; j[0..8] +%endif + + addps %8, %4, %5 ; t10235476 + subps %9, %4, %5 ; +-r[0..7] + + shufps %8, %8, %8, q2301 ; t[0..7] + xorps %9, %9, [mask_pmpmpmpm] ; r[0..7] + + subps %4, %2, %8 ; %3,3[01] + subps %5, %3, %9 ; %3,3[23] + + addps %2, %2, %8 ; m0 + addps %3, %3, %9 ; m1 +%endmacro + +%macro SPLIT_RADIX_COMBINE_64 0 + SPLIT_RADIX_COMBINE_LITE 1, m0, m1, tx1_e0, tx2_e0, tw_e, tw_o, tmp1, tmp2 + + movaps [outq + 0*mmsize], m0 + movaps [outq + 4*mmsize], m1 + movaps [outq + 8*mmsize], tx1_e0 + movaps [outq + 12*mmsize], tx2_e0 + + SPLIT_RADIX_COMBINE_HALF 0, m2, m3, tx1_o0, tx2_o0, tw_e, tw_o, tmp1, tmp2, m0 + + movaps [outq + 2*mmsize], m2 + movaps [outq + 6*mmsize], m3 + movaps [outq + 10*mmsize], tx1_o0 + movaps [outq + 14*mmsize], tx2_o0 + + movaps tw_e, [tab_64_float + mmsize] + vperm2f128 tw_o, tw_o, [tab_64_float + 64 - 4*7 - mmsize], 0x23 + + movaps m0, [outq + 1*mmsize] + movaps m1, [outq + 3*mmsize] + movaps m2, [outq + 5*mmsize] + movaps m3, [outq + 7*mmsize] + + SPLIT_RADIX_COMBINE 0, m0, m2, m1, m3, tx1_e1, tx2_e1, tx1_o1, tx2_o1, tw_e, tw_o, \ + tmp1, tmp2, tx2_o0, tx1_o0, tx2_e0, tx1_e0 ; temporary registers + + movaps [outq + 1*mmsize], m0 + movaps [outq + 3*mmsize], m1 + movaps [outq + 5*mmsize], m2 + movaps [outq + 7*mmsize], m3 + + movaps [outq + 9*mmsize], tx1_e1 + movaps [outq + 11*mmsize], tx1_o1 + movaps [outq + 13*mmsize], tx2_e1 + movaps [outq + 15*mmsize], tx2_o1 +%endmacro + +; Perform a single even/odd split radix combination with loads and stores +; The _4 indicates this is a quarter of the iterations required to complete a full +; combine loop +; %1 must contain len*2, %2 must contain len*4, %3 must contain len*6 +%macro SPLIT_RADIX_LOAD_COMBINE_4 8 + movaps m8, [rtabq + (%5)*mmsize + %7] + vperm2f128 m9, m9, [itabq - (%5)*mmsize + %8], 0x23 + + movaps m0, [outq + (0 + %4)*mmsize + %6] + movaps m2, [outq + (2 + %4)*mmsize + %6] + movaps m1, [outq + %1 + (0 + %4)*mmsize + %6] + movaps m3, [outq + %1 + (2 + %4)*mmsize + %6] + + movaps m4, [outq + %2 + (0 + %4)*mmsize + %6] + movaps m6, [outq + %2 + (2 + %4)*mmsize + %6] + movaps m5, [outq + %3 + (0 + %4)*mmsize + %6] + movaps m7, [outq + %3 + (2 + %4)*mmsize + %6] + + SPLIT_RADIX_COMBINE 0, m0, m1, m2, m3, \ + m4, m5, m6, m7, \ + m8, m9, \ + m10, m11, m12, m13, m14, m15 + + movaps [outq + (0 + %4)*mmsize + %6], m0 + movaps [outq + (2 + %4)*mmsize + %6], m2 + movaps [outq + %1 + (0 + %4)*mmsize + %6], m1 + movaps [outq + %1 + (2 + %4)*mmsize + %6], m3 + + movaps [outq + %2 + (0 + %4)*mmsize + %6], m4 + movaps [outq + %2 + (2 + %4)*mmsize + %6], m6 + movaps [outq + %3 + (0 + %4)*mmsize + %6], m5 + movaps [outq + %3 + (2 + %4)*mmsize + %6], m7 +%endmacro + +%macro SPLIT_RADIX_LOAD_COMBINE_FULL 2-5 +%if %0 > 2 +%define offset_c %3 +%else +%define offset_c 0 +%endif +%if %0 > 3 +%define offset_r %4 +%else +%define offset_r 0 +%endif +%if %0 > 4 +%define offset_i %5 +%else +%define offset_i 0 +%endif + + SPLIT_RADIX_LOAD_COMBINE_4 %1, 2*%1, %2, 0, 0, offset_c, offset_r, offset_i + SPLIT_RADIX_LOAD_COMBINE_4 %1, 2*%1, %2, 1, 1, offset_c, offset_r, offset_i + SPLIT_RADIX_LOAD_COMBINE_4 %1, 2*%1, %2, 4, 2, offset_c, offset_r, offset_i + SPLIT_RADIX_LOAD_COMBINE_4 %1, 2*%1, %2, 5, 3, offset_c, offset_r, offset_i +%endmacro + +; Perform a single even/odd split radix combination with loads, deinterleaves and +; stores. The _2 indicates this is a half of the iterations required to complete +; a full combine+deinterleave loop +; %3 must contain len*2, %4 must contain len*4, %5 must contain len*6 +%macro SPLIT_RADIX_COMBINE_DEINTERLEAVE_2 6 + movaps m8, [rtabq + (0 + %2)*mmsize] + vperm2f128 m9, m9, [itabq - (0 + %2)*mmsize], 0x23 + + movaps m0, [outq + (0 + 0 + %1)*mmsize + %6] + movaps m2, [outq + (2 + 0 + %1)*mmsize + %6] + movaps m1, [outq + %3 + (0 + 0 + %1)*mmsize + %6] + movaps m3, [outq + %3 + (2 + 0 + %1)*mmsize + %6] + + movaps m4, [outq + %4 + (0 + 0 + %1)*mmsize + %6] + movaps m6, [outq + %4 + (2 + 0 + %1)*mmsize + %6] + movaps m5, [outq + %5 + (0 + 0 + %1)*mmsize + %6] + movaps m7, [outq + %5 + (2 + 0 + %1)*mmsize + %6] + + SPLIT_RADIX_COMBINE 0, m0, m1, m2, m3, \ + m4, m5, m6, m7, \ + m8, m9, \ + m10, m11, m12, m13, m14, m15 + + unpckhpd m10, m0, m2 + unpckhpd m11, m1, m3 + unpckhpd m12, m4, m6 + unpckhpd m13, m5, m7 + unpcklpd m0, m0, m2 + unpcklpd m1, m1, m3 + unpcklpd m4, m4, m6 + unpcklpd m5, m5, m7 + + vextractf128 [outq + (0 + 0 + %1)*mmsize + %6 + 0], m0, 0 + vextractf128 [outq + (0 + 0 + %1)*mmsize + %6 + 16], m10, 0 + vextractf128 [outq + %3 + (0 + 0 + %1)*mmsize + %6 + 0], m1, 0 + vextractf128 [outq + %3 + (0 + 0 + %1)*mmsize + %6 + 16], m11, 0 + + vextractf128 [outq + %4 + (0 + 0 + %1)*mmsize + %6 + 0], m4, 0 + vextractf128 [outq + %4 + (0 + 0 + %1)*mmsize + %6 + 16], m12, 0 + vextractf128 [outq + %5 + (0 + 0 + %1)*mmsize + %6 + 0], m5, 0 + vextractf128 [outq + %5 + (0 + 0 + %1)*mmsize + %6 + 16], m13, 0 + + vperm2f128 m10, m10, m0, 0x13 + vperm2f128 m11, m11, m1, 0x13 + vperm2f128 m12, m12, m4, 0x13 + vperm2f128 m13, m13, m5, 0x13 + + movaps m8, [rtabq + (1 + %2)*mmsize] + vperm2f128 m9, m9, [itabq - (1 + %2)*mmsize], 0x23 + + movaps m0, [outq + (0 + 1 + %1)*mmsize + %6] + movaps m2, [outq + (2 + 1 + %1)*mmsize + %6] + movaps m1, [outq + %3 + (0 + 1 + %1)*mmsize + %6] + movaps m3, [outq + %3 + (2 + 1 + %1)*mmsize + %6] + + movaps [outq + (0 + 1 + %1)*mmsize + %6], m10 ; m0 conflict + movaps [outq + %3 + (0 + 1 + %1)*mmsize + %6], m11 ; m1 conflict + + movaps m4, [outq + %4 + (0 + 1 + %1)*mmsize + %6] + movaps m6, [outq + %4 + (2 + 1 + %1)*mmsize + %6] + movaps m5, [outq + %5 + (0 + 1 + %1)*mmsize + %6] + movaps m7, [outq + %5 + (2 + 1 + %1)*mmsize + %6] + + movaps [outq + %4 + (0 + 1 + %1)*mmsize + %6], m12 ; m4 conflict + movaps [outq + %5 + (0 + 1 + %1)*mmsize + %6], m13 ; m5 conflict + + SPLIT_RADIX_COMBINE 0, m0, m1, m2, m3, \ + m4, m5, m6, m7, \ + m8, m9, \ + m10, m11, m12, m13, m14, m15 ; temporary registers + + unpcklpd m8, m0, m2 + unpcklpd m9, m1, m3 + unpcklpd m10, m4, m6 + unpcklpd m11, m5, m7 + unpckhpd m0, m0, m2 + unpckhpd m1, m1, m3 + unpckhpd m4, m4, m6 + unpckhpd m5, m5, m7 + + vextractf128 [outq + (2 + 0 + %1)*mmsize + %6 + 0], m8, 0 + vextractf128 [outq + (2 + 0 + %1)*mmsize + %6 + 16], m0, 0 + vextractf128 [outq + (2 + 1 + %1)*mmsize + %6 + 0], m8, 1 + vextractf128 [outq + (2 + 1 + %1)*mmsize + %6 + 16], m0, 1 + + vextractf128 [outq + %3 + (2 + 0 + %1)*mmsize + %6 + 0], m9, 0 + vextractf128 [outq + %3 + (2 + 0 + %1)*mmsize + %6 + 16], m1, 0 + vextractf128 [outq + %3 + (2 + 1 + %1)*mmsize + %6 + 0], m9, 1 + vextractf128 [outq + %3 + (2 + 1 + %1)*mmsize + %6 + 16], m1, 1 + + vextractf128 [outq + %4 + (2 + 0 + %1)*mmsize + %6 + 0], m10, 0 + vextractf128 [outq + %4 + (2 + 0 + %1)*mmsize + %6 + 16], m4, 0 + vextractf128 [outq + %4 + (2 + 1 + %1)*mmsize + %6 + 0], m10, 1 + vextractf128 [outq + %4 + (2 + 1 + %1)*mmsize + %6 + 16], m4, 1 + + vextractf128 [outq + %5 + (2 + 0 + %1)*mmsize + %6 + 0], m11, 0 + vextractf128 [outq + %5 + (2 + 0 + %1)*mmsize + %6 + 16], m5, 0 + vextractf128 [outq + %5 + (2 + 1 + %1)*mmsize + %6 + 0], m11, 1 + vextractf128 [outq + %5 + (2 + 1 + %1)*mmsize + %6 + 16], m5, 1 +%endmacro + +%macro SPLIT_RADIX_COMBINE_DEINTERLEAVE_FULL 2-3 +%if %0 > 2 +%define offset %3 +%else +%define offset 0 +%endif + SPLIT_RADIX_COMBINE_DEINTERLEAVE_2 0, 0, %1, %1*2, %2, offset + SPLIT_RADIX_COMBINE_DEINTERLEAVE_2 4, 2, %1, %1*2, %2, offset +%endmacro + +INIT_XMM sse3 +cglobal fft2_asm_float, 0, 0, 0, ctx, out, in, stride + movaps m0, [inq] + FFT2 m0, m1 + movaps [outq], m0 + ret + +cglobal fft2_float, 4, 4, 2, ctx, out, in, stride + movaps m0, [inq] + FFT2 m0, m1 + movaps [outq], m0 + RET + +%macro FFT4_FN 3 +INIT_XMM sse2 +%if %3 +cglobal fft4_ %+ %1 %+ _asm_float, 0, 0, 0, ctx, out, in, stride +%else +cglobal fft4_ %+ %1 %+ _float, 4, 4, 3, ctx, out, in, stride +%endif + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] + +%if %2 + shufps m2, m1, m0, q3210 + shufps m0, m0, m1, q3210 + movaps m1, m2 +%endif + + FFT4 m0, m1, m2 + + unpcklpd m2, m0, m1 + unpckhpd m0, m0, m1 + + movaps [outq + 0*mmsize], m2 + movaps [outq + 1*mmsize], m0 + +%if %3 + ret +%else + RET +%endif +%endmacro + +FFT4_FN fwd, 0, 0 +FFT4_FN fwd, 0, 1 +FFT4_FN inv, 1, 0 +FFT4_FN inv, 1, 1 + +%macro FFT8_SSE_FN 1 +INIT_XMM sse3 +%if %1 +cglobal fft8_asm_float, 0, 0, 0, ctx, out, in, stride, tmp + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] + movaps m2, [inq + 2*mmsize] + movaps m3, [inq + 3*mmsize] +%else +cglobal fft8_float, 4, 4, 6, ctx, out, in, tmp + mov ctxq, [ctxq + AVTXContext.map] + LOAD64_LUT m0, inq, ctxq, (mmsize/2)*0, tmpq + LOAD64_LUT m1, inq, ctxq, (mmsize/2)*1, tmpq + LOAD64_LUT m2, inq, ctxq, (mmsize/2)*2, tmpq + LOAD64_LUT m3, inq, ctxq, (mmsize/2)*3, tmpq +%endif + + FFT8 m0, m1, m2, m3, m4, m5 + + unpcklpd m4, m0, m3 + unpcklpd m5, m1, m2 + unpckhpd m0, m0, m3 + unpckhpd m1, m1, m2 + + movups [outq + 0*mmsize], m4 + movups [outq + 1*mmsize], m0 + movups [outq + 2*mmsize], m5 + movups [outq + 3*mmsize], m1 + +%if %1 + ret +%else + RET +%endif + +%if %1 +cglobal fft8_ns_float, 4, 5, 6, ctx, out, in, stride, tmp + call mangle(ff_tx_fft8_asm_float_sse3) + RET +%endif +%endmacro + +FFT8_SSE_FN 0 +FFT8_SSE_FN 1 + +%macro FFT8_AVX_FN 1 +INIT_YMM avx +%if %1 +cglobal fft8_asm_float, 0, 0, 0, ctx, out, in, stride, tmp + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] +%else +cglobal fft8_float, 4, 4, 4, ctx, out, in, tmp + mov ctxq, [ctxq + AVTXContext.map] + LOAD64_LUT m0, inq, ctxq, (mmsize/2)*0, tmpq, m2 + LOAD64_LUT m1, inq, ctxq, (mmsize/2)*1, tmpq, m3 +%endif + + FFT8_AVX m0, m1, m2, m3 + + unpcklpd m2, m0, m1 + unpckhpd m0, m0, m1 + + ; Around 2% faster than 2x vperm2f128 + 2x movapd + vextractf128 [outq + 16*0], m2, 0 + vextractf128 [outq + 16*1], m0, 0 + vextractf128 [outq + 16*2], m2, 1 + vextractf128 [outq + 16*3], m0, 1 + +%if %1 + ret +%else + RET +%endif + +%if %1 +cglobal fft8_ns_float, 4, 5, 4, ctx, out, in, stride, tmp + call mangle(ff_tx_fft8_asm_float_avx) + RET +%endif +%endmacro + +FFT8_AVX_FN 0 +FFT8_AVX_FN 1 + +%macro FFT16_FN 2 +INIT_YMM %1 +%if %2 +cglobal fft16_asm_float, 0, 0, 0, ctx, out, in, stride, tmp + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] + movaps m2, [inq + 2*mmsize] + movaps m3, [inq + 3*mmsize] +%else +cglobal fft16_float, 4, 4, 8, ctx, out, in, tmp + mov ctxq, [ctxq + AVTXContext.map] + LOAD64_LUT m0, inq, ctxq, (mmsize/2)*0, tmpq, m4 + LOAD64_LUT m1, inq, ctxq, (mmsize/2)*1, tmpq, m5 + LOAD64_LUT m2, inq, ctxq, (mmsize/2)*2, tmpq, m6 + LOAD64_LUT m3, inq, ctxq, (mmsize/2)*3, tmpq, m7 +%endif + + FFT16 m0, m1, m2, m3, m4, m5, m6, m7 + + unpcklpd m5, m1, m3 + unpcklpd m4, m0, m2 + unpckhpd m1, m1, m3 + unpckhpd m0, m0, m2 + + vextractf128 [outq + 16*0], m4, 0 + vextractf128 [outq + 16*1], m0, 0 + vextractf128 [outq + 16*2], m4, 1 + vextractf128 [outq + 16*3], m0, 1 + vextractf128 [outq + 16*4], m5, 0 + vextractf128 [outq + 16*5], m1, 0 + vextractf128 [outq + 16*6], m5, 1 + vextractf128 [outq + 16*7], m1, 1 + +%if %2 + ret +%else + RET +%endif + +%if %2 +cglobal fft16_ns_float, 4, 5, 8, ctx, out, in, stride, tmp + call mangle(ff_tx_fft16_asm_float_ %+ %1) + RET +%endif +%endmacro + +FFT16_FN avx, 0 +FFT16_FN avx, 1 +FFT16_FN fma3, 0 +FFT16_FN fma3, 1 + +%macro FFT32_FN 2 +INIT_YMM %1 +%if %2 +cglobal fft32_asm_float, 0, 0, 0, ctx, out, in, stride, tmp + movaps m4, [inq + 4*mmsize] + movaps m5, [inq + 5*mmsize] + movaps m6, [inq + 6*mmsize] + movaps m7, [inq + 7*mmsize] +%else +cglobal fft32_float, 4, 4, 16, ctx, out, in, tmp + mov ctxq, [ctxq + AVTXContext.map] + LOAD64_LUT m4, inq, ctxq, (mmsize/2)*4, tmpq, m8, m12 + LOAD64_LUT m5, inq, ctxq, (mmsize/2)*5, tmpq, m9, m13 + LOAD64_LUT m6, inq, ctxq, (mmsize/2)*6, tmpq, m10, m14 + LOAD64_LUT m7, inq, ctxq, (mmsize/2)*7, tmpq, m11, m15 +%endif + + FFT8 m4, m5, m6, m7, m8, m9 + +%if %2 + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] + movaps m2, [inq + 2*mmsize] + movaps m3, [inq + 3*mmsize] +%else + LOAD64_LUT m0, inq, ctxq, (mmsize/2)*0, tmpq, m8, m12 + LOAD64_LUT m1, inq, ctxq, (mmsize/2)*1, tmpq, m9, m13 + LOAD64_LUT m2, inq, ctxq, (mmsize/2)*2, tmpq, m10, m14 + LOAD64_LUT m3, inq, ctxq, (mmsize/2)*3, tmpq, m11, m15 +%endif + + movaps m8, [tab_32_float] + vperm2f128 m9, m9, [tab_32_float + 4*8 - 4*7], 0x23 + + FFT16 m0, m1, m2, m3, m10, m11, m12, m13 + + SPLIT_RADIX_COMBINE 1, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, \ + m10, m11, m12, m13, m14, m15 ; temporary registers + + unpcklpd m9, m1, m3 + unpcklpd m10, m5, m7 + unpcklpd m8, m0, m2 + unpcklpd m11, m4, m6 + unpckhpd m1, m1, m3 + unpckhpd m5, m5, m7 + unpckhpd m0, m0, m2 + unpckhpd m4, m4, m6 + + vextractf128 [outq + 16* 0], m8, 0 + vextractf128 [outq + 16* 1], m0, 0 + vextractf128 [outq + 16* 2], m8, 1 + vextractf128 [outq + 16* 3], m0, 1 + vextractf128 [outq + 16* 4], m9, 0 + vextractf128 [outq + 16* 5], m1, 0 + vextractf128 [outq + 16* 6], m9, 1 + vextractf128 [outq + 16* 7], m1, 1 + + vextractf128 [outq + 16* 8], m11, 0 + vextractf128 [outq + 16* 9], m4, 0 + vextractf128 [outq + 16*10], m11, 1 + vextractf128 [outq + 16*11], m4, 1 + vextractf128 [outq + 16*12], m10, 0 + vextractf128 [outq + 16*13], m5, 0 + vextractf128 [outq + 16*14], m10, 1 + vextractf128 [outq + 16*15], m5, 1 + +%if %2 + ret +%else + RET +%endif + +%if %2 +cglobal fft32_ns_float, 4, 5, 16, ctx, out, in, stride, tmp + call mangle(ff_tx_fft32_asm_float_ %+ %1) + RET +%endif +%endmacro + +%if ARCH_X86_64 +FFT32_FN avx, 0 +FFT32_FN avx, 1 +FFT32_FN fma3, 0 +FFT32_FN fma3, 1 +%endif + +%macro FFT_SPLIT_RADIX_DEF 1-2 +ALIGN 16 +.%1 %+ pt: + PUSH lenq + mov lenq, (%1/4) + + add outq, (%1*4) - (%1/1) + call .32pt + + add outq, (%1*2) - (%1/2) ; the synth loops also increment outq + call .32pt + + POP lenq + sub outq, (%1*4) + (%1*2) + (%1/2) + + lea rtabq, [tab_ %+ %1 %+ _float] + lea itabq, [tab_ %+ %1 %+ _float + %1 - 4*7] + +%if %0 > 1 + cmp tgtq, %1 + je .deinterleave + + mov tmpq, %1 + +.synth_ %+ %1: + SPLIT_RADIX_LOAD_COMBINE_FULL 2*%1, 6*%1, 0, 0, 0 + add outq, 8*mmsize + add rtabq, 4*mmsize + sub itabq, 4*mmsize + sub tmpq, 4*mmsize + jg .synth_ %+ %1 + + cmp lenq, %1 + jg %2 ; can't do math here, nasm doesn't get it + ret +%endif +%endmacro + +%macro FFT_SPLIT_RADIX_FN 2 +INIT_YMM %1 +%if %2 +cglobal fft_sr_asm_float, 0, 0, 0, ctx, out, in, stride, len, lut, itab, rtab, tgt, tmp +%else +cglobal fft_sr_float, 4, 10, 16, 272, ctx, out, in, stride, len, lut, itab, rtab, tgt, tmp + movsxd lenq, dword [ctxq + AVTXContext.len] + mov lutq, [ctxq + AVTXContext.map] +%endif + mov tgtq, lenq + +; Bottom-most/32-point transform =============================================== +ALIGN 16 +.32pt: +%if %2 + movaps m4, [inq + 4*mmsize] + movaps m5, [inq + 5*mmsize] + movaps m6, [inq + 6*mmsize] + movaps m7, [inq + 7*mmsize] +%else + LOAD64_LUT m4, inq, lutq, (mmsize/2)*4, tmpq, m8, m12 + LOAD64_LUT m5, inq, lutq, (mmsize/2)*5, tmpq, m9, m13 + LOAD64_LUT m6, inq, lutq, (mmsize/2)*6, tmpq, m10, m14 + LOAD64_LUT m7, inq, lutq, (mmsize/2)*7, tmpq, m11, m15 +%endif + + FFT8 m4, m5, m6, m7, m8, m9 + +%if %2 + movaps m0, [inq + 0*mmsize] + movaps m1, [inq + 1*mmsize] + movaps m2, [inq + 2*mmsize] + movaps m3, [inq + 3*mmsize] +%else + LOAD64_LUT m0, inq, lutq, (mmsize/2)*0, tmpq, m8, m12 + LOAD64_LUT m1, inq, lutq, (mmsize/2)*1, tmpq, m9, m13 + LOAD64_LUT m2, inq, lutq, (mmsize/2)*2, tmpq, m10, m14 + LOAD64_LUT m3, inq, lutq, (mmsize/2)*3, tmpq, m11, m15 +%endif + + movaps m8, [tab_32_float] + vperm2f128 m9, m9, [tab_32_float + 32 - 4*7], 0x23 + + FFT16 m0, m1, m2, m3, m10, m11, m12, m13 + + SPLIT_RADIX_COMBINE 1, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, \ + m10, m11, m12, m13, m14, m15 ; temporary registers + + movaps [outq + 1*mmsize], m1 + movaps [outq + 3*mmsize], m3 + movaps [outq + 5*mmsize], m5 + movaps [outq + 7*mmsize], m7 + +%if %2 + add inq, 8*mmsize +%else + add lutq, (mmsize/2)*8 +%endif + cmp lenq, 32 + jg .64pt + + movaps [outq + 0*mmsize], m0 + movaps [outq + 2*mmsize], m2 + movaps [outq + 4*mmsize], m4 + movaps [outq + 6*mmsize], m6 + + ret + +; 64-point transform =========================================================== +ALIGN 16 +.64pt: +; Helper defines, these make it easier to track what's happening +%define tx1_e0 m4 +%define tx1_e1 m5 +%define tx1_o0 m6 +%define tx1_o1 m7 +%define tx2_e0 m8 +%define tx2_e1 m9 +%define tx2_o0 m10 +%define tx2_o1 m11 +%define tw_e m12 +%define tw_o m13 +%define tmp1 m14 +%define tmp2 m15 + + SWAP m4, m1 + SWAP m6, m3 + +%if %2 + movaps tx1_e0, [inq + 0*mmsize] + movaps tx1_e1, [inq + 1*mmsize] + movaps tx1_o0, [inq + 2*mmsize] + movaps tx1_o1, [inq + 3*mmsize] +%else + LOAD64_LUT tx1_e0, inq, lutq, (mmsize/2)*0, tmpq, tw_e, tmp1 + LOAD64_LUT tx1_e1, inq, lutq, (mmsize/2)*1, tmpq, tw_o, tmp2 + LOAD64_LUT tx1_o0, inq, lutq, (mmsize/2)*2, tmpq, tw_e, tmp1 + LOAD64_LUT tx1_o1, inq, lutq, (mmsize/2)*3, tmpq, tw_o, tmp2 +%endif + + FFT16 tx1_e0, tx1_e1, tx1_o0, tx1_o1, tw_e, tw_o, tx2_o0, tx2_o1 + +%if %2 + movaps tx2_e0, [inq + 4*mmsize] + movaps tx2_e1, [inq + 5*mmsize] + movaps tx2_o0, [inq + 6*mmsize] + movaps tx2_o1, [inq + 7*mmsize] +%else + LOAD64_LUT tx2_e0, inq, lutq, (mmsize/2)*4, tmpq, tw_e, tmp1 + LOAD64_LUT tx2_e1, inq, lutq, (mmsize/2)*5, tmpq, tw_o, tmp2 + LOAD64_LUT tx2_o0, inq, lutq, (mmsize/2)*6, tmpq, tw_e, tmp1 + LOAD64_LUT tx2_o1, inq, lutq, (mmsize/2)*7, tmpq, tw_o, tmp2 +%endif + + FFT16 tx2_e0, tx2_e1, tx2_o0, tx2_o1, tmp1, tmp2, tw_e, tw_o + + movaps tw_e, [tab_64_float] + vperm2f128 tw_o, tw_o, [tab_64_float + 64 - 4*7], 0x23 + +%if %2 + add inq, 8*mmsize +%else + add lutq, (mmsize/2)*8 +%endif + cmp tgtq, 64 + je .64pt_deint + + SPLIT_RADIX_COMBINE_64 + + cmp lenq, 64 + jg .128pt + ret + +; 128-point transform ========================================================== +ALIGN 16 +.128pt: + PUSH lenq + mov lenq, 32 + + add outq, 16*mmsize + call .32pt + + add outq, 8*mmsize + call .32pt + + POP lenq + sub outq, 24*mmsize + + lea rtabq, [tab_128_float] + lea itabq, [tab_128_float + 128 - 4*7] + + cmp tgtq, 128 + je .deinterleave + + SPLIT_RADIX_LOAD_COMBINE_FULL 2*128, 6*128 + + cmp lenq, 128 + jg .256pt + ret + +; 256-point transform ========================================================== +ALIGN 16 +.256pt: + PUSH lenq + mov lenq, 64 + + add outq, 32*mmsize + call .32pt + + add outq, 16*mmsize + call .32pt + + POP lenq + sub outq, 48*mmsize + + lea rtabq, [tab_256_float] + lea itabq, [tab_256_float + 256 - 4*7] + + cmp tgtq, 256 + je .deinterleave + + SPLIT_RADIX_LOAD_COMBINE_FULL 2*256, 6*256 + SPLIT_RADIX_LOAD_COMBINE_FULL 2*256, 6*256, 8*mmsize, 4*mmsize, -4*mmsize + + cmp lenq, 256 + jg .512pt + ret + +; 512-point transform ========================================================== +ALIGN 16 +.512pt: + PUSH lenq + mov lenq, 128 + + add outq, 64*mmsize + call .32pt + + add outq, 32*mmsize + call .32pt + + POP lenq + sub outq, 96*mmsize + + lea rtabq, [tab_512_float] + lea itabq, [tab_512_float + 512 - 4*7] + + cmp tgtq, 512 + je .deinterleave + + mov tmpq, 4 + +.synth_512: + SPLIT_RADIX_LOAD_COMBINE_FULL 2*512, 6*512 + add outq, 8*mmsize + add rtabq, 4*mmsize + sub itabq, 4*mmsize + sub tmpq, 1 + jg .synth_512 + + cmp lenq, 512 + jg .1024pt + ret + +; 1024-point transform ========================================================== +ALIGN 16 +.1024pt: + PUSH lenq + mov lenq, 256 + + add outq, 96*mmsize + call .32pt + + add outq, 64*mmsize + call .32pt + + POP lenq + sub outq, 192*mmsize + + lea rtabq, [tab_1024_float] + lea itabq, [tab_1024_float + 1024 - 4*7] + + cmp tgtq, 1024 + je .deinterleave + + mov tmpq, 8 + +.synth_1024: + SPLIT_RADIX_LOAD_COMBINE_FULL 2*1024, 6*1024 + add outq, 8*mmsize + add rtabq, 4*mmsize + sub itabq, 4*mmsize + sub tmpq, 1 + jg .synth_1024 + + cmp lenq, 1024 + jg .2048pt + ret + +; 2048 to 131072-point transforms ============================================== +FFT_SPLIT_RADIX_DEF 2048, .4096pt +FFT_SPLIT_RADIX_DEF 4096, .8192pt +FFT_SPLIT_RADIX_DEF 8192, .16384pt +FFT_SPLIT_RADIX_DEF 16384, .32768pt +FFT_SPLIT_RADIX_DEF 32768, .65536pt +FFT_SPLIT_RADIX_DEF 65536, .131072pt +FFT_SPLIT_RADIX_DEF 131072 + +;=============================================================================== +; Final synthesis + deinterleaving code +;=============================================================================== +.deinterleave: +%if %2 + PUSH strideq +%endif + mov tgtq, lenq + imul tmpq, lenq, 2 + lea strideq, [4*lenq + tmpq] + +.synth_deinterleave: + SPLIT_RADIX_COMBINE_DEINTERLEAVE_FULL tmpq, strideq + add outq, 8*mmsize + add rtabq, 4*mmsize + sub itabq, 4*mmsize + sub tgtq, 4*mmsize + jg .synth_deinterleave + +%if %2 + POP strideq + sub outq, tmpq + neg tmpq + lea inq, [inq + tmpq*4] + ret +%else + RET +%endif + +; 64-point deinterleave which only has to load 4 registers ===================== +.64pt_deint: + SPLIT_RADIX_COMBINE_LITE 1, m0, m1, tx1_e0, tx2_e0, tw_e, tw_o, tmp1, tmp2 + SPLIT_RADIX_COMBINE_HALF 0, m2, m3, tx1_o0, tx2_o0, tw_e, tw_o, tmp1, tmp2, tw_e + + unpcklpd tmp1, m0, m2 + unpcklpd tmp2, m1, m3 + unpcklpd tw_o, tx1_e0, tx1_o0 + unpcklpd tw_e, tx2_e0, tx2_o0 + unpckhpd m0, m0, m2 + unpckhpd m1, m1, m3 + unpckhpd tx1_e0, tx1_e0, tx1_o0 + unpckhpd tx2_e0, tx2_e0, tx2_o0 + + vextractf128 [outq + 0*mmsize + 0], tmp1, 0 + vextractf128 [outq + 0*mmsize + 16], m0, 0 + vextractf128 [outq + 4*mmsize + 0], tmp2, 0 + vextractf128 [outq + 4*mmsize + 16], m1, 0 + + vextractf128 [outq + 8*mmsize + 0], tw_o, 0 + vextractf128 [outq + 8*mmsize + 16], tx1_e0, 0 + vextractf128 [outq + 9*mmsize + 0], tw_o, 1 + vextractf128 [outq + 9*mmsize + 16], tx1_e0, 1 + + vperm2f128 tmp1, tmp1, m0, 0x31 + vperm2f128 tmp2, tmp2, m1, 0x31 + + vextractf128 [outq + 12*mmsize + 0], tw_e, 0 + vextractf128 [outq + 12*mmsize + 16], tx2_e0, 0 + vextractf128 [outq + 13*mmsize + 0], tw_e, 1 + vextractf128 [outq + 13*mmsize + 16], tx2_e0, 1 + + movaps tw_e, [tab_64_float + mmsize] + vperm2f128 tw_o, tw_o, [tab_64_float + 64 - 4*7 - mmsize], 0x23 + + movaps m0, [outq + 1*mmsize] + movaps m1, [outq + 3*mmsize] + movaps m2, [outq + 5*mmsize] + movaps m3, [outq + 7*mmsize] + + movaps [outq + 1*mmsize], tmp1 + movaps [outq + 5*mmsize], tmp2 + + SPLIT_RADIX_COMBINE 0, m0, m2, m1, m3, tx1_e1, tx2_e1, tx1_o1, tx2_o1, tw_e, tw_o, \ + tmp1, tmp2, tx2_o0, tx1_o0, tx2_e0, tx1_e0 ; temporary registers + + unpcklpd tmp1, m0, m1 + unpcklpd tmp2, m2, m3 + unpcklpd tw_e, tx1_e1, tx1_o1 + unpcklpd tw_o, tx2_e1, tx2_o1 + unpckhpd m0, m0, m1 + unpckhpd m2, m2, m3 + unpckhpd tx1_e1, tx1_e1, tx1_o1 + unpckhpd tx2_e1, tx2_e1, tx2_o1 + + vextractf128 [outq + 2*mmsize + 0], tmp1, 0 + vextractf128 [outq + 2*mmsize + 16], m0, 0 + vextractf128 [outq + 3*mmsize + 0], tmp1, 1 + vextractf128 [outq + 3*mmsize + 16], m0, 1 + + vextractf128 [outq + 6*mmsize + 0], tmp2, 0 + vextractf128 [outq + 6*mmsize + 16], m2, 0 + vextractf128 [outq + 7*mmsize + 0], tmp2, 1 + vextractf128 [outq + 7*mmsize + 16], m2, 1 + + vextractf128 [outq + 10*mmsize + 0], tw_e, 0 + vextractf128 [outq + 10*mmsize + 16], tx1_e1, 0 + vextractf128 [outq + 11*mmsize + 0], tw_e, 1 + vextractf128 [outq + 11*mmsize + 16], tx1_e1, 1 + + vextractf128 [outq + 14*mmsize + 0], tw_o, 0 + vextractf128 [outq + 14*mmsize + 16], tx2_e1, 0 + vextractf128 [outq + 15*mmsize + 0], tw_o, 1 + vextractf128 [outq + 15*mmsize + 16], tx2_e1, 1 + +%if %2 + sub inq, 16*mmsize + ret +%else + RET +%endif + +%if %2 +cglobal fft_sr_ns_float, 4, 10, 16, 272, ctx, out, in, tmp, len, lut, itab, rtab, tgt, off + movsxd lenq, dword [ctxq + AVTXContext.len] + mov lutq, [ctxq + AVTXContext.map] + + call mangle(ff_tx_fft_sr_asm_float_ %+ %1) + RET +%endif +%endmacro + +%if ARCH_X86_64 +FFT_SPLIT_RADIX_FN avx, 0 +FFT_SPLIT_RADIX_FN avx, 1 +FFT_SPLIT_RADIX_FN fma3, 0 +FFT_SPLIT_RADIX_FN fma3, 1 +%if HAVE_AVX2_EXTERNAL +FFT_SPLIT_RADIX_FN avx2, 0 +FFT_SPLIT_RADIX_FN avx2, 1 +%endif +%endif + +%macro FFT15_FN 2 +INIT_YMM avx2 +cglobal fft15_ %+ %2, 4, 10, 16, ctx, out, in, stride, len, lut, tmp, tgt5, stride3, stride5 + mov lutq, [ctxq + AVTXContext.map] + + imul stride3q, strideq, 3 + imul stride5q, strideq, 5 + + movaps m11, [mask_mmppmmmm] ; mmppmmmm + movaps m10, [tab_53_float] ; tab5 + movaps xm9, [tab_53_float + 32] ; tab3 + vpermpd m9, m9, q1110 ; tab[23232323] + movaps m8, [s15_perm] + +%if %1 + movups xm0, [inq] + movddup xm5, [inq + 16] + movups m2, [inq + mmsize*0 + 24] + movups m3, [inq + mmsize*1 + 24] + movups m4, [inq + mmsize*2 + 24] +%else + LOAD64_LUT xm0, inq, lutq, 0, tmpq, m14, xm15 + LOAD64_LUT m2, inq, lutq, (mmsize/2)*0 + 12, tmpq, m6, m7 + LOAD64_LUT m3, inq, lutq, (mmsize/2)*1 + 12, tmpq, m14, m15 + LOAD64_LUT m4, inq, lutq, (mmsize/2)*2 + 12, tmpq, m6, m7 + mov tmpd, [lutq + 8] + movddup xm5, [inq + tmpq*8] +%endif + + FFT15 + + lea tgt5q, [outq + stride5q] + lea tmpq, [outq + stride5q*2] + + movhps [outq], xm14 ; out[0] + movhps [outq + stride5q*1], xm15 ; out[5] + movlps [outq + stride5q*2], xm15 ; out[10] + + vextractf128 xm3, m0, 1 + vextractf128 xm4, m1, 1 + vextractf128 xm5, m2, 1 + + movlps [outq + strideq*1], xm1 + movhps [outq + strideq*2], xm2 + movlps [outq + stride3q*1], xm3 + movhps [outq + strideq*4], xm4 + movlps [outq + stride3q*2], xm0 + movlps [outq + strideq*8], xm5 + movhps [outq + stride3q*4], xm0 + movhps [tgt5q + strideq*2], xm1 + movhps [tgt5q + strideq*4], xm3 + movlps [tmpq + strideq*1], xm2 + movlps [tmpq + stride3q*1], xm4 + movhps [tmpq + strideq*4], xm5 + + RET +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +FFT15_FN 0, float +FFT15_FN 1, ns_float +%endif + +%macro IMDCT_FN 1 +INIT_YMM %1 +cglobal mdct_inv_float, 4, 14, 16, 320, ctx, out, in, stride, len, lut, exp, t1, t2, t3, \ + t4, t5, btmp + movsxd lenq, dword [ctxq + AVTXContext.len] + mov expq, [ctxq + AVTXContext.exp] + + lea t1d, [lend - 1] + imul t1d, strided + + mov btmpq, ctxq ; backup original context + mov lutq, [ctxq + AVTXContext.map] ; load map + + cmp strideq, 4 + je .stride4 + + shl strideq, 1 + movd xm4, strided + vpbroadcastd m4, xm4 ; stride splatted + movd xm5, t1d + vpbroadcastd m5, xm5 ; offset splatted + + mov t2q, outq ; don't modify the original output + pcmpeqd m15, m15 ; set all bits to 1 + +.stridex_pre: + pmulld m2, m4, [lutq] ; multiply by stride + movaps m0, m15 + psubd m3, m5, m2 ; subtract from offset + movaps m1, m15 + vgatherdps m6, [inq + m2], m0 ; im + vgatherdps m7, [inq + m3], m1 ; re + + movaps m8, [expq + 0*mmsize] ; tab 1 + movaps m9, [expq + 1*mmsize] ; tab 2 + + unpcklps m0, m7, m6 ; re, im, re, im + unpckhps m1, m7, m6 ; re, im, re, im + + vperm2f128 m2, m1, m0, 0x02 ; output order + vperm2f128 m3, m1, m0, 0x13 ; output order + + movshdup m10, m8 ; tab 1 imim + movshdup m11, m9 ; tab 2 imim + movsldup m12, m8 ; tab 1 rere + movsldup m13, m9 ; tab 2 rere + + mulps m10, m2 ; 1 reim * imim + mulps m11, m3 ; 2 reim * imim + + shufps m10, m10, m10, q2301 + shufps m11, m11, m11, q2301 + + fmaddsubps m10, m12, m2, m10 + fmaddsubps m11, m13, m3, m11 + + movups [t2q + 0*mmsize], m10 + movups [t2q + 1*mmsize], m11 + + add expq, mmsize*2 + add lutq, mmsize + add t2q, mmsize*2 + sub lenq, mmsize/2 + jg .stridex_pre + jmp .transform + +.stride4: + lea expq, [expq + lenq*4] + lea lutq, [lutq + lenq*2] + lea t1q, [inq + t1q] + lea t1q, [t1q + strideq - mmsize] + lea t2q, [lenq*2 - mmsize/2] + +.stride4_pre: + movups m4, [inq] + movups m3, [t1q] + + movsldup m1, m4 ; im im, im im + movshdup m0, m3 ; re re, re re + movshdup m4, m4 ; re re, re re (2) + movsldup m3, m3 ; im im, im im (2) + + movups m2, [expq] ; tab + movups m5, [expq + 2*t2q] ; tab (2) + + vpermpd m0, m0, q0123 ; flip + shufps m7, m2, m2, q2301 + vpermpd m4, m4, q0123 ; flip (2) + shufps m8, m5, m5, q2301 + + mulps m1, m7 ; im im * tab.reim + mulps m3, m8 ; im im * tab.reim (2) + + fmaddsubps m0, m0, m2, m1 + fmaddsubps m4, m4, m5, m3 + + vextractf128 xm3, m0, 1 + vextractf128 xm6, m4, 1 + + ; scatter + movsxd strideq, dword [lutq + 0*4] + movsxd lenq, dword [lutq + 1*4] + movsxd t3q, dword [lutq + 2*4] + movsxd t4q, dword [lutq + 3*4] + + movlps [outq + strideq*8], xm0 + movhps [outq + lenq*8], xm0 + movlps [outq + t3q*8], xm3 + movhps [outq + t4q*8], xm3 + + movsxd strideq, dword [lutq + 0*4 + t2q] + movsxd lenq, dword [lutq + 1*4 + t2q] + movsxd t3q, dword [lutq + 2*4 + t2q] + movsxd t4q, dword [lutq + 3*4 + t2q] + + movlps [outq + strideq*8], xm4 + movhps [outq + lenq*8], xm4 + movlps [outq + t3q*8], xm6 + movhps [outq + t4q*8], xm6 + + add lutq, mmsize/2 + add expq, mmsize + add inq, mmsize + sub t1q, mmsize + sub t2q, mmsize + jge .stride4_pre + +.transform: + mov strideq, 2*4 + mov t4q, ctxq ; backup original context + mov t5q, [ctxq + AVTXContext.fn] ; subtransform's jump point + mov ctxq, [ctxq + AVTXContext.sub] + mov lutq, [ctxq + AVTXContext.map] + movsxd lenq, dword [ctxq + AVTXContext.len] + + mov inq, outq ; in-place transform + call t5q ; call the FFT + + mov ctxq, t4q ; restore original context + movsxd lenq, dword [ctxq + AVTXContext.len] + mov expq, [ctxq + AVTXContext.exp] + lea expq, [expq + lenq*4] + + xor t1q, t1q ; low + lea t2q, [lenq*4 - mmsize] ; high + +.post: + movaps m2, [expq + t2q] ; tab h + movaps m3, [expq + t1q] ; tab l + movups m0, [outq + t2q] ; in h + movups m1, [outq + t1q] ; in l + + movshdup m4, m2 ; tab h imim + movshdup m5, m3 ; tab l imim + movsldup m6, m2 ; tab h rere + movsldup m7, m3 ; tab l rere + + shufps m2, m0, m0, q2301 ; in h imre + shufps m3, m1, m1, q2301 ; in l imre + + mulps m6, m0 + mulps m7, m1 + + fmaddsubps m4, m4, m2, m6 + fmaddsubps m5, m5, m3, m7 + + vpermpd m3, m5, q0123 ; flip + vpermpd m2, m4, q0123 ; flip + + blendps m1, m2, m5, 01010101b + blendps m0, m3, m4, 01010101b + + movups [outq + t2q], m0 + movups [outq + t1q], m1 + + add t1q, mmsize + sub t2q, mmsize + sub lenq, mmsize/2 + jg .post + + RET +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +IMDCT_FN avx2 +%endif + +%macro PFA_15_FN 2 +INIT_YMM %1 +%if %2 +cglobal fft_pfa_15xM_asm_float, 0, 0, 0, ctx, out, in, stride, len, lut, buf, map, tgt, tmp, \ + tgt5, stride3, stride5, btmp +%else +cglobal fft_pfa_15xM_float, 4, 14, 16, 320, ctx, out, in, stride, len, lut, buf, map, tgt, tmp, \ + tgt5, stride3, stride5, btmp +%endif + +%if %2 + PUSH inq + PUSH tgt5q + PUSH stride3q + PUSH stride5q + PUSH btmpq +%endif + + PUSH strideq + + mov btmpq, outq + + mov outq, [ctxq + AVTXContext.tmp] +%if %2 == 0 + movsxd lenq, dword [ctxq + AVTXContext.len] + mov lutq, [ctxq + AVTXContext.map] +%endif + + ; Load stride (second transform's length) and second transform's LUT + mov tmpq, [ctxq + AVTXContext.sub] + movsxd strideq, dword [tmpq + AVTXContext.len] + mov mapq, [tmpq + AVTXContext.map] + + shl strideq, 3 + imul stride3q, strideq, 3 + imul stride5q, strideq, 5 + + movaps m11, [mask_mmppmmmm] ; mmppmmmm + movaps m10, [tab_53_float] ; tab5 + movaps xm9, [tab_53_float + 32] ; tab3 + vpermpd m9, m9, q1110 ; tab[23232323] + movaps m8, [s15_perm] + +.dim1: + mov tmpd, [mapq] + lea tgtq, [outq + tmpq*8] + +%if %2 + movups xm0, [inq] ; in[0,1].reim + movddup xm5, [inq + 16] ; in[2].reimreim + movups m2, [inq + mmsize*0 + 24] ; in[3-6].reim + movups m3, [inq + mmsize*1 + 24] ; in[7-11].reim + movups m4, [inq + mmsize*2 + 24] ; in[12-15].reim +%else + LOAD64_LUT xm0, inq, lutq, 0, tmpq, m14, xm15 ; in[0,1].reim + LOAD64_LUT m2, inq, lutq, (mmsize/2)*0 + 12, tmpq, m6, m7 + LOAD64_LUT m3, inq, lutq, (mmsize/2)*1 + 12, tmpq, m14, m15 + LOAD64_LUT m4, inq, lutq, (mmsize/2)*2 + 12, tmpq, m6, m7 + mov tmpd, [lutq + 8] + movddup xm5, [inq + tmpq*8] ; in[2].reimreim +%endif + + FFT15 + + lea tgt5q, [tgtq + stride5q] + lea tmpq, [tgtq + stride5q*2] + + movhps [tgtq], xm14 ; out[0] + movhps [tgtq + stride5q*1], xm15 ; out[5] + movlps [tgtq + stride5q*2], xm15 ; out[10] + + vextractf128 xm3, m0, 1 + vextractf128 xm4, m1, 1 + vextractf128 xm5, m2, 1 + + movlps [tgtq + strideq*1], xm1 + movhps [tgtq + strideq*2], xm2 + movlps [tgtq + stride3q*1], xm3 + movhps [tgtq + strideq*4], xm4 + movlps [tgtq + stride3q*2], xm0 + movlps [tgtq + strideq*8], xm5 + movhps [tgtq + stride3q*4], xm0 + movhps [tgt5q + strideq*2], xm1 + movhps [tgt5q + strideq*4], xm3 + movlps [tmpq + strideq*1], xm2 + movlps [tmpq + stride3q*1], xm4 + movhps [tmpq + strideq*4], xm5 + +%if %2 + add inq, mmsize*3 + 24 +%else + add lutq, (mmsize/2)*3 + 12 +%endif + add mapq, 4 + sub lenq, 15 + jg .dim1 + + ; Second transform setup + mov stride5q, ctxq ; backup original context + movsxd stride3q, dword [ctxq + AVTXContext.len] ; full length + mov tgt5q, [ctxq + AVTXContext.fn] ; subtransform's jump point + + mov inq, outq ; in-place transform + mov ctxq, [ctxq + AVTXContext.sub] ; load subtransform's context + mov lutq, [ctxq + AVTXContext.map] ; load subtransform's map + movsxd lenq, dword [ctxq + AVTXContext.len] ; load subtransform's length + +.dim2: + call tgt5q ; call the FFT + lea inq, [inq + lenq*8] + lea outq, [outq + lenq*8] + sub stride3q, lenq + jg .dim2 + + mov ctxq, stride5q ; restore original context + mov lutq, [ctxq + AVTXContext.map] + mov inq, [ctxq + AVTXContext.tmp] + movsxd lenq, dword [ctxq + AVTXContext.len] ; full length + + lea stride3q, [lutq + lenq*4] ; second part of the LUT + mov stride5q, lenq + mov tgt5q, btmpq + POP strideq + lea tmpq, [strideq + 2*strideq] + +.post: + LOAD64_LUT m0, inq, stride3q, 0, tmpq, m8, m9 + vextractf128 xm1, m0, 1 + movlps [tgt5q], xm0 + movhps [tgt5q + strideq], xm0 + movlps [tgt5q + strideq*2], xm1 + movhps [tgt5q + tmpq], xm1 + + lea tgt5q, [tgt5q + 4*strideq] + add stride3q, mmsize/2 + sub stride5q, mmsize/8 + jg .post + +%if %2 + mov outq, btmpq + POP btmpq + POP stride5q + POP stride3q + POP tgt5q + POP inq + ret +%else + RET +%endif + +%if %2 +cglobal fft_pfa_15xM_ns_float, 4, 14, 16, 320, ctx, out, in, stride, len, lut, buf, map, tgt, tmp, \ + tgt5, stride3, stride5, btmp + movsxd lenq, dword [ctxq + AVTXContext.len] + mov lutq, [ctxq + AVTXContext.map] + + call mangle(ff_tx_fft_pfa_15xM_asm_float) + RET +%endif +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +PFA_15_FN avx2, 0 +PFA_15_FN avx2, 1 +%endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float_init.c b/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float_init.c new file mode 100644 index 00000000..d3c0beb5 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/tx_float_init.c @@ -0,0 +1,310 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define TX_FLOAT +#include "libavutil/tx_priv.h" +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" + +#include "config.h" + +TX_DECL_FN(fft2, sse3) +TX_DECL_FN(fft4_fwd, sse2) +TX_DECL_FN(fft4_inv, sse2) +TX_DECL_FN(fft8, sse3) +TX_DECL_FN(fft8_ns, sse3) +TX_DECL_FN(fft8, avx) +TX_DECL_FN(fft8_ns, avx) +TX_DECL_FN(fft15, avx2) +TX_DECL_FN(fft15_ns, avx2) +TX_DECL_FN(fft16, avx) +TX_DECL_FN(fft16_ns, avx) +TX_DECL_FN(fft16, fma3) +TX_DECL_FN(fft16_ns, fma3) +TX_DECL_FN(fft32, avx) +TX_DECL_FN(fft32_ns, avx) +TX_DECL_FN(fft32, fma3) +TX_DECL_FN(fft32_ns, fma3) +TX_DECL_FN(fft_sr, avx) +TX_DECL_FN(fft_sr_ns, avx) +TX_DECL_FN(fft_sr, fma3) +TX_DECL_FN(fft_sr_ns, fma3) +TX_DECL_FN(fft_sr, avx2) +TX_DECL_FN(fft_sr_ns, avx2) + +TX_DECL_FN(fft_pfa_15xM, avx2) +TX_DECL_FN(fft_pfa_15xM_ns, avx2) + +TX_DECL_FN(mdct_inv, avx2) + +TX_DECL_FN(fft2_asm, sse3) +TX_DECL_FN(fft4_fwd_asm, sse2) +TX_DECL_FN(fft4_inv_asm, sse2) +TX_DECL_FN(fft8_asm, sse3) +TX_DECL_FN(fft8_asm, avx) +TX_DECL_FN(fft16_asm, avx) +TX_DECL_FN(fft16_asm, fma3) +TX_DECL_FN(fft32_asm, avx) +TX_DECL_FN(fft32_asm, fma3) +TX_DECL_FN(fft_sr_asm, avx) +TX_DECL_FN(fft_sr_asm, fma3) +TX_DECL_FN(fft_sr_asm, avx2) + +TX_DECL_FN(fft_pfa_15xM_asm, avx2) + +#define DECL_INIT_FN(basis, interleave) \ +static av_cold int b ##basis## _i ##interleave(AVTXContext *s, \ + const FFTXCodelet *cd, \ + uint64_t flags, \ + FFTXCodeletOptions *opts, \ + int len, int inv, \ + const void *scale) \ +{ \ + ff_tx_init_tabs_float(len); \ + if (cd->max_len == 2) \ + return ff_tx_gen_ptwo_revtab(s, opts); \ + else \ + return ff_tx_gen_split_radix_parity_revtab(s, len, inv, opts, \ + basis, interleave); \ +} + +DECL_INIT_FN(8, 0) +DECL_INIT_FN(8, 2) + +static av_cold int factor_init(AVTXContext *s, const FFTXCodelet *cd, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale) +{ + int ret; + + /* The transformations below are performed in the gather domain, + * so override the option and let the infrastructure convert the map + * to SCATTER if needed. */ + FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_GATHER }; + + TX_TAB(ff_tx_init_tabs)(len); + + if (len == 15) + ret = ff_tx_gen_pfa_input_map(s, &sub_opts, 3, 5); + else + ret = ff_tx_gen_default_map(s, &sub_opts); + + if (ret < 0) + return ret; + + if (len == 15) { + int cnt = 0, tmp[15]; + + /* Special permutation to simplify loads in the pre-permuted version */ + memcpy(tmp, s->map, 15*sizeof(*tmp)); + for (int i = 1; i < 15; i += 3) { + s->map[cnt] = tmp[i]; + cnt++; + } + for (int i = 2; i < 15; i += 3) { + s->map[cnt] = tmp[i]; + cnt++; + } + for (int i = 0; i < 15; i += 3) { + s->map[cnt] = tmp[i]; + cnt++; + } + memmove(&s->map[7], &s->map[6], 4*sizeof(int)); + memmove(&s->map[3], &s->map[1], 4*sizeof(int)); + s->map[1] = tmp[2]; + s->map[2] = tmp[0]; + } + + return 0; +} + +static av_cold int m_inv_init(AVTXContext *s, const FFTXCodelet *cd, + uint64_t flags, FFTXCodeletOptions *opts, + int len, int inv, const void *scale) +{ + int ret; + FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_GATHER }; + + s->scale_d = *((SCALE_TYPE *)scale); + s->scale_f = s->scale_d; + + flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */ + flags |= AV_TX_INPLACE; /* in-place */ + flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */ + flags |= FF_TX_ASM_CALL; /* We want an assembly function, not C */ + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, len >> 1, + inv, scale))) + return ret; + + s->map = av_malloc(len*sizeof(*s->map)); + if (!s->map) + return AVERROR(ENOMEM); + + memcpy(s->map, s->sub->map, (len >> 1)*sizeof(*s->map)); + /* Invert lookup table for unstrided path */ + for (int i = 0; i < (len >> 1); i++) + s->map[(len >> 1) + s->map[i]] = i; + + if ((ret = ff_tx_mdct_gen_exp_float(s, s->map))) + return ret; + + return 0; +} + +static av_cold int fft_pfa_init(AVTXContext *s, + const FFTXCodelet *cd, + uint64_t flags, + FFTXCodeletOptions *opts, + int len, int inv, + const void *scale) +{ + int ret; + int sub_len = len / cd->factors[0]; + FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_SCATTER }; + + flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */ + flags |= AV_TX_INPLACE; /* in-place */ + flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */ + flags |= FF_TX_ASM_CALL; /* We want an assembly function, not C */ + + if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, + sub_len, inv, scale))) + return ret; + + if ((ret = ff_tx_gen_compound_mapping(s, opts, s->inv, cd->factors[0], sub_len))) + return ret; + + if (cd->factors[0] == 15) { + int tmp[15]; + + /* Our 15-point transform is also a compound one, so embed its input map */ + TX_EMBED_INPUT_PFA_MAP(s->map, len, 3, 5); + + /* Special permutation to simplify loads in the pre-permuted version */ + for (int k = 0; k < s->sub[0].len; k++) { + int cnt = 0; + memcpy(tmp, &s->map[k*15], 15*sizeof(*tmp)); + for (int i = 1; i < 15; i += 3) { + s->map[k*15 + cnt] = tmp[i]; + cnt++; + } + for (int i = 2; i < 15; i += 3) { + s->map[k*15 + cnt] = tmp[i]; + cnt++; + } + for (int i = 0; i < 15; i += 3) { + s->map[k*15 + cnt] = tmp[i]; + cnt++; + } + memmove(&s->map[k*15 + 7], &s->map[k*15 + 6], 4*sizeof(int)); + memmove(&s->map[k*15 + 3], &s->map[k*15 + 1], 4*sizeof(int)); + s->map[k*15 + 1] = tmp[2]; + s->map[k*15 + 2] = tmp[0]; + } + } + + if (!(s->tmp = av_malloc(len*sizeof(*s->tmp)))) + return AVERROR(ENOMEM); + + TX_TAB(ff_tx_init_tabs)(len / sub_len); + + return 0; +} + +const FFTXCodelet * const ff_tx_codelet_list_float_x86[] = { + TX_DEF(fft2, FFT, 2, 2, 2, 0, 128, NULL, sse3, SSE3, AV_TX_INPLACE, 0), + TX_DEF(fft2_asm, FFT, 2, 2, 2, 0, 192, b8_i0, sse3, SSE3, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0), + TX_DEF(fft2, FFT, 2, 2, 2, 0, 192, b8_i0, sse3, SSE3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2, AV_TX_INPLACE | FF_TX_FORWARD_ONLY, 0), + TX_DEF(fft4_fwd_asm, FFT, 4, 4, 2, 0, 192, b8_i0, sse2, SSE2, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0), + TX_DEF(fft4_inv_asm, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2, + AV_TX_INPLACE | FF_TX_INVERSE_ONLY | FF_TX_ASM_CALL, 0), + TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 192, b8_i0, sse2, SSE2, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft4_inv, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2, AV_TX_INPLACE | FF_TX_INVERSE_ONLY, 0), + TX_DEF(fft8, FFT, 8, 8, 2, 0, 128, b8_i0, sse3, SSE3, AV_TX_INPLACE, 0), + TX_DEF(fft8_asm, FFT, 8, 8, 2, 0, 192, b8_i0, sse3, SSE3, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0), + TX_DEF(fft8_ns, FFT, 8, 8, 2, 0, 192, b8_i0, sse3, SSE3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0), + TX_DEF(fft8, FFT, 8, 8, 2, 0, 256, b8_i0, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft8_asm, FFT, 8, 8, 2, 0, 320, b8_i0, avx, AVX, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft8_ns, FFT, 8, 8, 2, 0, 320, b8_i0, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16, FFT, 16, 16, 2, 0, 256, b8_i2, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16_asm, FFT, 16, 16, 2, 0, 320, b8_i2, avx, AVX, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16_ns, FFT, 16, 16, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16, FFT, 16, 16, 2, 0, 288, b8_i2, fma3, FMA3, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16_asm, FFT, 16, 16, 2, 0, 352, b8_i2, fma3, FMA3, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft16_ns, FFT, 16, 16, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + +#if ARCH_X86_64 + TX_DEF(fft32, FFT, 32, 32, 2, 0, 256, b8_i2, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft32_asm, FFT, 32, 32, 2, 0, 320, b8_i2, avx, AVX, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft32, FFT, 32, 32, 2, 0, 288, b8_i2, fma3, FMA3, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft32_asm, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 256, b8_i2, avx, AVX, 0, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 288, b8_i2, fma3, FMA3, 0, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW), + +#if HAVE_AVX2_EXTERNAL + TX_DEF(fft15, FFT, 15, 15, 15, 0, 320, factor_init, avx2, AVX2, + AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW), + TX_DEF(fft15_ns, FFT, 15, 15, 15, 0, 384, factor_init, avx2, AVX2, + AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW), + + TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 320, b8_i2, avx2, AVX2, 0, + AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE, + AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + + TX_DEF(fft_pfa_15xM, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 320, fft_pfa_init, avx2, AVX2, + AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + TX_DEF(fft_pfa_15xM_asm, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2, + AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + TX_DEF(fft_pfa_15xM_ns, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2, + AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), + + TX_DEF(mdct_inv, MDCT, 16, TX_LEN_UNLIMITED, 2, TX_FACTOR_ANY, 384, m_inv_init, avx2, AVX2, + FF_TX_INVERSE_ONLY, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER), +#endif +#endif + + NULL, +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/w64xmmtest.h b/arm/raspi/third_party/ffmpeg/libavutil/x86/w64xmmtest.h new file mode 100644 index 00000000..a4a05b04 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/w64xmmtest.h @@ -0,0 +1,78 @@ +/* + * check XMM registers for clobbers on Win64 + * Copyright (c) 2008 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_W64XMMTEST_H +#define AVUTIL_X86_W64XMMTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storexmmregs(mem) \ + __asm__ volatile( \ + "movups %%xmm6 , 0x00(%0)\n\t" \ + "movups %%xmm7 , 0x10(%0)\n\t" \ + "movups %%xmm8 , 0x20(%0)\n\t" \ + "movups %%xmm9 , 0x30(%0)\n\t" \ + "movups %%xmm10, 0x40(%0)\n\t" \ + "movups %%xmm11, 0x50(%0)\n\t" \ + "movups %%xmm12, 0x60(%0)\n\t" \ + "movups %%xmm13, 0x70(%0)\n\t" \ + "movups %%xmm14, 0x80(%0)\n\t" \ + "movups %%xmm15, 0x90(%0)\n\t" \ + :: "r"(mem) : "memory") + +#define testxmmclobbers(func, ctx, ...) \ + uint64_t xmm[2][10][2]; \ + int ret; \ + storexmmregs(xmm[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storexmmregs(xmm[1]); \ + if (memcmp(xmm[0], xmm[1], sizeof(xmm[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "XMM REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 10; i ++) \ + if (xmm[0][i][0] != xmm[1][i][0] || \ + xmm[0][i][1] != xmm[1][i][1]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "xmm%-2d = %016"PRIx64"%016"PRIx64"\n", \ + 6 + i, av_bswap64(xmm[0][i][0]), \ + av_bswap64(xmm[0][i][1])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"%016"PRIx64"\n", \ + av_bswap64(xmm[1][i][0]), \ + av_bswap64(xmm[1][i][1])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_X86_W64XMMTEST_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/x86inc.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/x86inc.asm new file mode 100644 index 00000000..ae9c1a1c --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/x86inc.asm @@ -0,0 +1,1738 @@ +;***************************************************************************** +;* x86inc.asm: x264asm abstraction layer +;***************************************************************************** +;* Copyright (C) 2005-2018 x264 project +;* +;* Authors: Loren Merritt +;* Henrik Gramner +;* Anton Mitrofanov +;* Fiona Glaser +;* +;* Permission to use, copy, modify, and/or distribute this software for any +;* purpose with or without fee is hereby granted, provided that the above +;* copyright notice and this permission notice appear in all copies. +;* +;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +;***************************************************************************** + +; This is a header file for the x264ASM assembly language, which uses +; NASM/YASM syntax combined with a large number of macros to provide easy +; abstraction between different calling conventions (x86_32, win64, linux64). +; It also has various other useful features to simplify writing the kind of +; DSP functions that are most often used in x264. + +; Unlike the rest of x264, this file is available under an ISC license, as it +; has significant usefulness outside of x264 and we want it to be available +; to the largest audience possible. Of course, if you modify it for your own +; purposes to add a new feature, we strongly encourage contributing a patch +; as this feature might be useful for others as well. Send patches or ideas +; to x264-devel@videolan.org . + +%ifndef private_prefix + %define private_prefix x264 +%endif + +%ifndef public_prefix + %define public_prefix private_prefix +%endif + +%if HAVE_ALIGNED_STACK + %define STACK_ALIGNMENT 16 +%endif +%ifndef STACK_ALIGNMENT + %if ARCH_X86_64 + %define STACK_ALIGNMENT 16 + %else + %define STACK_ALIGNMENT 4 + %endif +%endif + +%define WIN64 0 +%define UNIX64 0 +%if ARCH_X86_64 + %ifidn __OUTPUT_FORMAT__,win32 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,win64 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,x64 + %define WIN64 1 + %else + %define UNIX64 1 + %endif +%endif + +%define FORMAT_ELF 0 +%ifidn __OUTPUT_FORMAT__,elf + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf32 + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf64 + %define FORMAT_ELF 1 +%endif + +%ifdef PREFIX + %define mangle(x) _ %+ x +%else + %define mangle(x) x +%endif + +; aout does not support align= +; NOTE: This section is out of sync with x264, in order to +; keep supporting OS/2. +%macro SECTION_RODATA 0-1 16 + %ifidn __OUTPUT_FORMAT__,aout + SECTION .text + %elifidn __OUTPUT_FORMAT__,coff + SECTION .text + %elifidn __OUTPUT_FORMAT__,win32 + SECTION .rdata align=%1 + %elif WIN64 + SECTION .rdata align=%1 + %else + SECTION .rodata align=%1 + %endif +%endmacro + +%if WIN64 + %define PIC +%elif ARCH_X86_64 == 0 +; x86_32 doesn't require PIC. +; Some distros prefer shared objects to be PIC, but nothing breaks if +; the code contains a few textrels, so we'll skip that complexity. + %undef PIC +%endif +%ifdef PIC + default rel +%endif + +%macro CPUNOP 1 + %if HAVE_CPUNOP + CPU %1 + %endif +%endmacro + +; Macros to eliminate most code duplication between x86_32 and x86_64: +; Currently this works only for leaf functions which load all their arguments +; into registers at the start, and make no other use of the stack. Luckily that +; covers most of x264's asm. + +; PROLOGUE: +; %1 = number of arguments. loads them from stack if needed. +; %2 = number of registers used. pushes callee-saved regs if needed. +; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed. +; %4 = (optional) stack size to be allocated. The stack will be aligned before +; allocating the specified stack size. If the required stack alignment is +; larger than the known stack alignment the stack will be manually aligned +; and an extra register will be allocated to hold the original stack +; pointer (to not invalidate r0m etc.). To prevent the use of an extra +; register as stack pointer, request a negative stack size. +; %4+/%5+ = list of names to define to registers +; PROLOGUE can also be invoked by adding the same options to cglobal + +; e.g. +; cglobal foo, 2,3,7,0x40, dst, src, tmp +; declares a function (foo) that automatically loads two arguments (dst and +; src) into registers, uses one additional register (tmp) plus 7 vector +; registers (m0-m6) and allocates 0x40 bytes of stack space. + +; TODO Some functions can use some args directly from the stack. If they're the +; last args then you can just not declare them, but if they're in the middle +; we need more flexible macro. + +; RET: +; Pops anything that was pushed by PROLOGUE, and returns. + +; REP_RET: +; Use this instead of RET if it's a branch target. + +; registers: +; rN and rNq are the native-size register holding function argument N +; rNd, rNw, rNb are dword, word, and byte size +; rNh is the high 8 bits of the word size +; rNm is the original location of arg N (a register or on the stack), dword +; rNmp is native size + +%macro DECLARE_REG 2-3 + %define r%1q %2 + %define r%1d %2d + %define r%1w %2w + %define r%1b %2b + %define r%1h %2h + %define %2q %2 + %if %0 == 2 + %define r%1m %2d + %define r%1mp %2 + %elif ARCH_X86_64 ; memory + %define r%1m [rstk + stack_offset + %3] + %define r%1mp qword r %+ %1 %+ m + %else + %define r%1m [rstk + stack_offset + %3] + %define r%1mp dword r %+ %1 %+ m + %endif + %define r%1 %2 +%endmacro + +%macro DECLARE_REG_SIZE 3 + %define r%1q r%1 + %define e%1q r%1 + %define r%1d e%1 + %define e%1d e%1 + %define r%1w %1 + %define e%1w %1 + %define r%1h %3 + %define e%1h %3 + %define r%1b %2 + %define e%1b %2 + %if ARCH_X86_64 == 0 + %define r%1 e%1 + %endif +%endmacro + +DECLARE_REG_SIZE ax, al, ah +DECLARE_REG_SIZE bx, bl, bh +DECLARE_REG_SIZE cx, cl, ch +DECLARE_REG_SIZE dx, dl, dh +DECLARE_REG_SIZE si, sil, null +DECLARE_REG_SIZE di, dil, null +DECLARE_REG_SIZE bp, bpl, null + +; t# defines for when per-arch register allocation is more complex than just function arguments + +%macro DECLARE_REG_TMP 1-* + %assign %%i 0 + %rep %0 + CAT_XDEFINE t, %%i, r%1 + %assign %%i %%i+1 + %rotate 1 + %endrep +%endmacro + +%macro DECLARE_REG_TMP_SIZE 0-* + %rep %0 + %define t%1q t%1 %+ q + %define t%1d t%1 %+ d + %define t%1w t%1 %+ w + %define t%1h t%1 %+ h + %define t%1b t%1 %+ b + %rotate 1 + %endrep +%endmacro + +DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 + +%if ARCH_X86_64 + %define gprsize 8 +%else + %define gprsize 4 +%endif + +%macro PUSH 1 + push %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset+gprsize + %endif +%endmacro + +%macro POP 1 + pop %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset-gprsize + %endif +%endmacro + +%macro PUSH_IF_USED 1-* + %rep %0 + %if %1 < regs_used + PUSH r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro POP_IF_USED 1-* + %rep %0 + %if %1 < regs_used + pop r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro LOAD_IF_USED 1-* + %rep %0 + %if %1 < num_args + mov r%1, r %+ %1 %+ mp + %endif + %rotate 1 + %endrep +%endmacro + +%macro SUB 2 + sub %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset+(%2) + %endif +%endmacro + +%macro ADD 2 + add %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset-(%2) + %endif +%endmacro + +%macro movifnidn 2 + %ifnidn %1, %2 + mov %1, %2 + %endif +%endmacro + +%macro movsxdifnidn 2 + %ifnidn %1, %2 + movsxd %1, %2 + %endif +%endmacro + +%macro ASSERT 1 + %if (%1) == 0 + %error assertion ``%1'' failed + %endif +%endmacro + +%macro DEFINE_ARGS 0-* + %ifdef n_arg_names + %assign %%i 0 + %rep n_arg_names + CAT_UNDEF arg_name %+ %%i, q + CAT_UNDEF arg_name %+ %%i, d + CAT_UNDEF arg_name %+ %%i, w + CAT_UNDEF arg_name %+ %%i, h + CAT_UNDEF arg_name %+ %%i, b + CAT_UNDEF arg_name %+ %%i, m + CAT_UNDEF arg_name %+ %%i, mp + CAT_UNDEF arg_name, %%i + %assign %%i %%i+1 + %endrep + %endif + + %xdefine %%stack_offset stack_offset + %undef stack_offset ; so that the current value of stack_offset doesn't get baked in by xdefine + %assign %%i 0 + %rep %0 + %xdefine %1q r %+ %%i %+ q + %xdefine %1d r %+ %%i %+ d + %xdefine %1w r %+ %%i %+ w + %xdefine %1h r %+ %%i %+ h + %xdefine %1b r %+ %%i %+ b + %xdefine %1m r %+ %%i %+ m + %xdefine %1mp r %+ %%i %+ mp + CAT_XDEFINE arg_name, %%i, %1 + %assign %%i %%i+1 + %rotate 1 + %endrep + %xdefine stack_offset %%stack_offset + %assign n_arg_names %0 +%endmacro + +%define required_stack_alignment ((mmsize + 15) & ~15) +%define vzeroupper_required (mmsize > 16 && (ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) +%define high_mm_regs (16*cpuflag(avx512)) + +%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) + %ifnum %1 + %if %1 != 0 + %assign %%pad 0 + %assign stack_size %1 + %if stack_size < 0 + %assign stack_size -stack_size + %endif + %if WIN64 + %assign %%pad %%pad + 32 ; shadow space + %if mmsize != 8 + %assign xmm_regs_used %2 + %if xmm_regs_used > 8 + %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers + %endif + %endif + %endif + %if required_stack_alignment <= STACK_ALIGNMENT + ; maintain the current stack alignment + %assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %else + %assign %%reg_num (regs_used - 1) + %xdefine rstk r %+ %%reg_num + ; align stack, and save original stack location directly above + ; it, i.e. in [rsp+stack_size_padded], so we can restore the + ; stack in a single instruction (i.e. mov rsp, rstk or mov + ; rsp, [rsp+stack_size_padded]) + %if %1 < 0 ; need to store rsp on stack + %xdefine rstkm [rsp + stack_size + %%pad] + %assign %%pad %%pad + gprsize + %else ; can keep rsp in rstk during whole function + %xdefine rstkm rstk + %endif + %assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1)) + mov rstk, rsp + and rsp, ~(required_stack_alignment-1) + sub rsp, stack_size_padded + movifnidn rstkm, rstk + %endif + WIN64_PUSH_XMM + %endif + %endif +%endmacro + +%macro SETUP_STACK_POINTER 1 + %ifnum %1 + %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT + %if %1 > 0 + ; Reserve an additional register for storing the original stack pointer, but avoid using + ; eax/rax for this purpose since it can potentially get overwritten as a return value. + %assign regs_used (regs_used + 1) + %if ARCH_X86_64 && regs_used == 7 + %assign regs_used 8 + %elif ARCH_X86_64 == 0 && regs_used == 1 + %assign regs_used 2 + %endif + %endif + %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 + ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) + ; since it's used as a hidden argument in vararg functions to specify the number of vector registers used. + %assign regs_used 5 + UNIX64 * 3 + %endif + %endif + %endif +%endmacro + +%if WIN64 ; Windows x64 ;================================================= + +DECLARE_REG 0, rcx +DECLARE_REG 1, rdx +DECLARE_REG 2, R8 +DECLARE_REG 3, R9 +DECLARE_REG 4, R10, 40 +DECLARE_REG 5, R11, 48 +DECLARE_REG 6, rax, 56 +DECLARE_REG 7, rdi, 64 +DECLARE_REG 8, rsi, 72 +DECLARE_REG 9, rbx, 80 +DECLARE_REG 10, rbp, 88 +DECLARE_REG 11, R14, 96 +DECLARE_REG 12, R15, 104 +DECLARE_REG 13, R12, 112 +DECLARE_REG 14, R13, 120 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4, %3 + %if mmsize != 8 && stack_size == 0 + WIN64_SPILL_XMM %3 + %endif + LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%macro WIN64_PUSH_XMM 0 + ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. + %if xmm_regs_used > 6 + high_mm_regs + movaps [rstk + stack_offset + 8], xmm6 + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps [rstk + stack_offset + 24], xmm7 + %endif + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i 8 + %rep %%xmm_regs_on_stack + movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro WIN64_SPILL_XMM 1 + %assign xmm_regs_used %1 + ASSERT xmm_regs_used <= 16 + high_mm_regs + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. + %assign %%pad %%xmm_regs_on_stack*16 + 32 + %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %endif + WIN64_PUSH_XMM +%endmacro + +%macro WIN64_RESTORE_XMM_INTERNAL 0 + %assign %%pad_size 0 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i xmm_regs_used - high_mm_regs + %rep %%xmm_regs_on_stack + %assign %%i %%i-1 + movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] + %endrep + %endif + %if stack_size_padded > 0 + %if stack_size > 0 && required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %assign %%pad_size stack_size_padded + %endif + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps xmm7, [rsp + stack_offset - %%pad_size + 24] + %endif + %if xmm_regs_used > 6 + high_mm_regs + movaps xmm6, [rsp + stack_offset - %%pad_size + 8] + %endif +%endmacro + +%macro WIN64_RESTORE_XMM 0 + WIN64_RESTORE_XMM_INTERNAL + %assign stack_offset (stack_offset-stack_size_padded) + %assign stack_size_padded 0 + %assign xmm_regs_used 0 +%endmacro + +%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs + +%macro RET 0 + WIN64_RESTORE_XMM_INTERNAL + POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%elif ARCH_X86_64 ; *nix x64 ;============================================= + +DECLARE_REG 0, rdi +DECLARE_REG 1, rsi +DECLARE_REG 2, rdx +DECLARE_REG 3, rcx +DECLARE_REG 4, R8 +DECLARE_REG 5, R9 +DECLARE_REG 6, rax, 8 +DECLARE_REG 7, R10, 16 +DECLARE_REG 8, R11, 24 +DECLARE_REG 9, rbx, 32 +DECLARE_REG 10, rbp, 40 +DECLARE_REG 11, R14, 48 +DECLARE_REG 12, R15, 56 +DECLARE_REG 13, R12, 64 +DECLARE_REG 14, R13, 72 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + %assign xmm_regs_used %3 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4 + LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 14, 13, 12, 11, 10, 9 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%else ; X86_32 ;============================================================== + +DECLARE_REG 0, eax, 4 +DECLARE_REG 1, ecx, 8 +DECLARE_REG 2, edx, 12 +DECLARE_REG 3, ebx, 16 +DECLARE_REG 4, esi, 20 +DECLARE_REG 5, edi, 24 +DECLARE_REG 6, ebp, 28 +%define rsp esp + +%macro DECLARE_ARG 1-* + %rep %0 + %define r%1m [rstk + stack_offset + 4*%1 + 4] + %define r%1mp dword r%1m + %rotate 1 + %endrep +%endmacro + +DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + %if num_args > 7 + %assign num_args 7 + %endif + %if regs_used > 7 + %assign regs_used 7 + %endif + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 7 + PUSH_IF_USED 3, 4, 5, 6 + ALLOC_STACK %4 + LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 6, 5, 4, 3 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%endif ;====================================================================== + +%if WIN64 == 0 + %macro WIN64_SPILL_XMM 1 + %endmacro + %macro WIN64_RESTORE_XMM 0 + %endmacro + %macro WIN64_PUSH_XMM 0 + %endmacro +%endif + +; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either +; a branch or a branch target. So switch to a 2-byte form of ret in that case. +; We can automatically detect "follows a branch", but not a branch target. +; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.) +%macro REP_RET 0 + %if has_epilogue || cpuflag(ssse3) + RET + %else + rep ret + %endif + annotate_function_size +%endmacro + +%define last_branch_adr $$ +%macro AUTO_REP_RET 0 + %if notcpuflag(ssse3) + times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr. + %endif + ret + annotate_function_size +%endmacro + +%macro BRANCH_INSTR 0-* + %rep %0 + %macro %1 1-2 %1 + %2 %1 + %if notcpuflag(ssse3) + %%branch_instr equ $ + %xdefine last_branch_adr %%branch_instr + %endif + %endmacro + %rotate 1 + %endrep +%endmacro + +BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp + +%macro TAIL_CALL 2 ; callee, is_nonadjacent + %if has_epilogue + call %1 + RET + %elif %2 + jmp %1 + %endif + annotate_function_size +%endmacro + +;============================================================================= +; arch-independent part +;============================================================================= + +%assign function_align 16 + +; Begin a function. +; Applies any symbol mangling needed for C linkage, and sets up a define such that +; subsequent uses of the function name automatically refer to the mangled version. +; Appends cpuflags to the function name if cpuflags has been specified. +; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX +; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2). +%macro cglobal 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 1, %1 %+ SUFFIX, %2 +%endmacro +%macro cvisible 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 0, %1 %+ SUFFIX, %2 +%endmacro +%macro cglobal_internal 2-3+ + annotate_function_size + %if %1 + %xdefine %%FUNCTION_PREFIX private_prefix + ; Chromium patch to ensure symbols are correctly hidden for macho files, + ; normal yasm does not have a private_extern flag. + %ifidn __OUTPUT_FORMAT__,macho + %xdefine %%VISIBILITY private_extern + %elifidn __OUTPUT_FORMAT__,macho32 + %xdefine %%VISIBILITY private_extern + %elifidn __OUTPUT_FORMAT__,macho64 + %xdefine %%VISIBILITY private_extern + %else + %xdefine %%VISIBILITY hidden + %endif + %else + %xdefine %%FUNCTION_PREFIX public_prefix + %xdefine %%VISIBILITY + %endif + %ifndef cglobaled_%2 + %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2) + %xdefine %2.skip_prologue %2 %+ .skip_prologue + CAT_XDEFINE cglobaled_, %2, 1 + %endif + %xdefine current_function %2 + ; Chromium patch to ensure symbols are correctly hidden for macho files, + ; normal yasm does not have a private_extern flag. + %xdefine current_function_section __SECT__ + %if FORMAT_ELF + global %2:function %%VISIBILITY + %elifidn __OUTPUT_FORMAT__,elf32 + global %2:function %%VISIBILITY + %elifidn __OUTPUT_FORMAT__,elf64 + global %2:function %%VISIBILITY + %elifidn __OUTPUT_FORMAT__,macho + global %2:%%VISIBILITY + %elifidn __OUTPUT_FORMAT__,macho32 + global %2:%%VISIBILITY + %elifidn __OUTPUT_FORMAT__,macho64 + global %2:%%VISIBILITY + %else + global %2 + %endif + align function_align + %2: + RESET_MM_PERMUTATION ; needed for x86-64, also makes disassembly somewhat nicer + %xdefine rstk rsp ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required + %assign stack_offset 0 ; stack pointer offset relative to the return address + %assign stack_size 0 ; amount of stack space that can be freely used inside a function + %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding + %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper + %ifnidn %3, "" + PROLOGUE %3 + %endif +%endmacro + +; Create a global symbol from a local label with the correct name mangling and type +%macro cglobal_label 1 + %if FORMAT_ELF + global current_function %+ %1:function hidden + %else + global current_function %+ %1 + %endif + %1: +%endmacro + +%macro cextern 1 + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +; like cextern, but without the prefix +%macro cextern_naked 1 + %ifdef PREFIX + %xdefine %1 mangle(%1) + %endif + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +%macro const 1-2+ + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + %if FORMAT_ELF + global %1:data hidden + %else + global %1 + %endif + %1: %2 +%endmacro + +; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default. +%if FORMAT_ELF + [SECTION .note.GNU-stack noalloc noexec nowrite progbits] +%endif + +; Tell debuggers how large the function was. +; This may be invoked multiple times per function; we rely on later instances overriding earlier ones. +; This is invoked by RET and similar macros, and also cglobal does it for the previous function, +; but if the last function in a source file doesn't use any of the standard macros for its epilogue, +; then its size might be unspecified. +%macro annotate_function_size 0 + %ifdef __YASM_VER__ + %ifdef current_function + %if FORMAT_ELF + current_function_section + %%ecf equ $ + size current_function %%ecf - current_function + __SECT__ + %endif + %endif + %endif +%endmacro + +; cpuflags + +%assign cpuflags_mmx (1<<0) +%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx +%assign cpuflags_3dnow (1<<2) | cpuflags_mmx +%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow +%assign cpuflags_sse (1<<4) | cpuflags_mmx2 +%assign cpuflags_sse2 (1<<5) | cpuflags_sse +%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 +%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2 +%assign cpuflags_sse3 (1<<8) | cpuflags_sse2 +%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3 +%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3 +%assign cpuflags_sse42 (1<<11)| cpuflags_sse4 +%assign cpuflags_aesni (1<<12)| cpuflags_sse42 +%assign cpuflags_avx (1<<13)| cpuflags_sse42 +%assign cpuflags_xop (1<<14)| cpuflags_avx +%assign cpuflags_fma4 (1<<15)| cpuflags_avx +%assign cpuflags_fma3 (1<<16)| cpuflags_avx +%assign cpuflags_bmi1 (1<<17)| cpuflags_avx|cpuflags_lzcnt +%assign cpuflags_bmi2 (1<<18)| cpuflags_bmi1 +%assign cpuflags_avx2 (1<<19)| cpuflags_fma3|cpuflags_bmi2 +%assign cpuflags_avx512 (1<<20)| cpuflags_avx2 ; F, CD, BW, DQ, VL +%assign cpuflags_avx512icl (1<<25)| cpuflags_avx512 + +%assign cpuflags_cache32 (1<<21) +%assign cpuflags_cache64 (1<<22) +%assign cpuflags_aligned (1<<23) ; not a cpu feature, but a function variant +%assign cpuflags_atom (1<<24) + +; Returns a boolean value expressing whether or not the specified cpuflag is enabled. +%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1) +%define notcpuflag(x) (cpuflag(x) ^ 1) + +; Takes an arbitrary number of cpuflags from the above list. +; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu. +; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co. +%macro INIT_CPUFLAGS 0-* + %xdefine SUFFIX + %undef cpuname + %assign cpuflags 0 + + %if %0 >= 1 + %rep %0 + %ifdef cpuname + %xdefine cpuname cpuname %+ _%1 + %else + %xdefine cpuname %1 + %endif + %assign cpuflags cpuflags | cpuflags_%1 + %rotate 1 + %endrep + %xdefine SUFFIX _ %+ cpuname + + %if cpuflag(avx) + %assign avx_enabled 1 + %endif + %if (mmsize == 16 && notcpuflag(sse2)) || (mmsize == 32 && notcpuflag(avx2)) + %define mova movaps + %define movu movups + %define movnta movntps + %endif + %if cpuflag(aligned) + %define movu mova + %elif cpuflag(sse3) && notcpuflag(ssse3) + %define movu lddqu + %endif + %endif + + %if ARCH_X86_64 || cpuflag(sse2) + CPUNOP amdnop + %else + CPUNOP basicnop + %endif +%endmacro + +; Merge mmx, sse*, and avx* +; m# is a simd register of the currently selected size +; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# +; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# +; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# +; (All 4 remain in sync through SWAP.) + +%macro CAT_XDEFINE 3 + %xdefine %1%2 %3 +%endmacro + +%macro CAT_UNDEF 2 + %undef %1%2 +%endmacro + +%macro DEFINE_MMREGS 1 ; mmtype + %assign %%prev_mmregs 0 + %ifdef num_mmregs + %assign %%prev_mmregs num_mmregs + %endif + + %assign num_mmregs 8 + %if ARCH_X86_64 && mmsize >= 16 + %assign num_mmregs 16 + %if cpuflag(avx512) || mmsize == 64 + %assign num_mmregs 32 + %endif + %endif + + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1 %+ %%i + CAT_XDEFINE nn%1, %%i, %%i + %assign %%i %%i+1 + %endrep + %if %%prev_mmregs > num_mmregs + %rep %%prev_mmregs - num_mmregs + CAT_UNDEF m, %%i + CAT_UNDEF nn %+ mmtype, %%i + %assign %%i %%i+1 + %endrep + %endif + %xdefine mmtype %1 +%endmacro + +; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper +%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg + %if ARCH_X86_64 && cpuflag(avx512) + %assign %%i %1 + %rep 16-%1 + %assign %%i_high %%i+16 + SWAP %%i, %%i_high + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro INIT_MMX 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_MMX %1 + %define mmsize 8 + %define mova movq + %define movu movq + %define movh movd + %define movnta movntq + INIT_CPUFLAGS %1 + DEFINE_MMREGS mm +%endmacro + +%macro INIT_XMM 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_XMM %1 + %define mmsize 16 + %define mova movdqa + %define movu movdqu + %define movh movq + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS xmm + %if WIN64 + AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers + %endif +%endmacro + +%macro INIT_YMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_YMM %1 + %define mmsize 32 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS ymm + AVX512_MM_PERMUTATION +%endmacro + +%macro INIT_ZMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_ZMM %1 + %define mmsize 64 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS zmm + AVX512_MM_PERMUTATION +%endmacro + +INIT_XMM + +%macro DECLARE_MMCAST 1 + %define mmmm%1 mm%1 + %define mmxmm%1 mm%1 + %define mmymm%1 mm%1 + %define mmzmm%1 mm%1 + %define xmmmm%1 mm%1 + %define xmmxmm%1 xmm%1 + %define xmmymm%1 xmm%1 + %define xmmzmm%1 xmm%1 + %define ymmmm%1 mm%1 + %define ymmxmm%1 xmm%1 + %define ymmymm%1 ymm%1 + %define ymmzmm%1 ymm%1 + %define zmmmm%1 mm%1 + %define zmmxmm%1 xmm%1 + %define zmmymm%1 ymm%1 + %define zmmzmm%1 zmm%1 + %define xm%1 xmm %+ m%1 + %define ym%1 ymm %+ m%1 + %define zm%1 zmm %+ m%1 +%endmacro + +%assign i 0 +%rep 32 + DECLARE_MMCAST i + %assign i i+1 +%endrep + +; I often want to use macros that permute their arguments. e.g. there's no +; efficient way to implement butterfly or transpose or dct without swapping some +; arguments. +; +; I would like to not have to manually keep track of the permutations: +; If I insert a permutation in the middle of a function, it should automatically +; change everything that follows. For more complex macros I may also have multiple +; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations. +; +; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that +; permutes its arguments. It's equivalent to exchanging the contents of the +; registers, except that this way you exchange the register names instead, so it +; doesn't cost any cycles. + +%macro PERMUTE 2-* ; takes a list of pairs to swap + %rep %0/2 + %xdefine %%tmp%2 m%2 + %rotate 2 + %endrep + %rep %0/2 + %xdefine m%1 %%tmp%2 + CAT_XDEFINE nn, m%1, %1 + %rotate 2 + %endrep +%endmacro + +%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs) + %ifnum %1 ; SWAP 0, 1, ... + SWAP_INTERNAL_NUM %1, %2 + %else ; SWAP m0, m1, ... + SWAP_INTERNAL_NAME %1, %2 + %endif +%endmacro + +%macro SWAP_INTERNAL_NUM 2-* + %rep %0-1 + %xdefine %%tmp m%1 + %xdefine m%1 m%2 + %xdefine m%2 %%tmp + CAT_XDEFINE nn, m%1, %1 + CAT_XDEFINE nn, m%2, %2 + %rotate 1 + %endrep +%endmacro + +%macro SWAP_INTERNAL_NAME 2-* + %xdefine %%args nn %+ %1 + %rep %0-1 + %xdefine %%args %%args, nn %+ %2 + %rotate 1 + %endrep + SWAP_INTERNAL_NUM %%args +%endmacro + +; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later +; calls to that function will automatically load the permutation, so values can +; be returned in mmregs. +%macro SAVE_MM_PERMUTATION 0-1 + %if %0 + %xdefine %%f %1_m + %else + %xdefine %%f current_function %+ _m + %endif + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE %%f, %%i, m %+ %%i + %assign %%i %%i+1 + %endrep +%endmacro + +%macro LOAD_MM_PERMUTATION 1 ; name to load from + %ifdef %1_m0 + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1_m %+ %%i + CAT_XDEFINE nn, m %+ %%i, %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't +%macro call 1 + %ifid %1 + call_internal %1 %+ SUFFIX, %1 + %else + call %1 + %endif +%endmacro +%macro call_internal 2 + %xdefine %%i %2 + %ifndef cglobaled_%2 + %ifdef cglobaled_%1 + %xdefine %%i %1 + %endif + %endif + call %%i + LOAD_MM_PERMUTATION %%i +%endmacro + +; Substitutions that reduce instruction size but are functionally equivalent +%macro add 2 + %ifnum %2 + %if %2==128 + sub %1, -128 + %else + add %1, %2 + %endif + %else + add %1, %2 + %endif +%endmacro + +%macro sub 2 + %ifnum %2 + %if %2==128 + add %1, -128 + %else + sub %1, %2 + %endif + %else + sub %1, %2 + %endif +%endmacro + +;============================================================================= +; AVX abstraction layer +;============================================================================= + +%assign i 0 +%rep 32 + %if i < 8 + CAT_XDEFINE sizeofmm, i, 8 + CAT_XDEFINE regnumofmm, i, i + %endif + CAT_XDEFINE sizeofxmm, i, 16 + CAT_XDEFINE sizeofymm, i, 32 + CAT_XDEFINE sizeofzmm, i, 64 + CAT_XDEFINE regnumofxmm, i, i + CAT_XDEFINE regnumofymm, i, i + CAT_XDEFINE regnumofzmm, i, i + %assign i i+1 +%endrep +%undef i + +%macro CHECK_AVX_INSTR_EMU 3-* + %xdefine %%opcode %1 + %xdefine %%dst %2 + %rep %0-2 + %ifidn %%dst, %3 + %error non-avx emulation of ``%%opcode'' is not supported + %endif + %rotate 1 + %endrep +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +;%6+: operands +%macro RUN_AVX_INSTR 6-9+ + %ifnum sizeof%7 + %assign __sizeofreg sizeof%7 + %elifnum sizeof%6 + %assign __sizeofreg sizeof%6 + %else + %assign __sizeofreg mmsize + %endif + %assign __emulate_avx 0 + %if avx_enabled && __sizeofreg >= 16 + %xdefine __instr v%1 + %else + %xdefine __instr %1 + %if %0 >= 8+%4 + %assign __emulate_avx 1 + %endif + %endif + %ifnidn %2, fnord + %ifdef cpuname + %if notcpuflag(%2) + %error use of ``%1'' %2 instruction in cpuname function: current_function + %elif cpuflags_%2 < cpuflags_sse && notcpuflag(sse2) && __sizeofreg > 8 + %error use of ``%1'' sse2 instruction in cpuname function: current_function + %endif + %endif + %endif + + %if __emulate_avx + %xdefine __src1 %7 + %xdefine __src2 %8 + %if %5 && %4 == 0 + %ifnidn %6, %7 + %ifidn %6, %8 + %xdefine __src1 %8 + %xdefine __src2 %7 + %elifnnum sizeof%8 + ; 3-operand AVX instructions with a memory arg can only have it in src2, + ; whereas SSE emulation prefers to have it in src1 (i.e. the mov). + ; So, if the instruction is commutative with a memory arg, swap them. + %xdefine __src1 %8 + %xdefine __src2 %7 + %endif + %endif + %endif + %ifnidn %6, __src1 + %if %0 >= 9 + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, __src2, %9 + %else + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, __src2 + %endif + %if __sizeofreg == 8 + MOVQ %6, __src1 + %elif %3 + MOVAPS %6, __src1 + %else + MOVDQA %6, __src1 + %endif + %endif + %if %0 >= 9 + %1 %6, __src2, %9 + %else + %1 %6, __src2 + %endif + %elif %0 >= 9 + __instr %6, %7, %8, %9 + %elif %0 == 8 + __instr %6, %7, %8 + %elif %0 == 7 + __instr %6, %7 + %else + __instr %6 + %endif +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +%macro AVX_INSTR 1-5 fnord, 0, 255, 0 + %macro %1 1-10 fnord, fnord, fnord, fnord, %1, %2, %3, %4, %5 + %ifidn %2, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1 + %elifidn %3, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2 + %elifidn %4, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3 + %elifidn %5, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4 + %else + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4, %5 + %endif + %endmacro +%endmacro + +; Instructions with both VEX/EVEX and legacy encodings +; Non-destructive instructions are written without parameters +AVX_INSTR addpd, sse2, 1, 0, 1 +AVX_INSTR addps, sse, 1, 0, 1 +AVX_INSTR addsd, sse2, 1, 0, 0 +AVX_INSTR addss, sse, 1, 0, 0 +AVX_INSTR addsubpd, sse3, 1, 0, 0 +AVX_INSTR addsubps, sse3, 1, 0, 0 +AVX_INSTR aesdec, aesni, 0, 0, 0 +AVX_INSTR aesdeclast, aesni, 0, 0, 0 +AVX_INSTR aesenc, aesni, 0, 0, 0 +AVX_INSTR aesenclast, aesni, 0, 0, 0 +AVX_INSTR aesimc, aesni +AVX_INSTR aeskeygenassist, aesni +AVX_INSTR andnpd, sse2, 1, 0, 0 +AVX_INSTR andnps, sse, 1, 0, 0 +AVX_INSTR andpd, sse2, 1, 0, 1 +AVX_INSTR andps, sse, 1, 0, 1 +AVX_INSTR blendpd, sse4, 1, 1, 0 +AVX_INSTR blendps, sse4, 1, 1, 0 +AVX_INSTR blendvpd, sse4 ; can't be emulated +AVX_INSTR blendvps, sse4 ; can't be emulated +AVX_INSTR cmpeqpd, sse2, 1, 0, 1 +AVX_INSTR cmpeqps, sse, 1, 0, 1 +AVX_INSTR cmpeqsd, sse2, 1, 0, 0 +AVX_INSTR cmpeqss, sse, 1, 0, 0 +AVX_INSTR cmplepd, sse2, 1, 0, 0 +AVX_INSTR cmpleps, sse, 1, 0, 0 +AVX_INSTR cmplesd, sse2, 1, 0, 0 +AVX_INSTR cmpless, sse, 1, 0, 0 +AVX_INSTR cmpltpd, sse2, 1, 0, 0 +AVX_INSTR cmpltps, sse, 1, 0, 0 +AVX_INSTR cmpltsd, sse2, 1, 0, 0 +AVX_INSTR cmpltss, sse, 1, 0, 0 +AVX_INSTR cmpneqpd, sse2, 1, 0, 1 +AVX_INSTR cmpneqps, sse, 1, 0, 1 +AVX_INSTR cmpneqsd, sse2, 1, 0, 0 +AVX_INSTR cmpneqss, sse, 1, 0, 0 +AVX_INSTR cmpnlepd, sse2, 1, 0, 0 +AVX_INSTR cmpnleps, sse, 1, 0, 0 +AVX_INSTR cmpnlesd, sse2, 1, 0, 0 +AVX_INSTR cmpnless, sse, 1, 0, 0 +AVX_INSTR cmpnltpd, sse2, 1, 0, 0 +AVX_INSTR cmpnltps, sse, 1, 0, 0 +AVX_INSTR cmpnltsd, sse2, 1, 0, 0 +AVX_INSTR cmpnltss, sse, 1, 0, 0 +AVX_INSTR cmpordpd, sse2 1, 0, 1 +AVX_INSTR cmpordps, sse 1, 0, 1 +AVX_INSTR cmpordsd, sse2 1, 0, 0 +AVX_INSTR cmpordss, sse 1, 0, 0 +AVX_INSTR cmppd, sse2, 1, 1, 0 +AVX_INSTR cmpps, sse, 1, 1, 0 +AVX_INSTR cmpsd, sse2, 1, 1, 0 +AVX_INSTR cmpss, sse, 1, 1, 0 +AVX_INSTR cmpunordpd, sse2, 1, 0, 1 +AVX_INSTR cmpunordps, sse, 1, 0, 1 +AVX_INSTR cmpunordsd, sse2, 1, 0, 0 +AVX_INSTR cmpunordss, sse, 1, 0, 0 +AVX_INSTR comisd, sse2 +AVX_INSTR comiss, sse +AVX_INSTR cvtdq2pd, sse2 +AVX_INSTR cvtdq2ps, sse2 +AVX_INSTR cvtpd2dq, sse2 +AVX_INSTR cvtpd2ps, sse2 +AVX_INSTR cvtps2dq, sse2 +AVX_INSTR cvtps2pd, sse2 +AVX_INSTR cvtsd2si, sse2 +AVX_INSTR cvtsd2ss, sse2, 1, 0, 0 +AVX_INSTR cvtsi2sd, sse2, 1, 0, 0 +AVX_INSTR cvtsi2ss, sse, 1, 0, 0 +AVX_INSTR cvtss2sd, sse2, 1, 0, 0 +AVX_INSTR cvtss2si, sse +AVX_INSTR cvttpd2dq, sse2 +AVX_INSTR cvttps2dq, sse2 +AVX_INSTR cvttsd2si, sse2 +AVX_INSTR cvttss2si, sse +AVX_INSTR divpd, sse2, 1, 0, 0 +AVX_INSTR divps, sse, 1, 0, 0 +AVX_INSTR divsd, sse2, 1, 0, 0 +AVX_INSTR divss, sse, 1, 0, 0 +AVX_INSTR dppd, sse4, 1, 1, 0 +AVX_INSTR dpps, sse4, 1, 1, 0 +AVX_INSTR extractps, sse4 +AVX_INSTR haddpd, sse3, 1, 0, 0 +AVX_INSTR haddps, sse3, 1, 0, 0 +AVX_INSTR hsubpd, sse3, 1, 0, 0 +AVX_INSTR hsubps, sse3, 1, 0, 0 +AVX_INSTR insertps, sse4, 1, 1, 0 +AVX_INSTR lddqu, sse3 +AVX_INSTR ldmxcsr, sse +AVX_INSTR maskmovdqu, sse2 +AVX_INSTR maxpd, sse2, 1, 0, 1 +AVX_INSTR maxps, sse, 1, 0, 1 +AVX_INSTR maxsd, sse2, 1, 0, 0 +AVX_INSTR maxss, sse, 1, 0, 0 +AVX_INSTR minpd, sse2, 1, 0, 1 +AVX_INSTR minps, sse, 1, 0, 1 +AVX_INSTR minsd, sse2, 1, 0, 0 +AVX_INSTR minss, sse, 1, 0, 0 +AVX_INSTR movapd, sse2 +AVX_INSTR movaps, sse +AVX_INSTR movd, mmx +AVX_INSTR movddup, sse3 +AVX_INSTR movdqa, sse2 +AVX_INSTR movdqu, sse2 +AVX_INSTR movhlps, sse, 1, 0, 0 +AVX_INSTR movhpd, sse2, 1, 0, 0 +AVX_INSTR movhps, sse, 1, 0, 0 +AVX_INSTR movlhps, sse, 1, 0, 0 +AVX_INSTR movlpd, sse2, 1, 0, 0 +AVX_INSTR movlps, sse, 1, 0, 0 +AVX_INSTR movmskpd, sse2 +AVX_INSTR movmskps, sse +AVX_INSTR movntdq, sse2 +AVX_INSTR movntdqa, sse4 +AVX_INSTR movntpd, sse2 +AVX_INSTR movntps, sse +AVX_INSTR movq, mmx +AVX_INSTR movsd, sse2, 1, 0, 0 +AVX_INSTR movshdup, sse3 +AVX_INSTR movsldup, sse3 +AVX_INSTR movss, sse, 1, 0, 0 +AVX_INSTR movupd, sse2 +AVX_INSTR movups, sse +AVX_INSTR mpsadbw, sse4, 0, 1, 0 +AVX_INSTR mulpd, sse2, 1, 0, 1 +AVX_INSTR mulps, sse, 1, 0, 1 +AVX_INSTR mulsd, sse2, 1, 0, 0 +AVX_INSTR mulss, sse, 1, 0, 0 +AVX_INSTR orpd, sse2, 1, 0, 1 +AVX_INSTR orps, sse, 1, 0, 1 +AVX_INSTR pabsb, ssse3 +AVX_INSTR pabsd, ssse3 +AVX_INSTR pabsw, ssse3 +AVX_INSTR packsswb, mmx, 0, 0, 0 +AVX_INSTR packssdw, mmx, 0, 0, 0 +AVX_INSTR packuswb, mmx, 0, 0, 0 +AVX_INSTR packusdw, sse4, 0, 0, 0 +AVX_INSTR paddb, mmx, 0, 0, 1 +AVX_INSTR paddw, mmx, 0, 0, 1 +AVX_INSTR paddd, mmx, 0, 0, 1 +AVX_INSTR paddq, sse2, 0, 0, 1 +AVX_INSTR paddsb, mmx, 0, 0, 1 +AVX_INSTR paddsw, mmx, 0, 0, 1 +AVX_INSTR paddusb, mmx, 0, 0, 1 +AVX_INSTR paddusw, mmx, 0, 0, 1 +AVX_INSTR palignr, ssse3, 0, 1, 0 +AVX_INSTR pand, mmx, 0, 0, 1 +AVX_INSTR pandn, mmx, 0, 0, 0 +AVX_INSTR pavgb, mmx2, 0, 0, 1 +AVX_INSTR pavgw, mmx2, 0, 0, 1 +AVX_INSTR pblendvb, sse4 ; can't be emulated +AVX_INSTR pblendw, sse4, 0, 1, 0 +AVX_INSTR pclmulqdq, fnord, 0, 1, 0 +AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0 +AVX_INSTR pcmpestri, sse42 +AVX_INSTR pcmpestrm, sse42 +AVX_INSTR pcmpistri, sse42 +AVX_INSTR pcmpistrm, sse42 +AVX_INSTR pcmpeqb, mmx, 0, 0, 1 +AVX_INSTR pcmpeqw, mmx, 0, 0, 1 +AVX_INSTR pcmpeqd, mmx, 0, 0, 1 +AVX_INSTR pcmpeqq, sse4, 0, 0, 1 +AVX_INSTR pcmpgtb, mmx, 0, 0, 0 +AVX_INSTR pcmpgtw, mmx, 0, 0, 0 +AVX_INSTR pcmpgtd, mmx, 0, 0, 0 +AVX_INSTR pcmpgtq, sse42, 0, 0, 0 +AVX_INSTR pextrb, sse4 +AVX_INSTR pextrd, sse4 +AVX_INSTR pextrq, sse4 +AVX_INSTR pextrw, mmx2 +AVX_INSTR phaddw, ssse3, 0, 0, 0 +AVX_INSTR phaddd, ssse3, 0, 0, 0 +AVX_INSTR phaddsw, ssse3, 0, 0, 0 +AVX_INSTR phminposuw, sse4 +AVX_INSTR phsubw, ssse3, 0, 0, 0 +AVX_INSTR phsubd, ssse3, 0, 0, 0 +AVX_INSTR phsubsw, ssse3, 0, 0, 0 +AVX_INSTR pinsrb, sse4, 0, 1, 0 +AVX_INSTR pinsrd, sse4, 0, 1, 0 +AVX_INSTR pinsrq, sse4, 0, 1, 0 +AVX_INSTR pinsrw, mmx2, 0, 1, 0 +AVX_INSTR pmaddwd, mmx, 0, 0, 1 +AVX_INSTR pmaddubsw, ssse3, 0, 0, 0 +AVX_INSTR pmaxsb, sse4, 0, 0, 1 +AVX_INSTR pmaxsw, mmx2, 0, 0, 1 +AVX_INSTR pmaxsd, sse4, 0, 0, 1 +AVX_INSTR pmaxub, mmx2, 0, 0, 1 +AVX_INSTR pmaxuw, sse4, 0, 0, 1 +AVX_INSTR pmaxud, sse4, 0, 0, 1 +AVX_INSTR pminsb, sse4, 0, 0, 1 +AVX_INSTR pminsw, mmx2, 0, 0, 1 +AVX_INSTR pminsd, sse4, 0, 0, 1 +AVX_INSTR pminub, mmx2, 0, 0, 1 +AVX_INSTR pminuw, sse4, 0, 0, 1 +AVX_INSTR pminud, sse4, 0, 0, 1 +AVX_INSTR pmovmskb, mmx2 +AVX_INSTR pmovsxbw, sse4 +AVX_INSTR pmovsxbd, sse4 +AVX_INSTR pmovsxbq, sse4 +AVX_INSTR pmovsxwd, sse4 +AVX_INSTR pmovsxwq, sse4 +AVX_INSTR pmovsxdq, sse4 +AVX_INSTR pmovzxbw, sse4 +AVX_INSTR pmovzxbd, sse4 +AVX_INSTR pmovzxbq, sse4 +AVX_INSTR pmovzxwd, sse4 +AVX_INSTR pmovzxwq, sse4 +AVX_INSTR pmovzxdq, sse4 +AVX_INSTR pmuldq, sse4, 0, 0, 1 +AVX_INSTR pmulhrsw, ssse3, 0, 0, 1 +AVX_INSTR pmulhuw, mmx2, 0, 0, 1 +AVX_INSTR pmulhw, mmx, 0, 0, 1 +AVX_INSTR pmullw, mmx, 0, 0, 1 +AVX_INSTR pmulld, sse4, 0, 0, 1 +AVX_INSTR pmuludq, sse2, 0, 0, 1 +AVX_INSTR por, mmx, 0, 0, 1 +AVX_INSTR psadbw, mmx2, 0, 0, 1 +AVX_INSTR pshufb, ssse3, 0, 0, 0 +AVX_INSTR pshufd, sse2 +AVX_INSTR pshufhw, sse2 +AVX_INSTR pshuflw, sse2 +AVX_INSTR psignb, ssse3, 0, 0, 0 +AVX_INSTR psignw, ssse3, 0, 0, 0 +AVX_INSTR psignd, ssse3, 0, 0, 0 +AVX_INSTR psllw, mmx, 0, 0, 0 +AVX_INSTR pslld, mmx, 0, 0, 0 +AVX_INSTR psllq, mmx, 0, 0, 0 +AVX_INSTR pslldq, sse2, 0, 0, 0 +AVX_INSTR psraw, mmx, 0, 0, 0 +AVX_INSTR psrad, mmx, 0, 0, 0 +AVX_INSTR psrlw, mmx, 0, 0, 0 +AVX_INSTR psrld, mmx, 0, 0, 0 +AVX_INSTR psrlq, mmx, 0, 0, 0 +AVX_INSTR psrldq, sse2, 0, 0, 0 +AVX_INSTR psubb, mmx, 0, 0, 0 +AVX_INSTR psubw, mmx, 0, 0, 0 +AVX_INSTR psubd, mmx, 0, 0, 0 +AVX_INSTR psubq, sse2, 0, 0, 0 +AVX_INSTR psubsb, mmx, 0, 0, 0 +AVX_INSTR psubsw, mmx, 0, 0, 0 +AVX_INSTR psubusb, mmx, 0, 0, 0 +AVX_INSTR psubusw, mmx, 0, 0, 0 +AVX_INSTR ptest, sse4 +AVX_INSTR punpckhbw, mmx, 0, 0, 0 +AVX_INSTR punpckhwd, mmx, 0, 0, 0 +AVX_INSTR punpckhdq, mmx, 0, 0, 0 +AVX_INSTR punpckhqdq, sse2, 0, 0, 0 +AVX_INSTR punpcklbw, mmx, 0, 0, 0 +AVX_INSTR punpcklwd, mmx, 0, 0, 0 +AVX_INSTR punpckldq, mmx, 0, 0, 0 +AVX_INSTR punpcklqdq, sse2, 0, 0, 0 +AVX_INSTR pxor, mmx, 0, 0, 1 +AVX_INSTR rcpps, sse +AVX_INSTR rcpss, sse, 1, 0, 0 +AVX_INSTR roundpd, sse4 +AVX_INSTR roundps, sse4 +AVX_INSTR roundsd, sse4, 1, 1, 0 +AVX_INSTR roundss, sse4, 1, 1, 0 +AVX_INSTR rsqrtps, sse +AVX_INSTR rsqrtss, sse, 1, 0, 0 +AVX_INSTR shufpd, sse2, 1, 1, 0 +AVX_INSTR shufps, sse, 1, 1, 0 +AVX_INSTR sqrtpd, sse2 +AVX_INSTR sqrtps, sse +AVX_INSTR sqrtsd, sse2, 1, 0, 0 +AVX_INSTR sqrtss, sse, 1, 0, 0 +AVX_INSTR stmxcsr, sse +AVX_INSTR subpd, sse2, 1, 0, 0 +AVX_INSTR subps, sse, 1, 0, 0 +AVX_INSTR subsd, sse2, 1, 0, 0 +AVX_INSTR subss, sse, 1, 0, 0 +AVX_INSTR ucomisd, sse2 +AVX_INSTR ucomiss, sse +AVX_INSTR unpckhpd, sse2, 1, 0, 0 +AVX_INSTR unpckhps, sse, 1, 0, 0 +AVX_INSTR unpcklpd, sse2, 1, 0, 0 +AVX_INSTR unpcklps, sse, 1, 0, 0 +AVX_INSTR xorpd, sse2, 1, 0, 1 +AVX_INSTR xorps, sse, 1, 0, 1 + +; 3DNow instructions, for sharing code between AVX, SSE and 3DN +AVX_INSTR pfadd, 3dnow, 1, 0, 1 +AVX_INSTR pfsub, 3dnow, 1, 0, 0 +AVX_INSTR pfmul, 3dnow, 1, 0, 1 + +; base-4 constants for shuffles +%assign i 0 +%rep 256 + %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3) + %if j < 10 + CAT_XDEFINE q000, j, i + %elif j < 100 + CAT_XDEFINE q00, j, i + %elif j < 1000 + CAT_XDEFINE q0, j, i + %else + CAT_XDEFINE q, j, i + %endif + %assign i i+1 +%endrep +%undef i +%undef j + +%macro FMA_INSTR 3 + %macro %1 4-7 %1, %2, %3 + %if cpuflag(xop) + v%5 %1, %2, %3, %4 + %elifnidn %1, %4 + %6 %1, %2, %3 + %7 %1, %4 + %else + %error non-xop emulation of ``%5 %1, %2, %3, %4'' is not supported + %endif + %endmacro +%endmacro + +FMA_INSTR pmacsww, pmullw, paddw +FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation +FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation +FMA_INSTR pmadcswd, pmaddwd, paddd + +; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf. +; This lets us use tzcnt without bumping the yasm version requirement yet. +%define tzcnt rep bsf + +; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax. +; FMA3 is only possible if dst is the same as one of the src registers. +; Either src2 or src3 can be a memory operand. +%macro FMA4_INSTR 2-* + %push fma4_instr + %xdefine %$prefix %1 + %rep %0 - 1 + %macro %$prefix%2 4-6 %$prefix, %2 + %if notcpuflag(fma3) && notcpuflag(fma4) + %error use of ``%5%6'' fma instruction in cpuname function: current_function + %elif cpuflag(fma4) + v%5%6 %1, %2, %3, %4 + %elifidn %1, %2 + ; If %3 or %4 is a memory operand it needs to be encoded as the last operand. + %ifnum sizeof%3 + v%{5}213%6 %2, %3, %4 + %else + v%{5}132%6 %2, %4, %3 + %endif + %elifidn %1, %3 + v%{5}213%6 %3, %2, %4 + %elifidn %1, %4 + v%{5}231%6 %4, %2, %3 + %else + %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported + %endif + %endmacro + %rotate 1 + %endrep + %pop +%endmacro + +FMA4_INSTR fmadd, pd, ps, sd, ss +FMA4_INSTR fmaddsub, pd, ps +FMA4_INSTR fmsub, pd, ps, sd, ss +FMA4_INSTR fmsubadd, pd, ps +FMA4_INSTR fnmadd, pd, ps, sd, ss +FMA4_INSTR fnmsub, pd, ps, sd, ss + +; Macros for converting VEX instructions to equivalent EVEX ones. +%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex + %macro %1 2-7 fnord, fnord, %1, %2, %3 + %ifidn %3, fnord + %define %%args %1, %2 + %elifidn %4, fnord + %define %%args %1, %2, %3 + %else + %define %%args %1, %2, %3, %4 + %endif + %assign %%evex_required cpuflag(avx512) & %7 + %ifnum regnumof%1 + %if regnumof%1 >= 16 || sizeof%1 > 32 + %assign %%evex_required 1 + %endif + %endif + %ifnum regnumof%2 + %if regnumof%2 >= 16 || sizeof%2 > 32 + %assign %%evex_required 1 + %endif + %endif + %if %%evex_required + %6 %%args + %else + %5 %%args ; Prefer VEX over EVEX due to shorter instruction length + %endif + %endmacro +%endmacro + +EVEX_INSTR vbroadcastf128, vbroadcastf32x4 +EVEX_INSTR vbroadcasti128, vbroadcasti32x4 +EVEX_INSTR vextractf128, vextractf32x4 +EVEX_INSTR vextracti128, vextracti32x4 +EVEX_INSTR vinsertf128, vinsertf32x4 +EVEX_INSTR vinserti128, vinserti32x4 +EVEX_INSTR vmovdqa, vmovdqa32 +EVEX_INSTR vmovdqu, vmovdqu32 +EVEX_INSTR vpand, vpandd +EVEX_INSTR vpandn, vpandnd +EVEX_INSTR vpor, vpord +EVEX_INSTR vpxor, vpxord +EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision +EVEX_INSTR vrcpss, vrcp14ss, 1 +EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 +EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 + +; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0) +%ifdef __YASM_VER__ + %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0 + %macro vpbroadcastq 2 + %if sizeof%1 == 16 + movddup %1, %2 + %else + vbroadcastsd %1, %2 + %endif + %endmacro + %endif +%endif diff --git a/arm/raspi/third_party/ffmpeg/libavutil/x86/x86util.asm b/arm/raspi/third_party/ffmpeg/libavutil/x86/x86util.asm new file mode 100644 index 00000000..d7cd9968 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/x86/x86util.asm @@ -0,0 +1,1028 @@ +;***************************************************************************** +;* x86util.asm +;***************************************************************************** +;* Copyright (C) 2008-2010 x264 project +;* +;* Authors: Loren Merritt +;* Holger Lubitz +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%define private_prefix ff +%define public_prefix avpriv +%define cpuflags_mmxext cpuflags_mmx2 + +%include "libavutil/x86/x86inc.asm" + +; expands to [base],...,[base+7*stride] +%define PASS8ROWS(base, base3, stride, stride3) \ + [base], [base + stride], [base + 2*stride], [base3], \ + [base3 + stride], [base3 + 2*stride], [base3 + stride3], [base3 + stride*4] + +; Interleave low src0 with low src1 and store in src0, +; interleave high src0 with high src1 and store in src1. +; %1 - types +; %2 - index of the register with src0 +; %3 - index of the register with src1 +; %4 - index of the register for intermediate results +; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3 +; src1: y0 y1 y2 y3 q0 q1 q2 q3 +; output: src0: x0 y0 x1 y1 x2 y2 x3 y3 +; src1: z0 q0 z1 q1 z2 q2 z3 q3 +%macro SBUTTERFLY 4 +%ifidn %1, dqqq + vperm2i128 m%4, m%2, m%3, q0301 + vinserti128 m%2, m%2, xm%3, 1 +%elif avx_enabled == 0 + mova m%4, m%2 + punpckl%1 m%2, m%3 + punpckh%1 m%4, m%3 +%else + punpckh%1 m%4, m%2, m%3 + punpckl%1 m%2, m%3 +%endif + SWAP %3, %4 +%endmacro + +%macro SBUTTERFLY2 4 + punpckl%1 m%4, m%2, m%3 + punpckh%1 m%2, m%2, m%3 + SWAP %2, %4, %3 +%endmacro + +%macro SBUTTERFLYPS 3 + unpcklps m%3, m%1, m%2 + unpckhps m%1, m%1, m%2 + SWAP %1, %3, %2 +%endmacro + +%macro SBUTTERFLYPD 3 + movlhps m%3, m%1, m%2 + movhlps m%2, m%2, m%1 + SWAP %1, %3 +%endmacro + +%macro TRANSPOSE4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE2x4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE2x4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SBUTTERFLY qdq, %1, %2, %5 + SBUTTERFLY qdq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE4x4D 5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 + SBUTTERFLY qdq, %1, %3, %5 + SBUTTERFLY qdq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops +%macro TRANSPOSE4x4PS 5 + SBUTTERFLYPS %1, %2, %5 + SBUTTERFLYPS %3, %4, %5 + SBUTTERFLYPD %1, %3, %5 + SBUTTERFLYPD %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE8x4D 9-11 +%if ARCH_X86_64 + SBUTTERFLY dq, %1, %2, %9 + SBUTTERFLY dq, %3, %4, %9 + SBUTTERFLY dq, %5, %6, %9 + SBUTTERFLY dq, %7, %8, %9 + SBUTTERFLY qdq, %1, %3, %9 + SBUTTERFLY qdq, %2, %4, %9 + SBUTTERFLY qdq, %5, %7, %9 + SBUTTERFLY qdq, %6, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7 +; out: m0..m7, unless %11 in which case m2 is in %9 +; spills into %9 and %10 + movdqa %9, m%7 + SBUTTERFLY dq, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY dq, %3, %4, %2 + SBUTTERFLY dq, %5, %6, %2 + SBUTTERFLY dq, %7, %8, %2 + SBUTTERFLY qdq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY qdq, %2, %4, %3 + SBUTTERFLY qdq, %5, %7, %3 + SBUTTERFLY qdq, %6, %8, %3 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%3, %9 +%endif +%endif +%endmacro + +%macro TRANSPOSE8x8W 9-11 +%if ARCH_X86_64 + SBUTTERFLY wd, %1, %2, %9 + SBUTTERFLY wd, %3, %4, %9 + SBUTTERFLY wd, %5, %6, %9 + SBUTTERFLY wd, %7, %8, %9 + SBUTTERFLY dq, %1, %3, %9 + SBUTTERFLY dq, %2, %4, %9 + SBUTTERFLY dq, %5, %7, %9 + SBUTTERFLY dq, %6, %8, %9 + SBUTTERFLY qdq, %1, %5, %9 + SBUTTERFLY qdq, %2, %6, %9 + SBUTTERFLY qdq, %3, %7, %9 + SBUTTERFLY qdq, %4, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7, unless %11 in which case m6 is in %9 +; out: m0..m7, unless %11 in which case m4 is in %10 +; spills into %9 and %10 +%if %0<11 + movdqa %9, m%7 +%endif + SBUTTERFLY wd, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY wd, %3, %4, %2 + SBUTTERFLY wd, %5, %6, %2 + SBUTTERFLY wd, %7, %8, %2 + SBUTTERFLY dq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY dq, %2, %4, %3 + SBUTTERFLY dq, %5, %7, %3 + SBUTTERFLY dq, %6, %8, %3 + SBUTTERFLY qdq, %1, %5, %3 + SBUTTERFLY qdq, %2, %6, %3 + movdqa %10, m%2 + movdqa m%3, %9 + SBUTTERFLY qdq, %3, %7, %2 + SBUTTERFLY qdq, %4, %8, %2 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%5, %10 +%endif +%endif +%endmacro + +%macro TRANSPOSE16x16W 18-19 +; in: m0..m15, unless %19 in which case m6 is in %17 +; out: m0..m15, unless %19 in which case m4 is in %18 +; spills into %17 and %18 +%if %0 < 19 + mova %17, m%7 +%endif + + SBUTTERFLY dqqq, %1, %9, %7 + SBUTTERFLY dqqq, %2, %10, %7 + SBUTTERFLY dqqq, %3, %11, %7 + SBUTTERFLY dqqq, %4, %12, %7 + SBUTTERFLY dqqq, %5, %13, %7 + SBUTTERFLY dqqq, %6, %14, %7 + mova %18, m%14 + mova m%7, %17 + SBUTTERFLY dqqq, %7, %15, %14 + SBUTTERFLY dqqq, %8, %16, %14 + + SBUTTERFLY wd, %1, %2, %14 + SBUTTERFLY wd, %3, %4, %14 + SBUTTERFLY wd, %5, %6, %14 + SBUTTERFLY wd, %7, %8, %14 + SBUTTERFLY wd, %9, %10, %14 + SBUTTERFLY wd, %11, %12, %14 + mova %17, m%12 + mova m%14, %18 + SBUTTERFLY wd, %13, %14, %12 + SBUTTERFLY wd, %15, %16, %12 + + SBUTTERFLY dq, %1, %3, %12 + SBUTTERFLY dq, %2, %4, %12 + SBUTTERFLY dq, %5, %7, %12 + SBUTTERFLY dq, %6, %8, %12 + SBUTTERFLY dq, %9, %11, %12 + mova %18, m%11 + mova m%12, %17 + SBUTTERFLY dq, %10, %12, %11 + SBUTTERFLY dq, %13, %15, %11 + SBUTTERFLY dq, %14, %16, %11 + + SBUTTERFLY qdq, %1, %5, %11 + SBUTTERFLY qdq, %2, %6, %11 + SBUTTERFLY qdq, %3, %7, %11 + SBUTTERFLY qdq, %4, %8, %11 + + SWAP %2, %5 + SWAP %4, %7 + + SBUTTERFLY qdq, %9, %13, %11 + SBUTTERFLY qdq, %10, %14, %11 + mova m%11, %18 + mova %18, m%5 + SBUTTERFLY qdq, %11, %15, %5 + SBUTTERFLY qdq, %12, %16, %5 + +%if %0 < 19 + mova m%5, %18 +%endif + + SWAP %10, %13 + SWAP %12, %15 +%endmacro + +%macro TRANSPOSE_8X8B 8 + %if mmsize == 8 + %error "This macro does not support mmsize == 8" + %endif + punpcklbw m%1, m%2 + punpcklbw m%3, m%4 + punpcklbw m%5, m%6 + punpcklbw m%7, m%8 + TRANSPOSE4x4W %1, %3, %5, %7, %2 + MOVHL m%2, m%1 + MOVHL m%4, m%3 + MOVHL m%6, m%5 + MOVHL m%8, m%7 +%endmacro + +; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place +%macro PABSW 2 +%if cpuflag(ssse3) + pabsw %1, %2 +%elif cpuflag(mmxext) + pxor %1, %1 + psubw %1, %2 + pmaxsw %1, %2 +%else + pxor %1, %1 + pcmpgtw %1, %2 + pxor %2, %1 + psubw %2, %1 + SWAP %1, %2 +%endif +%endmacro + +%macro PSIGNW 2 +%if cpuflag(ssse3) + psignw %1, %2 +%else + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS1 2 +%if cpuflag(ssse3) + pabsw %1, %1 +%elif cpuflag(mmxext) ; a, tmp + pxor %2, %2 + psubw %2, %1 + pmaxsw %1, %2 +%else ; a, tmp + pxor %2, %2 + pcmpgtw %2, %1 + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS2 4 +%if cpuflag(ssse3) + pabsw %1, %1 + pabsw %2, %2 +%elif cpuflag(mmxext) ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + psubw %3, %1 + psubw %4, %2 + pmaxsw %1, %3 + pmaxsw %2, %4 +%else ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + pcmpgtw %3, %1 + pcmpgtw %4, %2 + pxor %1, %3 + pxor %2, %4 + psubw %1, %3 + psubw %2, %4 +%endif +%endmacro + +%macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 +%else + pxor %2, %2 + psubb %2, %1 + pminub %1, %2 +%endif +%endmacro + +%macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 + pabsb %2, %2 +%else + pxor %3, %3 + pxor %4, %4 + psubb %3, %1 + psubb %4, %2 + pminub %1, %3 + pminub %2, %4 +%endif +%endmacro + +%macro ABSD2 4 + pxor %3, %3 + pxor %4, %4 + pcmpgtd %3, %1 + pcmpgtd %4, %2 + pxor %1, %3 + pxor %2, %4 + psubd %1, %3 + psubd %2, %4 +%endmacro + +%macro ABS4 6 + ABS2 %1, %2, %5, %6 + ABS2 %3, %4, %5, %6 +%endmacro + +%macro SPLATB_LOAD 3 +%if cpuflag(ssse3) + movd %1, [%2-3] + pshufb %1, %3 +%else + movd %1, [%2-3] ;to avoid crossing a cacheline + punpcklbw %1, %1 + SPLATW %1, %1, 3 +%endif +%endmacro + +%macro SPLATB_REG 3 +%if cpuflag(ssse3) + movd %1, %2d + pshufb %1, %3 +%else + movd %1, %2d + punpcklbw %1, %1 + SPLATW %1, %1, 0 +%endif +%endmacro + +%macro HADDD 2 ; sum junk +%if sizeof%1 == 32 +%define %2 xmm%2 + vextracti128 %2, %1, 1 +%define %1 xmm%1 + paddd %1, %2 +%endif +%if mmsize >= 16 +%if cpuflag(xop) && sizeof%1 == 16 + vphadddq %1, %1 +%endif + movhlps %2, %1 + paddd %1, %2 +%endif +%if notcpuflag(xop) || sizeof%1 != 16 +%if cpuflag(mmxext) + PSHUFLW %2, %1, q0032 +%else ; mmx + mova %2, %1 + psrlq %2, 32 +%endif + paddd %1, %2 +%endif +%undef %1 +%undef %2 +%endmacro + +%macro HADDW 2 ; reg, tmp +%if cpuflag(xop) && sizeof%1 == 16 + vphaddwq %1, %1 + movhlps %2, %1 + paddd %1, %2 +%else + pmaddwd %1, [pw_1] + HADDD %1, %2 +%endif +%endmacro + +%macro HADDPS 3 ; dst, src, tmp +%if cpuflag(sse3) + haddps %1, %1, %2 +%else + movaps %3, %1 + shufps %1, %2, q2020 + shufps %3, %2, q3131 + addps %1, %3 +%endif +%endmacro + +%macro PALIGNR 4-5 +%if cpuflag(ssse3) +%if %0==5 + palignr %1, %2, %3, %4 +%else + palignr %1, %2, %3 +%endif +%else ; [dst,] src1, src2, imm, tmp + %define %%dst %1 +%if %0==5 +%ifnidn %1, %2 + mova %%dst, %2 +%endif + %rotate 1 +%endif +%ifnidn %4, %2 + mova %4, %2 +%endif +%if mmsize==8 + psllq %%dst, (8-%3)*8 + psrlq %4, %3*8 +%else + pslldq %%dst, 16-%3 + psrldq %4, %3 +%endif + por %%dst, %4 +%endif +%endmacro + +%macro PAVGB 2-4 +%if cpuflag(mmxext) + pavgb %1, %2 +%elif cpuflag(3dnow) + pavgusb %1, %2 +%elif cpuflag(mmx) + movu %3, %2 + por %3, %1 + pxor %1, %2 + pand %1, %4 + psrlq %1, 1 + psubb %3, %1 + SWAP %1, %3 +%endif +%endmacro + +%macro PSHUFLW 1+ + %if mmsize == 8 + pshufw %1 + %else + pshuflw %1 + %endif +%endmacro + +%macro PSWAPD 2 +%if cpuflag(mmxext) + pshufw %1, %2, q1032 +%elif cpuflag(3dnowext) + pswapd %1, %2 +%elif cpuflag(3dnow) + movq %1, %2 + psrlq %1, 32 + punpckldq %1, %2 +%endif +%endmacro + +%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from +%ifnum %5 + pand m%3, m%5, m%4 ; src .. y6 .. y4 + pand m%1, m%5, m%2 ; dst .. y6 .. y4 +%else + mova m%1, %5 + pand m%3, m%1, m%4 ; src .. y6 .. y4 + pand m%1, m%1, m%2 ; dst .. y6 .. y4 +%endif + psrlw m%2, 8 ; dst .. y7 .. y5 + psrlw m%4, 8 ; src .. y7 .. y5 +%endmacro + +%macro SUMSUB_BA 3-4 +%if %0==3 + padd%1 m%2, m%3 + padd%1 m%3, m%3 + psub%1 m%3, m%2 +%else +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endif +%endmacro + +%macro SUMSUB_BADC 5-6 +%if %0==6 + SUMSUB_BA %1, %2, %3, %6 + SUMSUB_BA %1, %4, %5, %6 +%else + padd%1 m%2, m%3 + padd%1 m%4, m%5 + padd%1 m%3, m%3 + padd%1 m%5, m%5 + psub%1 m%3, m%2 + psub%1 m%5, m%4 +%endif +%endmacro + +%macro SUMSUB2_AB 4 +%ifnum %3 + psub%1 m%4, m%2, m%3 + psub%1 m%4, m%3 + padd%1 m%2, m%2 + padd%1 m%2, m%3 +%else + mova m%4, m%2 + padd%1 m%2, m%2 + padd%1 m%2, %3 + psub%1 m%4, %3 + psub%1 m%4, %3 +%endif +%endmacro + +%macro SUMSUB2_BA 4 +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + padd%1 m%2, m%3 + psub%1 m%3, m%4 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + padd%1 m%4, m%3 + psub%1 m%3, m%2 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endmacro + +%macro SUMSUBD2_AB 5 +%ifnum %4 + psra%1 m%5, m%2, 1 ; %3: %3>>1 + psra%1 m%4, m%3, 1 ; %2: %2>>1 + padd%1 m%4, m%2 ; %3: %3>>1+%2 + psub%1 m%5, m%3 ; %2: %2>>1-%3 + SWAP %2, %5 + SWAP %3, %4 +%else + mova %5, m%2 + mova %4, m%3 + psra%1 m%3, 1 ; %3: %3>>1 + psra%1 m%2, 1 ; %2: %2>>1 + padd%1 m%3, %5 ; %3: %3>>1+%2 + psub%1 m%2, %4 ; %2: %2>>1-%3 +%endif +%endmacro + +%macro DCT4_1D 5 +%ifnum %5 + SUMSUB_BADC w, %4, %1, %3, %2, %5 + SUMSUB_BA w, %3, %4, %5 + SUMSUB2_AB w, %1, %2, %5 + SWAP %1, %3, %4, %5, %2 +%else + SUMSUB_BADC w, %4, %1, %3, %2 + SUMSUB_BA w, %3, %4 + mova [%5], m%2 + SUMSUB2_AB w, %1, [%5], %2 + SWAP %1, %3, %4, %2 +%endif +%endmacro + +%macro IDCT4_1D 6-7 +%ifnum %6 + SUMSUBD2_AB %1, %3, %5, %7, %6 + ; %3: %3>>1-%5 %5: %3+%5>>1 + SUMSUB_BA %1, %4, %2, %7 + ; %4: %2+%4 %2: %2-%4 + SUMSUB_BADC %1, %5, %4, %3, %2, %7 + ; %5: %2+%4 + (%3+%5>>1) + ; %4: %2+%4 - (%3+%5>>1) + ; %3: %2-%4 + (%3>>1-%5) + ; %2: %2-%4 - (%3>>1-%5) +%else +%ifidn %1, w + SUMSUBD2_AB %1, %3, %5, [%6], [%6+16] +%else + SUMSUBD2_AB %1, %3, %5, [%6], [%6+32] +%endif + SUMSUB_BA %1, %4, %2 + SUMSUB_BADC %1, %5, %4, %3, %2 +%endif + SWAP %2, %5, %4 + ; %2: %2+%4 + (%3+%5>>1) row0 + ; %3: %2-%4 + (%3>>1-%5) row1 + ; %4: %2-%4 - (%3>>1-%5) row2 + ; %5: %2+%4 - (%3+%5>>1) row3 +%endmacro + + +%macro LOAD_DIFF 5 +%ifidn %3, none + movh %1, %4 + movh %2, %5 + punpcklbw %1, %2 + punpcklbw %2, %2 + psubw %1, %2 +%else + movh %1, %4 + punpcklbw %1, %3 + movh %2, %5 + punpcklbw %2, %3 + psubw %1, %2 +%endif +%endmacro + +%macro STORE_DCT 6 + movq [%5+%6+ 0], m%1 + movq [%5+%6+ 8], m%2 + movq [%5+%6+16], m%3 + movq [%5+%6+24], m%4 + movhps [%5+%6+32], m%1 + movhps [%5+%6+40], m%2 + movhps [%5+%6+48], m%3 + movhps [%5+%6+56], m%4 +%endmacro + +%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment? + LOAD_DIFF m%1, m%5, m%7, [%8], [%9] + LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3] + LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3] + LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5] +%if %10 + lea %8, [%8+4*r1] + lea %9, [%9+4*r3] +%endif +%endmacro + +%macro DIFFx2 6-7 + movh %3, %5 + punpcklbw %3, %4 + psraw %1, 6 + paddsw %1, %3 + movh %3, %6 + punpcklbw %3, %4 + psraw %2, 6 + paddsw %2, %3 + packuswb %2, %1 +%endmacro + +%macro STORE_DIFF 4 + movh %2, %4 + punpcklbw %2, %3 + psraw %1, 6 + paddsw %1, %2 + packuswb %1, %1 + movh %4, %1 +%endmacro + +%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride + movh %3, [%7] + movh %4, [%7+%8] + psraw %1, %6 + psraw %2, %6 + punpcklbw %3, %5 + punpcklbw %4, %5 + paddw %3, %1 + paddw %4, %2 + packuswb %3, %5 + packuswb %4, %5 + movh [%7], %3 + movh [%7+%8], %4 +%endmacro + +%macro PMINUB 3 ; dst, src, ignored +%if cpuflag(mmxext) + pminub %1, %2 +%else ; dst, src, tmp + mova %3, %1 + psubusb %3, %2 + psubb %1, %3 +%endif +%endmacro + +%macro SPLATW 2-3 0 +%if cpuflag(avx2) && %3 == 0 + vpbroadcastw %1, %2 +%elif mmsize == 16 + pshuflw %1, %2, (%3)*0x55 + punpcklqdq %1, %1 +%elif cpuflag(mmxext) + pshufw %1, %2, (%3)*0x55 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + %if %3 & 2 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif + %if %3 & 1 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif +%endif +%endmacro + +%macro SPLATD 1 +%if mmsize == 8 + punpckldq %1, %1 +%elif cpuflag(sse2) + pshufd %1, %1, 0 +%elif cpuflag(sse) + shufps %1, %1, 0 +%endif +%endmacro + +%macro CLIPUB 3 ;(dst, min, max) + pmaxub %1, %2 + pminub %1, %3 +%endmacro + +%macro CLIPW 3 ;(dst, min, max) + pmaxsw %1, %2 + pminsw %1, %3 +%endmacro + +%macro PMINSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pminsd %1, %2 +%elif cpuflag(sse2) + cvtdq2ps %1, %1 + minps %1, %2 + cvtps2dq %1, %1 +%else + mova %3, %2 + pcmpgtd %3, %1 + pxor %1, %2 + pand %1, %3 + pxor %1, %2 +%endif +%endmacro + +%macro PMAXSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pmaxsd %1, %2 +%else + mova %3, %1 + pcmpgtd %3, %2 + pand %1, %3 + pandn %3, %2 + por %1, %3 +%endif +%endmacro + +%macro CLIPD 3-4 +%if cpuflag(sse4); src/dst, min, max, unused + pminsd %1, %3 + pmaxsd %1, %2 +%elif cpuflag(sse2) ; src/dst, min (float), max (float), unused + cvtdq2ps %1, %1 + minps %1, %3 + maxps %1, %2 + cvtps2dq %1, %1 +%else ; src/dst, min, max, tmp + PMINSD %1, %3, %4 + PMAXSD %1, %2, %4 +%endif +%endmacro + +%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vbroadcastss %1, %2 +%elif cpuflag(avx) + %ifnum sizeof%2 ; avx1 register + shufps xmm%1, xmm%2, xmm%2, q0000 + %if sizeof%1 >= 32 ; mmsize>=32 + vinsertf128 %1, %1, xmm%1, 1 + %endif + %else ; avx1 memory + vbroadcastss %1, %2 + %endif +%else + %ifnum sizeof%2 ; sse register + shufps %1, %2, %2, q0000 + %else ; sse memory + movss %1, %2 + shufps %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTSD 2 ; dst xmm/ymm, src m64 +%if cpuflag(avx) && mmsize == 32 + vbroadcastsd %1, %2 +%elif cpuflag(sse3) + movddup %1, %2 +%else ; sse2 + movsd %1, %2 + movlhps %1, %1 +%endif +%endmacro + +%macro VPBROADCASTD 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vpbroadcastd %1, %2 +%elif cpuflag(avx) && sizeof%1 >= 32 + %error vpbroadcastd not possible with ymm on avx1. try vbroadcastss +%else + %ifnum sizeof%2 ; sse2 register + pshufd %1, %2, q0000 + %else ; sse memory + movd %1, %2 + pshufd %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTI128 2 ; dst xmm/ymm, src : 128bits val +%if mmsize > 16 + vbroadcasti128 %1, %2 +%else + mova %1, %2 +%endif +%endmacro + +%macro SHUFFLE_MASK_W 8 + %rep 8 + %if %1>=0x80 + db %1, %1 + %else + db %1*2 + db %1*2+1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro PMOVSXWD 2; dst, src +%if cpuflag(sse4) + pmovsxwd %1, %2 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + punpcklwd %1, %1 + psrad %1, 16 +%endif +%endmacro + +; Wrapper for non-FMA version of fmaddps +%macro FMULADD_PS 5 + %if cpuflag(fma3) || cpuflag(fma4) + fmaddps %1, %2, %3, %4 + %elifidn %1, %4 + mulps %5, %2, %3 + addps %1, %4, %5 + %else + mulps %1, %2, %3 + addps %1, %4 + %endif +%endmacro + +%macro LSHIFT 2 +%if mmsize > 8 + pslldq %1, %2 +%else + psllq %1, 8*(%2) +%endif +%endmacro + +%macro RSHIFT 2 +%if mmsize > 8 + psrldq %1, %2 +%else + psrlq %1, 8*(%2) +%endif +%endmacro + +%macro MOVHL 2 ; dst, src +%ifidn %1, %2 + punpckhqdq %1, %2 +%elif cpuflag(avx) + punpckhqdq %1, %2, %2 +%elif cpuflag(sse4) + pshufd %1, %2, q3232 ; pshufd is slow on some older CPUs, so only use it on more modern ones +%else + movhlps %1, %2 ; may cause an int/float domain transition and has a dependency on dst +%endif +%endmacro + +; Horizontal Sum of Packed Single precision floats +; The resulting sum is in all elements. +%macro HSUMPS 2 ; dst/src, tmp +%if cpuflag(avx) + %if sizeof%1>=32 ; avx + vperm2f128 %2, %1, %1, (0)*16+(1) + addps %1, %2 + %endif + shufps %2, %1, %1, q1032 + addps %1, %2 + shufps %2, %1, %1, q0321 + addps %1, %2 +%else ; this form is a bit faster than the short avx-like emulation. + movaps %2, %1 + shufps %1, %1, q1032 + addps %1, %2 + movaps %2, %1 + shufps %1, %1, q0321 + addps %1, %2 + ; all %1 members should be equal for as long as float a+b==b+a +%endif +%endmacro + +; Emulate blendvps if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro BLENDVPS 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + blendvps %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 blendvps uses xmm0 as default 3d operand, you used %3 + %endif + blendvps %1, %2, %3 +%else + xorps %2, %1 + andps %2, %3 + xorps %1, %2 +%endif +%endmacro + +; Emulate pblendvb if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro PBLENDVB 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + %if cpuflag(avx) && notcpuflag(avx2) && sizeof%1 >= 32 + %error pblendb not possible with ymm on avx1, try blendvps. + %endif + pblendvb %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 pblendvd uses xmm0 as default 3d operand, you used %3 + %endif + pblendvb %1, %2, %3 +%else + pxor %2, %1 + pand %2, %3 + pxor %1, %2 +%endif +%endmacro diff --git a/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.c b/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.c new file mode 100644 index 00000000..3aed3142 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.c @@ -0,0 +1,417 @@ +/* + * CGA/EGA/VGA ROM font data + * + * 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 + * CGA/EGA/VGA ROM font data + */ + +#include +#include "xga_font_data.h" + +const uint8_t avpriv_cga_font[2048] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const uint8_t avpriv_vga16_font[4096] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.h b/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.h new file mode 100644 index 00000000..69dc3371 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/xga_font_data.h @@ -0,0 +1,35 @@ +/* + * CGA/EGA/VGA ROM font data + * + * 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 + * CGA/EGA/VGA ROM font data + */ + +#ifndef AVUTIL_XGA_FONT_DATA_H +#define AVUTIL_XGA_FONT_DATA_H + +#include +#include "internal.h" + +extern av_export_avutil const uint8_t avpriv_cga_font[2048]; +extern av_export_avutil const uint8_t avpriv_vga16_font[4096]; + +#endif /* AVUTIL_XGA_FONT_DATA_H */ diff --git a/arm/raspi/third_party/ffmpeg/libavutil/xtea.c b/arm/raspi/third_party/ffmpeg/libavutil/xtea.c new file mode 100644 index 00000000..6f376c36 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/xtea.c @@ -0,0 +1,253 @@ +/* + * A 32-bit implementation of the XTEA algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * loosely based on the implementation of David Wheeler and Roger Needham + * + * 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 + * @brief XTEA 32-bit implementation + * @author Samuel Pitoiset + * @ingroup lavu_xtea + */ + +#include +#include "config.h" +#include "intreadwrite.h" +#include "mem.h" +#include "xtea.h" + +AVXTEA *av_xtea_alloc(void) +{ + return av_mallocz(sizeof(struct AVXTEA)); +} + +void av_xtea_init(AVXTEA *ctx, const uint8_t key[16]) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RB32(key + (i << 2)); +} + +void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16]) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RL32(key + (i << 2)); +} + +static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; +#if !CONFIG_SMALL + uint32_t k0 = ctx->key[0]; + uint32_t k1 = ctx->key[1]; + uint32_t k2 = ctx->key[2]; + uint32_t k3 = ctx->key[3]; +#endif + + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + if (decrypt) { +#if CONFIG_SMALL + int i; + uint32_t delta = 0x9E3779B9U, sum = delta * 32; + + for (i = 0; i < 32; i++) { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + } +#else +#define DSTEP(SUM, K0, K1) \ + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + K0); \ + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9U + K1) + + DSTEP(0xC6EF3720U, k2, k3); + DSTEP(0x28B7BD67U, k3, k2); + DSTEP(0x8A8043AEU, k0, k1); + DSTEP(0xEC48C9F5U, k1, k0); + DSTEP(0x4E11503CU, k2, k3); + DSTEP(0xAFD9D683U, k2, k2); + DSTEP(0x11A25CCAU, k3, k1); + DSTEP(0x736AE311U, k0, k0); + DSTEP(0xD5336958U, k1, k3); + DSTEP(0x36FBEF9FU, k1, k2); + DSTEP(0x98C475E6U, k2, k1); + DSTEP(0xFA8CFC2DU, k3, k0); + DSTEP(0x5C558274U, k0, k3); + DSTEP(0xBE1E08BBU, k1, k2); + DSTEP(0x1FE68F02U, k1, k1); + DSTEP(0x81AF1549U, k2, k0); + DSTEP(0xE3779B90U, k3, k3); + DSTEP(0x454021D7U, k0, k2); + DSTEP(0xA708A81EU, k1, k1); + DSTEP(0x08D12E65U, k1, k0); + DSTEP(0x6A99B4ACU, k2, k3); + DSTEP(0xCC623AF3U, k3, k2); + DSTEP(0x2E2AC13AU, k0, k1); + DSTEP(0x8FF34781U, k0, k0); + DSTEP(0xF1BBCDC8U, k1, k3); + DSTEP(0x5384540FU, k2, k2); + DSTEP(0xB54CDA56U, k3, k1); + DSTEP(0x1715609DU, k0, k0); + DSTEP(0x78DDE6E4U, k0, k3); + DSTEP(0xDAA66D2BU, k1, k2); + DSTEP(0x3C6EF372U, k2, k1); + DSTEP(0x9E3779B9U, k3, k0); +#endif + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + } else { +#if CONFIG_SMALL + int i; + uint32_t sum = 0, delta = 0x9E3779B9U; + + for (i = 0; i < 32; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + } +#else +#define ESTEP(SUM, K0, K1) \ + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM + K0);\ + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9U + K1) + ESTEP(0x00000000U, k0, k3); + ESTEP(0x9E3779B9U, k1, k2); + ESTEP(0x3C6EF372U, k2, k1); + ESTEP(0xDAA66D2BU, k3, k0); + ESTEP(0x78DDE6E4U, k0, k0); + ESTEP(0x1715609DU, k1, k3); + ESTEP(0xB54CDA56U, k2, k2); + ESTEP(0x5384540FU, k3, k1); + ESTEP(0xF1BBCDC8U, k0, k0); + ESTEP(0x8FF34781U, k1, k0); + ESTEP(0x2E2AC13AU, k2, k3); + ESTEP(0xCC623AF3U, k3, k2); + ESTEP(0x6A99B4ACU, k0, k1); + ESTEP(0x08D12E65U, k1, k1); + ESTEP(0xA708A81EU, k2, k0); + ESTEP(0x454021D7U, k3, k3); + ESTEP(0xE3779B90U, k0, k2); + ESTEP(0x81AF1549U, k1, k1); + ESTEP(0x1FE68F02U, k2, k1); + ESTEP(0xBE1E08BBU, k3, k0); + ESTEP(0x5C558274U, k0, k3); + ESTEP(0xFA8CFC2DU, k1, k2); + ESTEP(0x98C475E6U, k2, k1); + ESTEP(0x36FBEF9FU, k3, k1); + ESTEP(0xD5336958U, k0, k0); + ESTEP(0x736AE311U, k1, k3); + ESTEP(0x11A25CCAU, k2, k2); + ESTEP(0xAFD9D683U, k3, k2); + ESTEP(0x4E11503CU, k0, k1); + ESTEP(0xEC48C9F5U, k1, k0); + ESTEP(0x8A8043AEU, k2, k3); + ESTEP(0x28B7BD67U, k3, k2); +#endif + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); +} + +static void xtea_le_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; + int i; + + v0 = AV_RL32(src); + v1 = AV_RL32(src + 4); + + if (decrypt) { + uint32_t delta = 0x9E3779B9, sum = delta * 32; + + for (i = 0; i < 32; i++) { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + } + if (iv) { + v0 ^= AV_RL32(iv); + v1 ^= AV_RL32(iv + 4); + memcpy(iv, src, 8); + } + } else { + uint32_t sum = 0, delta = 0x9E3779B9; + + for (i = 0; i < 32; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + } + } + + AV_WL32(dst, v0); + AV_WL32(dst + 4, v1); +} + +static void xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt, + void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *)) +{ + int i; + + if (decrypt) { + while (count--) { + crypt(ctx, dst, src, decrypt, iv); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + crypt(ctx, dst, dst, decrypt, NULL); + memcpy(iv, dst, 8); + } else { + crypt(ctx, dst, src, decrypt, NULL); + } + src += 8; + dst += 8; + } + } +} + +void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb); +} + +void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb); +} diff --git a/arm/raspi/third_party/ffmpeg/libavutil/xtea.h b/arm/raspi/third_party/ffmpeg/libavutil/xtea.h new file mode 100644 index 00000000..735427c1 --- /dev/null +++ b/arm/raspi/third_party/ffmpeg/libavutil/xtea.h @@ -0,0 +1,94 @@ +/* + * A 32-bit implementation of the XTEA algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_XTEA_H +#define AVUTIL_XTEA_H + +#include + +/** + * @file + * @brief Public header for libavutil XTEA algorithm + * @defgroup lavu_xtea XTEA + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVXTEA { + uint32_t key[16]; +} AVXTEA; + +/** + * Allocate an AVXTEA context. + */ +AVXTEA *av_xtea_alloc(void); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as big endian 32 bit numbers + */ +void av_xtea_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as little endian 32 bit numbers + */ +void av_xtea_le_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in big endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in little endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_le_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_XTEA_H */ diff --git a/src/media/media_options.gni b/src/media/media_options.gni index 2a6af039..f0518b99 100644 --- a/src/media/media_options.gni +++ b/src/media/media_options.gni @@ -329,7 +329,7 @@ declare_args() { # On CromeOS we are experimenting with the same set of systems CRAS runs on # ie. is_chromeos_device. chrome_wide_echo_cancellation_supported = - is_win || is_mac || is_linux || is_chromeos_device + is_win || is_mac || is_linux || is_chromeos_device } # Do not expand this list without double-checking with OWNERS, this is a list of