From ce7b145f2901389c02ed7637be4f65f4c26ffe4d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 23 Mar 2019 13:43:13 +0100 Subject: [PATCH 01/23] bcm2835-driver: install GL libs only if using bcm2835 GLES driver Signed-off-by: Matthias Reichl --- packages/graphics/bcm2835-driver/package.mk | 48 +++++++++++++++------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/graphics/bcm2835-driver/package.mk b/packages/graphics/bcm2835-driver/package.mk index e6c387260e..4e3372b4bf 100644 --- a/packages/graphics/bcm2835-driver/package.mk +++ b/packages/graphics/bcm2835-driver/package.mk @@ -22,15 +22,31 @@ fi make_target() { # Install vendor header files mkdir -p ${SYSROOT_PREFIX}/usr/include - cp -PRv ${PKG_FLOAT}/opt/vc/include/* ${SYSROOT_PREFIX}/usr/include + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/include/* ${SYSROOT_PREFIX}/usr/include + else + for f in $(cd ${PKG_FLOAT}/opt/vc/include; ls | grep -v "GL"); do + cp -PRv ${PKG_FLOAT}/opt/vc/include/$f ${SYSROOT_PREFIX}/usr/include + done + fi # Install EGL, OpenGL ES, Open VG, etc. vendor libs & pkgconfigs mkdir -p ${SYSROOT_PREFIX}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${SYSROOT_PREFIX}/usr/lib - ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmEGL.so ${SYSROOT_PREFIX}/usr/lib/libEGL.so - ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmGLESv2.so ${SYSROOT_PREFIX}/usr/lib/libGLESv2.so - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.a ${SYSROOT_PREFIX}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig ${SYSROOT_PREFIX}/usr/lib + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${SYSROOT_PREFIX}/usr/lib + ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmEGL.so ${SYSROOT_PREFIX}/usr/lib/libEGL.so + ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmGLESv2.so ${SYSROOT_PREFIX}/usr/lib/libGLESv2.so + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.a ${SYSROOT_PREFIX}/usr/lib + cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig ${SYSROOT_PREFIX}/usr/lib + else + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so *.a | grep -v "GL"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${SYSROOT_PREFIX}/usr/lib + done + mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig + for f in $(cd ${PKG_FLOAT}/opt/vc/lib/pkgconfig; ls | grep -v "gl"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig/$f ${SYSROOT_PREFIX}/usr/lib/pkgconfig + done + fi # Update prefix in vendor pkgconfig files for PKG_CONFIGS in $(find "${SYSROOT_PREFIX}/usr/lib" -type f -name "*.pc" 2>/dev/null); do @@ -46,11 +62,17 @@ make_target() { makeinstall_target() { # Install EGL, OpenGL ES and other vendor libs mkdir -p ${INSTALL}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${INSTALL}/usr/lib - ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so - ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so.1 - ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so - ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so.2 + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${INSTALL}/usr/lib + ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so + ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so.1 + ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so + ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so.2 + else + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so | grep -v "GL"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${INSTALL}/usr/lib + done + fi # Install useful tools mkdir -p ${INSTALL}/usr/bin @@ -68,5 +90,7 @@ makeinstall_target() { post_install() { # unbind Framebuffer console - enable_service unbind-console.service + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + enable_service unbind-console.service + fi } From df47b8be68f527340db9bdc0928ea39b537b7492 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 23 Mar 2019 13:43:47 +0100 Subject: [PATCH 02/23] RPi: always install bcm2835-driver bcm2835-driver provides various tools like vcdbg and tvservice Signed-off-by: Matthias Reichl --- projects/RPi/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/RPi/options b/projects/RPi/options index 3b0654d979..673babb5a5 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -116,7 +116,7 @@ # for a list of additional drivers see packages/linux-drivers # Space separated list is supported, # e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2" - ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS rpi-cirrus-config" + ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS rpi-cirrus-config bcm2835-driver" # build and install driver addons (yes / no) DRIVER_ADDONS_SUPPORT="yes" From 26b2b6317c6e65271a8e8b4ad64e71923eca3728 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 29 Apr 2019 23:38:42 +0200 Subject: [PATCH 03/23] RPi: add alsa card conf for bcm2835-audio Signed-off-by: Matthias Reichl --- .../usr/share/alsa/cards/bcm2835_alsa.conf | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf diff --git a/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf b/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf new file mode 100644 index 0000000000..71b23fadb4 --- /dev/null +++ b/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf @@ -0,0 +1,37 @@ + +bcm2835_alsa.pcm.iec958.0 { + @args [ CARD AES0 AES1 AES2 AES3 ] + @args.CARD { + type string + } + @args.AES0 { + type integer + } + @args.AES1 { + type integer + } + @args.AES2 { + type integer + } + @args.AES3 { + type integer + } + type hooks + slave.pcm { + type hw + card $CARD + device 1 + } + hooks.0 { + type ctl_elems + hook_args [ + { + interface PCM + name "IEC958 Playback Default" + lock true + preserve true + value [ $AES0 $AES1 $AES2 $AES3 ] + } + ] + } +} From 5e495a2bd2df189ee1f70981ce8fdfa222286576 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 3 Jun 2019 15:40:25 +0200 Subject: [PATCH 04/23] libcec: check for RPi project instead of KODIPLAYER_DRIVER Signed-off-by: Matthias Reichl --- packages/devel/libcec/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devel/libcec/package.mk b/packages/devel/libcec/package.mk index 2de020abc6..11fc693a26 100644 --- a/packages/devel/libcec/package.mk +++ b/packages/devel/libcec/package.mk @@ -19,7 +19,7 @@ PKG_CMAKE_OPTS_TARGET="-DBUILD_SHARED_LIBS=1 \ -DHAVE_AOCEC_API=0 -DHAVE_AMLOGIC_API=0 \ -DHAVE_GIT_BIN=0" -if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then +if [ "$PROJECT" = "RPi" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" fi @@ -34,7 +34,7 @@ if [ "$CEC_FRAMEWORK_SUPPORT" = "yes" ]; then fi pre_configure_target() { - if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then + if [ "$PROJECT" = "RPi" ]; then # detecting RPi support fails without -lvchiq_arm export LDFLAGS="$LDFLAGS -lvchiq_arm" fi From 439d3ff31e9a541dc762d9d360f46bab2abbd94a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 5 Mar 2019 21:52:55 +0100 Subject: [PATCH 05/23] config/graphic: also enable v3d and kmsro when building vc4 Signed-off-by: Matthias Reichl --- config/graphic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/graphic b/config/graphic index 2c122b4877..f80b3c7c37 100644 --- a/config/graphic +++ b/config/graphic @@ -107,7 +107,7 @@ get_graphicdrivers() { fi if listcontains "${GRAPHIC_DRIVERS}" "vc4"; then - GALLIUM_DRIVERS+=" vc4" + GALLIUM_DRIVERS+=" vc4 v3d kmsro" V4L2_SUPPORT="yes" VAAPI_SUPPORT="no" VDPAU_SUPPORT="no" From 4d65280e6665a10e4a99763ac8c7cb780a0dc907 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 23 Apr 2019 11:25:06 +0200 Subject: [PATCH 06/23] linux (RPi): update to kernel 71d47f4c4bd7 with RPi4 support Signed-off-by: Matthias Reichl --- packages/linux/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 23b4209360..4a6ea8d6ef 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -23,8 +23,8 @@ case "$LINUX" in PKG_SOURCE_NAME="linux-$LINUX-$PKG_VERSION.tar.gz" ;; raspberrypi) - PKG_VERSION="5040b4b78e4cb74a6364d9a7c6cca0385e2dffd8" # 4.19.50 - PKG_SHA256="134a9821db00c3c826dfeb86be9439a4d0c5b10796f7173a2e5d5728ef2fc979" + PKG_VERSION="71d47f4c4bd7fd395b87c474498187b2f9be8751" + PKG_SHA256="d1ef4b20f0e0435ed1792eccee99d430b06404ba114dbe3f17e0af616a9b748d" PKG_URL="https://github.com/raspberrypi/linux/archive/$PKG_VERSION.tar.gz" PKG_SOURCE_NAME="linux-$LINUX-$PKG_VERSION.tar.gz" ;; From 23c75ecd68440d78a7b094d28bf536c963bafe14 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 10 Jun 2019 11:33:20 +0200 Subject: [PATCH 07/23] bcm2835-bootloader: update to 2b7c80a Signed-off-by: Matthias Reichl --- packages/tools/bcm2835-bootloader/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tools/bcm2835-bootloader/package.mk b/packages/tools/bcm2835-bootloader/package.mk index dd28f623a9..751e7e09cd 100644 --- a/packages/tools/bcm2835-bootloader/package.mk +++ b/packages/tools/bcm2835-bootloader/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="bcm2835-bootloader" -PKG_VERSION="fd15e0700e45d9b7db83e30696aba299b9f2f31d" -PKG_SHA256="c9d32c2355ce4116206b3deae3e340545f345441c0c93ba2347971784fd327ff" +PKG_VERSION="2b7c80a066c9d72dd0703f574ab2f27b3c1c3c3d" +PKG_SHA256="76acf720350bac0458689f563947a51988617f4eb2e83334f5ef1565faa4e350" PKG_ARCH="arm" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com" From 12169b7387a38d5ae07f322a0d630460428f81ae Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 10 Jun 2019 11:33:48 +0200 Subject: [PATCH 08/23] bcm2835-driver: update to 2b7c80a Signed-off-by: Matthias Reichl --- packages/graphics/bcm2835-driver/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/graphics/bcm2835-driver/package.mk b/packages/graphics/bcm2835-driver/package.mk index 4e3372b4bf..7f71085fe4 100644 --- a/packages/graphics/bcm2835-driver/package.mk +++ b/packages/graphics/bcm2835-driver/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="bcm2835-driver" -PKG_VERSION="fd15e0700e45d9b7db83e30696aba299b9f2f31d" -PKG_SHA256="6324b4638b7b3f906469a1d2b94902f608436279749f167ade70e68c5c4c79a7" +PKG_VERSION="2b7c80a066c9d72dd0703f574ab2f27b3c1c3c3d" +PKG_SHA256="3cc783f4acffbcf52b8c303fbf497ed681c1c82210cdd005ccc383742fc07bbc" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com" PKG_URL="${DISTRO_SRC}/${PKG_NAME}-${PKG_VERSION}.tar.xz" From a94ed02bac2009a81fec85bfb58dd1d99eed370d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 3 Jun 2019 19:28:30 +0200 Subject: [PATCH 09/23] bcm2835-bootloader release: copy firmware from INSTALL Signed-off-by: Matthias Reichl --- packages/tools/bcm2835-bootloader/release | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/tools/bcm2835-bootloader/release b/packages/tools/bcm2835-bootloader/release index fbf9e5c545..a2e1ce9aa9 100755 --- a/packages/tools/bcm2835-bootloader/release +++ b/packages/tools/bcm2835-bootloader/release @@ -5,10 +5,10 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) mkdir -p $RELEASE_DIR/3rdparty/bootloader - cp -PR $BUILD/bcm2835-bootloader-*/LICENCE* $RELEASE_DIR/3rdparty/bootloader/ - cp -PR $BUILD/bcm2835-bootloader-*/bootcode.bin $RELEASE_DIR/3rdparty/bootloader/ - cp -PR $BUILD/bcm2835-bootloader-*/fixup_x.dat $RELEASE_DIR/3rdparty/bootloader/fixup.dat - cp -PR $BUILD/bcm2835-bootloader-*/start_x.elf $RELEASE_DIR/3rdparty/bootloader/start.elf + cp -PR $INSTALL/usr/share/bootloader/LICENCE* $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/bootcode.bin $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/fixup.dat $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/start.elf $RELEASE_DIR/3rdparty/bootloader/ if [ -f $(get_build_dir slice-firmware)/dt-blob.bin ]; then cp -PR $(get_build_dir slice-firmware)/dt-blob.bin $RELEASE_DIR/3rdparty/bootloader/ fi From 9917b60837a7d2402333430eaaa66d8ff3a9421d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 10 Jun 2019 19:30:04 +0200 Subject: [PATCH 10/23] scripts/image: copy firmware from INSTALL Signed-off-by: Matthias Reichl --- scripts/image | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/image b/scripts/image index 452decdcb1..5cfb2f8f86 100755 --- a/scripts/image +++ b/scripts/image @@ -389,11 +389,11 @@ if [ "${1}" = "release" -o "${1}" = "mkimage" -o "${1}" = "noobs" ]; then fi # Copy Bootloader - cp -PR ${BUILD}/bcm2835-bootloader-*/LICENCE* ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ - cp -PR ${BUILD}/bcm2835-bootloader-*/bootcode.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ - cp -PR ${BUILD}/bcm2835-bootloader-*/fixup_x.dat ${RELEASE_DIR}/${NOOBS_DISTRO}/System/fixup.dat - cp -PR ${BUILD}/bcm2835-bootloader-*/start_x.elf ${RELEASE_DIR}/${NOOBS_DISTRO}/System/start.elf - [ -f ${BUILD}/bcm2835-bootloader-*/dt-blob.bin ] && cp -PR ${BUILD}/bcm2835-bootloader-*/dt-blob.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/dt-blob.bin + cp -PR ${INSTALL}/usr/share/bootloader/LICENCE* ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/bootcode.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/fixup.dat ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/start.elf ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + [ -f ${INSTALL}/usr/share/bootloader/dt-blob.bin ] && cp -PR ${INSTALL}/usr/share/bootloader/dt-blob.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/dt-blob.bin # Copy system files cp ${TARGET_IMG}/${IMAGE_NAME}.system ${RELEASE_DIR}/${NOOBS_DISTRO}/System/SYSTEM From 1f64a8165d832dce86de0f6624814f3caeca39f8 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Fri, 17 May 2019 22:12:56 +0200 Subject: [PATCH 11/23] ffmpeg: make RPi HEVC optimization patch device specific Signed-off-by: Matthias Reichl --- .../RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch | 1 + .../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch | 0 .../patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch | 1 + .../patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch | 1 + 4 files changed, 3 insertions(+) create mode 120000 projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch rename packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch => projects/RPi/devices/RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch (100%) create mode 120000 projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch create mode 120000 projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch diff --git a/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch rename to projects/RPi/devices/RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch diff --git a/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file diff --git a/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file From d7ca15cce3355667234e401fe5f6f8fc7366dd87 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 23 Mar 2019 13:44:54 +0100 Subject: [PATCH 12/23] ffmpeg: check for RPi project instead of KODIPLAYER_DRIVER Signed-off-by: Matthias Reichl --- packages/multimedia/ffmpeg/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/multimedia/ffmpeg/package.mk b/packages/multimedia/ffmpeg/package.mk index 1ca7bc3148..0ea4308563 100644 --- a/packages/multimedia/ffmpeg/package.mk +++ b/packages/multimedia/ffmpeg/package.mk @@ -57,7 +57,7 @@ else PKG_FFMPEG_DEBUG="--disable-debug --enable-stripping" fi -if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then +if [ "$PROJECT" = "RPi" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" fi @@ -80,7 +80,7 @@ pre_configure_target() { cd $PKG_BUILD rm -rf .$TARGET_NAME - if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then + if [ "$PROJECT" = "RPi" ]; then PKG_FFMPEG_LIBS="-lbcm_host -lvcos -lvchiq_arm -lmmal -lmmal_core -lmmal_util -lvcsm" PKG_FFMPEG_RPI="--enable-rpi" else From 40b068464ba12f17782e30cf85d65762c2692efe Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 21 May 2019 12:58:12 +0200 Subject: [PATCH 13/23] RPi4: add new device Use upstream kodi with gbm/vc4 Signed-off-by: Matthias Reichl --- .../RPi/devices/RPi4/config/distroconfig.txt | 6 + .../RPi/devices/RPi4/linux/linux.arm.conf | 5422 +++++++++++++++++ projects/RPi/devices/RPi4/options | 14 + projects/RPi/options | 5 + 4 files changed, 5447 insertions(+) create mode 100644 projects/RPi/devices/RPi4/config/distroconfig.txt create mode 100644 projects/RPi/devices/RPi4/linux/linux.arm.conf create mode 100644 projects/RPi/devices/RPi4/options diff --git a/projects/RPi/devices/RPi4/config/distroconfig.txt b/projects/RPi/devices/RPi4/config/distroconfig.txt new file mode 100644 index 0000000000..a5670d0691 --- /dev/null +++ b/projects/RPi/devices/RPi4/config/distroconfig.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +# WARNING: DO NOT EDIT THIS FILE - IT WILL BE OVERWRITTEN WHEN UPGRADING! +dtoverlay=vc4-fkms-v3d +disable_overscan=1 diff --git a/projects/RPi/devices/RPi4/linux/linux.arm.conf b/projects/RPi/devices/RPi4/linux/linux.arm.conf new file mode 100644 index 0000000000..eb91978071 --- /dev/null +++ b/projects/RPi/devices/RPi4/linux/linux.arm.conf @@ -0,0 +1,5422 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.19.46 Kernel Configuration +# + +# +# Compiler: gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 +# +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=70200 +CONFIG_CLANG_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="@DISTRONAME@" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_USELIB is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +CONFIG_TREE_SRCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +# CONFIG_MEMCG_SWAP is not set +CONFIG_MEMCG_KMEM=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CGROUP_SCHED=y +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +# CONFIG_CGROUP_PIDS is not set +# CONFIG_CGROUP_RDMA is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +# CONFIG_USER_NS is not set +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_INITRAMFS_FORCE is not set +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_INITRAMFS_COMPRESSION=".gz" +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_BPF=y +CONFIG_EXPERT=y +# CONFIG_UID16 is not set +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +# CONFIG_SYSFS_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_BPF_SYSCALL=y +# CONFIG_USERFAULTFD is not set +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_SYSTEM_DATA_VERIFICATION=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIQ=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=3 + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AXXIA is not set +CONFIG_ARCH_BCM=y + +# +# IPROC architected SoCs +# +# CONFIG_ARCH_BCM_CYGNUS is not set +# CONFIG_ARCH_BCM_HR2 is not set +# CONFIG_ARCH_BCM_NSP is not set +# CONFIG_ARCH_BCM_5301X is not set + +# +# KONA architected SoCs +# +# CONFIG_ARCH_BCM_281XX is not set +# CONFIG_ARCH_BCM_21664 is not set +# CONFIG_ARCH_BCM_23550 is not set + +# +# Other Architectures +# +CONFIG_ARCH_BCM2835=y +# CONFIG_ARCH_BCM_53573 is not set +# CONFIG_ARCH_BCM_63XX is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NPCM is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_TANGO is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_LPAE=y +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_SPECTRE=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_DEBUG_ALIGN_RODATA=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# PCI controller drivers +# + +# +# Cadence PCIe controllers support +# +# CONFIG_PCIE_CADENCE_HOST is not set +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCIE_XILINX is not set +# CONFIG_PCI_V3_SEMI is not set +# CONFIG_PCIE_ALTERA is not set +CONFIG_PCIE_BRCMSTB=y + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCI_LAYERSCAPE is not set + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_ARM_PSCI is not set +CONFIG_ARCH_NR_GPIO=0 +CONFIG_HZ_FIXED=0 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_200 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 +CONFIG_SCHED_HRTICK=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_ARM_PATCH_IDIV=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_GENERIC_GUP=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +CONFIG_UACCESS_WITH_MEMCPY=y +# CONFIG_SECCOMP is not set +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +# CONFIG_XEN is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init usbcore.autosuspend=-1" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_CMDLINE_EXTEND=y +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y +# CONFIG_EFI is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set + +# +# CPU frequency scaling drivers +# +# CONFIG_CPUFREQ_DT is not set +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +CONFIG_ARM_BCM2835_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# ARM CPU Idle Drivers +# +# CONFIG_ARM_CPUIDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y + +# +# Power management options +# +# CONFIG_SUSPEND is not set +# CONFIG_HIBERNATION is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y + +# +# Firmware Drivers +# +# CONFIG_ARM_SCMI_PROTOCOL is not set +# CONFIG_ARM_SCPI_PROTOCOL is not set +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_RASPBERRYPI_FIRMWARE=y +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# Tegra firmware driver +# +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=y +CONFIG_CRYPTO_SHA1_ARM_NEON=y +# CONFIG_CRYPTO_SHA1_ARM_CE is not set +# CONFIG_CRYPTO_SHA2_ARM_CE is not set +CONFIG_CRYPTO_SHA256_ARM=m +# CONFIG_CRYPTO_SHA512_ARM is not set +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +# CONFIG_CRYPTO_AES_ARM_CE is not set +# CONFIG_CRYPTO_GHASH_ARM_CE is not set +CONFIG_CRYPTO_CRC32_ARM_CE=y +# CONFIG_CRYPTO_CHACHA20_NEON is not set +# CONFIG_VIRTUALIZATION is not set + +# +# General architecture-dependent options +# +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +CONFIG_OPTPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_NMI=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_CC_HAS_STACKPROTECTOR_NONE=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_PHYS_TO_DMA=y +CONFIG_REFCOUNT_FULL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_PLUGIN_HOSTCC="" +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_DEV_THROTTLING is not set +# CONFIG_BLK_CMDLINE_PARSER is not set +# CONFIG_BLK_WBT is not set +# CONFIG_BLK_CGROUP_IOLATENCY is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLK_MQ_PCI=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +# CONFIG_BFQ_GROUP_IOSCHED is not set +CONFIG_ASN1=y +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_ELF_FDPIC is not set +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y + +# +# Memory Management options +# +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +CONFIG_CMA_DEBUGFS=y +CONFIG_CMA_AREAS=7 +# CONFIG_ZSWAP is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +# CONFIG_ZSMALLOC is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_BENCHMARK is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +# CONFIG_XDP_SOCKETS is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=m +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +CONFIG_TCP_CONG_ADVANCED=y +# CONFIG_TCP_CONG_BIC is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_CONG_WESTWOOD is not set +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +# CONFIG_TCP_CONG_HYBLA is not set +CONFIG_TCP_CONG_VEGAS=m +# CONFIG_TCP_CONG_NV is not set +CONFIG_TCP_CONG_SCALABLE=m +# CONFIG_TCP_CONG_LP is not set +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_TCP_CONG_DCTCP is not set +CONFIG_TCP_CONG_CDG=m +# CONFIG_TCP_CONG_BBR is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SEG6_HMAC is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_INGRESS is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NETFILTER_NETLINK_OSF is not set +CONFIG_NF_CONNTRACK=m +# CONFIG_NF_LOG_NETDEV is not set +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_ZONES is not set +# CONFIG_NF_CONNTRACK_PROCFS is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CONNTRACK_LABELS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +# CONFIG_NF_CONNTRACK_TFTP is not set +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_NAT=m +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +# CONFIG_NF_SOCKET_IPV4 is not set +# CONFIG_NF_TPROXY_IPV4 is not set +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_IPV4 is not set +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=y +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_NF_SOCKET_IPV6 is not set +# CONFIG_NF_TPROXY_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +CONFIG_NF_REJECT_IPV6=m +# CONFIG_NF_LOG_IPV6 is not set +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_SRH is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_RAW is not set +CONFIG_IP6_NF_NAT=m +# CONFIG_IP6_NF_TARGET_MASQUERADE is not set +# CONFIG_IP6_NF_TARGET_NPT is not set +CONFIG_NF_DEFRAG_IPV6=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_BPFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_CBS is not set +# CONFIG_NET_SCH_ETF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_SKBPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_CODEL is not set +CONFIG_NET_SCH_FQ_CODEL=y +# CONFIG_NET_SCH_CAKE is not set +# CONFIG_NET_SCH_FQ is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_PLUG is not set +# CONFIG_NET_SCH_DEFAULT is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_NCSI is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_LEDS is not set +# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_NOKIA is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_MRVL is not set +CONFIG_BT_HCIBCM203X=m +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=m +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +CONFIG_BT_ATH3K=m +# CONFIG_BT_MTKUART is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set +# CONFIG_LWTUNNEL is not set +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +# CONFIG_NET_DEVLINK is not set +CONFIG_MAY_USE_DEVLINK=y +# CONFIG_FAILOVER is not set +CONFIG_HAVE_EBPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y + +# +# Generic Driver Options +# +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +CONFIG_WANT_DEV_COREDUMP=y +# CONFIG_ALLOW_DEV_COREDUMP is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +CONFIG_GENERIC_ARCH_TOPOLOGY=y + +# +# Bus devices +# +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_SIMPLE_PM_BUS is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_CONNECTOR is not set +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_CDROM=y +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_NBD=y +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set + +# +# NVME Support +# +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TARGET is not set + +# +# Misc devices +# +CONFIG_BCM2835_SMI=m +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +CONFIG_MISC_RTSX=y +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC & related support +# + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# VOP Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# + +# +# VOP Driver +# +# CONFIG_ECHO is not set +# CONFIG_MISC_RTSX_PCI is not set +CONFIG_MISC_RTSX_USB=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_MQ_DEFAULT is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=y +CONFIG_ISCSI_BOOT_SYSFS=y +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_GTP is not set +# CONFIG_MACSEC is not set +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +CONFIG_NET_VENDOR_AURORA=y +# CONFIG_AURORA_NB8800 is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +CONFIG_BCMGENET=y +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_BNXT is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +CONFIG_NET_VENDOR_CORTINA=y +# CONFIG_GEMINI_ETHERNET is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_ICE is not set +# CONFIG_FM10K is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLXSW_CORE is not set +# CONFIG_MLXFW is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +# CONFIG_LAN743X is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_NETERION=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_NETRONOME=y +# CONFIG_NFP is not set +CONFIG_NET_VENDOR_NI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_AX88796 is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_QED is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000_SPI is not set +# CONFIG_QCA7000_UART is not set +# CONFIG_QCOM_EMAC is not set +# CONFIG_RMNET is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SOLARFLARE=y +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_SOCIONEXT=y +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_ALE is not set +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_BCM_UNIMAC=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MSCC_MIIM is not set +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_ASIX_PHY is not set +# CONFIG_AT803X_PHY is not set +CONFIG_BCM7XXX_PHY=y +# CONFIG_BCM87XX_PHY is not set +CONFIG_BCM_NET_PHYLIB=y +CONFIG_BROADCOM_PHY=y +# CONFIG_CICADA_PHY is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_ICPLUS_PHY is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MICREL_PHY is not set +CONFIG_MICROCHIP_PHY=y +# CONFIG_MICROCHIP_T1_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_RENESAS_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_MPPE=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +CONFIG_USB_NET_DM9601=y +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +CONFIG_USB_HSO=m +# CONFIG_USB_NET_INT51X1 is not set +CONFIG_USB_IPHETH=m +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +# CONFIG_WIRELESS_WDS is not set +CONFIG_WLAN_VENDOR_ADMTEK=y +# CONFIG_ADM8211 is not set +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH5K_PCI is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_ATH9K_HWRNG=y +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +# CONFIG_ATH6KL_SDIO is not set +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +# CONFIG_WIL6210 is not set +# CONFIG_ATH10K is not set +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +CONFIG_WLAN_VENDOR_ATMEL=y +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +# CONFIG_B43_SDIO is not set +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCMFMAC_PCIE is not set +# CONFIG_BRCM_TRACING is not set +CONFIG_BRCMDBG=y +CONFIG_WLAN_VENDOR_CISCO=y +CONFIG_WLAN_VENDOR_INTEL=y +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWLWIFI is not set +CONFIG_WLAN_VENDOR_INTERSIL=y +# CONFIG_HOSTAP is not set +# CONFIG_HERMES is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +# CONFIG_P54_PCI is not set +# CONFIG_P54_SPI is not set +CONFIG_P54_LEDS=y +# CONFIG_PRISM54 is not set +CONFIG_WLAN_VENDOR_MARVELL=y +# CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_MWIFIEX is not set +# CONFIG_MWL8K is not set +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x0U=m +# CONFIG_MT76x2E is not set +CONFIG_MT76x2U=m +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT61PCI is not set +# CONFIG_RT2800PCI is not set +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +# CONFIG_RTL8180 is not set +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +# CONFIG_RTL8192CE is not set +# CONFIG_RTL8192SE is not set +# CONFIG_RTL8192DE is not set +# CONFIG_RTL8723AE is not set +# CONFIG_RTL8723BE is not set +# CONFIG_RTL8188EE is not set +# CONFIG_RTL8192EE is not set +# CONFIG_RTL8821AE is not set +# CONFIG_RTL8192CU is not set +# CONFIG_RTL8XXXU is not set +CONFIG_WLAN_VENDOR_RSI=y +# CONFIG_RSI_91X is not set +CONFIG_WLAN_VENDOR_ST=y +# CONFIG_CW1200 is not set +CONFIG_WLAN_VENDOR_TI=y +# CONFIG_WL1251 is not set +# CONFIG_WL12XX is not set +# CONFIG_WL18XX is not set +# CONFIG_WLCORE is not set +CONFIG_WLAN_VENDOR_ZYDAS=y +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_USB_NET_RNDIS_WLAN=m + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_NETDEVSIM is not set +# CONFIG_NET_FAILOVER is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_PSXPAD_SPI=m +CONFIG_JOYSTICK_PSXPAD_SPI_FF=y +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_RPISENSE is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_ADS7846=m +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_BU21029 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +CONFIG_TOUCHSCREEN_EGALAX=m +# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set +# CONFIG_TOUCHSCREEN_EXC3000 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_HIDEEP is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_S6SY761 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_EKTF2127 is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +CONFIG_TOUCHSCREEN_RPI_FT5406=m +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set +CONFIG_TOUCHSCREEN_USB_3M=y +# CONFIG_TOUCHSCREEN_USB_ITM is not set +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set +# CONFIG_TOUCHSCREEN_USB_ELO is not set +# CONFIG_TOUCHSCREEN_USB_E2I is not set +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_RM_TS is not set +# CONFIG_TOUCHSCREEN_SILEAD is not set +# CONFIG_TOUCHSCREEN_SIS_I2C is not set +CONFIG_TOUCHSCREEN_ST1232=m +# CONFIG_TOUCHSCREEN_STMFTS is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZET6223 is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ARIZONA_HAPTICS is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_PWM_VIBRA is not set +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_RMI4_CORE=y +# CONFIG_RMI4_I2C is not set +# CONFIG_RMI4_SPI is not set +# CONFIG_RMI4_SMB is not set +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=y +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +# CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F55 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM2708_VCMEM=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=m +CONFIG_BCM2835_SMI_DEV=m +CONFIG_ARGON_MEM=m +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_8250_FSL=y +# CONFIG_SERIAL_8250_DW is not set +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_MOXA is not set +CONFIG_SERIAL_OF_PLATFORM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +CONFIG_SERIAL_DEV_BUS=m +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_BCM2835=y +CONFIG_HW_RANDOM_IPROC_RNG200=y +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_DEMUX_PINCTRL is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_BCM2708=y +CONFIG_I2C_BCM2708_BAUDRATE=100000 +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_BCM2835=m +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_MEM is not set + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BCM2835=m +CONFIG_SPI_BCM2835AUX=m +# CONFIG_SPI_BCM_QSPI is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_ROCKCHIP is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +# CONFIG_PPS is not set + +# +# PTP clock support +# +# CONFIG_PTP_1588_CLOCK is not set + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_BCM2835=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +CONFIG_GPIO_RASPBERRYPI_EXP=y +CONFIG_GPIO_BCM_VIRT=y +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_FTGPIO010 is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_MPC8XXX is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set + +# +# MFD GPIO expanders +# +CONFIG_GPIO_ARIZONA=m +# CONFIG_HTC_EGPIO is not set + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_PCI_IDIO_16 is not set +# CONFIG_GPIO_PCIE_IDIO_24 is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set + +# +# USB GPIO expanders +# +CONFIG_W1=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_MATROX is not set +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2405 is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2413 is not set +# CONFIG_W1_SLAVE_DS2406 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2805 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2438 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_DS28E04 is not set +# CONFIG_W1_SLAVE_DS28E17 is not set +# CONFIG_POWER_AVS is not set +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMKONA is not set +# CONFIG_POWER_RESET_BRCMSTB is not set +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +CONFIG_POWER_RESET_RESTART=y +# CONFIG_POWER_RESET_VERSATILE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_SYSCON_REBOOT_MODE is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_LTC3651 is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASPEED is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FTSTEUTATES is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX6621 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +CONFIG_SENSORS_RASPBERRYPI_HWMON=y +CONFIG_SENSORS_RPI_POE_FAN=m +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_STTS751 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83773G is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_CPU_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_QORIQ_THERMAL is not set + +# +# ACPI INT340X thermal drivers +# + +# +# Broadcom thermal drivers +# +CONFIG_BCM2835_THERMAL=y +CONFIG_BRCMSTB_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +# CONFIG_WATCHDOG_SYSFS is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_FTWDT010_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +CONFIG_BCM2835_WDT=y +# CONFIG_MEN_A21_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y +CONFIG_BCMA_DRIVER_GMAC_CMN=y +# CONFIG_BCMA_DRIVER_GPIO is not set +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_RPISENSE_CORE is not set +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MFD_VX855 is not set +CONFIG_MFD_ARIZONA=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +# CONFIG_MFD_CS47L24 is not set +CONFIG_MFD_WM5102=y +# CONFIG_MFD_WM5110 is not set +# CONFIG_MFD_WM8997 is not set +# CONFIG_MFD_WM8998 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_88PG86X is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +# CONFIG_REGULATOR_PWM is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +# CONFIG_IR_HIX5HD2 is not set +CONFIG_IR_IMON=m +CONFIG_IR_IMON_RAW=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +# CONFIG_IR_SPI is not set +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +# CONFIG_RC_LOOPBACK is not set +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +# CONFIG_IR_SERIAL is not set +# CONFIG_IR_SIR is not set +CONFIG_RC_XBOX_DVD=m +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_PCI_SKELETON is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_DVB_CORE=m +# CONFIG_DVB_MMAP is not set +CONFIG_DVB_NET=y +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_VIDEO_USBTV=m + +# +# Analog TV USB devices +# +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160=m +# CONFIG_VIDEO_GO7007 is not set + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +# CONFIG_VIDEO_CX231XX_ALSA is not set +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +# CONFIG_VIDEO_TM6000_ALSA is not set +CONFIG_VIDEO_TM6000_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB3000MC=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_ZD1301=m +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_EM28XX_V4L2 is not set +# CONFIG_VIDEO_EM28XX_ALSA is not set +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m +# CONFIG_MEDIA_PCI_SUPPORT is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set + +# +# Supported MMC/SDIO adapters +# +CONFIG_SMS_SDIO_DRV=m +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +# CONFIG_SMS_SIANO_DEBUGFS is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y +CONFIG_VIDEO_IR_I2C=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m + +# +# RDS decoders +# + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# Video encoders +# + +# +# Camera sensor devices +# + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Audio/Video compression chips +# + +# +# SDR tuner chips +# + +# +# Miscellaneous helper chips +# + +# +# Sensors used on soc_camera driver +# + +# +# Media SPI Adapters +# +CONFIG_CXD2880_SPI_DRV=m +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_CXD2880=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LGDT3306A=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +CONFIG_DVB_TC90522=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_DRX39XYJ=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m + +# +# Common Interface (EN50221) controller drivers +# +CONFIG_DVB_SP2=m + +# +# Tools to develop new frontends +# + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_DRM=y +CONFIG_DRM_MIPI_DSI=y +# CONFIG_DRM_DP_AUX_CHARDEV is not set +# CONFIG_DRM_DEBUG_MM is not set +# CONFIG_DRM_DEBUG_SELFTEST is not set +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_DP_CEC is not set +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_SCHED=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_AMDGPU is not set + +# +# ACP (Audio CoProcessor) Configuration +# + +# +# AMD Library routines +# +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_EXYNOS is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_RCAR_DW_HDMI is not set +# CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_OMAP is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_QXL is not set +# CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_FSL_DCU is not set +# CONFIG_DRM_STM is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_LVDS is not set +# CONFIG_DRM_PANEL_SIMPLE is not set +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set +# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set +# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_LVDS_ENCODER is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_STI is not set +CONFIG_DRM_V3D=y +CONFIG_DRM_VC4=y +# CONFIG_DRM_VC4_HDMI_CEC is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_TINYDRM is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_TVE200 is not set +# CONFIG_DRM_LEGACY is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +CONFIG_FB_NOTIFY=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_BCM2708=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +# CONFIG_FB_RPISENSE is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set +# CONFIG_LCD_OTM3225A is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +# CONFIG_BACKLIGHT_PWM is not set +CONFIG_BACKLIGHT_RPI=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +CONFIG_BACKLIGHT_GPIO=y +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_ARCXCNN is not set +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_PCM_TIMER=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SE6X is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# HD-Audio +# +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDA_PREALLOC_SIZE=2048 +CONFIG_SND_ARM=y +# CONFIG_SND_ARMAACI is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_BCD2000=m +CONFIG_SND_USB_LINE6=m +CONFIG_SND_USB_POD=m +CONFIG_SND_USB_PODHD=m +CONFIG_SND_USB_TONEPORT=m +CONFIG_SND_USB_VARIAX=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_COMPRESS=y +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m +CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m +CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOSENSE_PI=m +CONFIG_SND_DIGIDAC1_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m +CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m +CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m +CONFIG_SND_PISOUND=m +CONFIG_SND_RPI_SIMPLE_SOUNDCARD=m +CONFIG_SND_RPI_WM8804_SOUNDCARD=m +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_I2S_HI6210_I2S is not set +# CONFIG_SND_SOC_IMG is not set + +# +# STMicroelectronics STM32 SOC audio support +# +# CONFIG_SND_SOC_XTFPGA_I2S is not set +# CONFIG_ZX_TDM is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +CONFIG_SND_SOC_ARIZONA=m +CONFIG_SND_SOC_WM_ADSP=m +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_AD193X_SPI is not set +# CONFIG_SND_SOC_AD193X_I2C is not set +CONFIG_SND_SOC_ADAU1701=m +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +CONFIG_SND_SOC_ADAU1977=m +CONFIG_SND_SOC_ADAU1977_I2C=m +CONFIG_SND_SOC_ADAU7002=m +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4458 is not set +CONFIG_SND_SOC_AK4554=m +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_AK5558 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_BD28623 is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +CONFIG_SND_SOC_CS4265=m +# CONFIG_SND_SOC_CS4270 is not set +CONFIG_SND_SOC_CS4271=m +CONFIG_SND_SOC_CS4271_I2C=m +# CONFIG_SND_SOC_CS4271_SPI is not set +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m +# CONFIG_SND_SOC_CS43130 is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DMIC=m +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8328_SPI is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_ICS43432 is not set +# CONFIG_SND_SOC_INNO_RK3036 is not set +# CONFIG_SND_SOC_MAX98504 is not set +# CONFIG_SND_SOC_MAX9867 is not set +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MAX98373 is not set +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1789_I2C is not set +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +# CONFIG_SND_SOC_PCM186X_I2C is not set +# CONFIG_SND_SOC_PCM186X_SPI is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +CONFIG_SND_SOC_PCM5102A=m +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_RT5616 is not set +CONFIG_SND_SOC_PCM1794A=m +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_I2C=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=m +# CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +CONFIG_SND_SOC_STA32X=m +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS6424 is not set +# CONFIG_SND_SOC_TDA7419 is not set +# CONFIG_SND_SOC_TFA9879 is not set +CONFIG_SND_SOC_TAS5713=m +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_TSCS42XX is not set +# CONFIG_SND_SOC_TSCS454 is not set +CONFIG_SND_SOC_WM5102=m +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +CONFIG_SND_SOC_WM8731=m +# CONFIG_SND_SOC_WM8737 is not set +CONFIG_SND_SOC_WM8741=m +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8782 is not set +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_ZX_AUD96P22 is not set +# CONFIG_SND_SOC_MAX9759 is not set +# CONFIG_SND_SOC_MT6351 is not set +# CONFIG_SND_SOC_NAU8540 is not set +# CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8824 is not set +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_I_SABRE_CODEC=m +CONFIG_SND_SIMPLE_CARD_UTILS=m +CONFIG_SND_SIMPLE_CARD=m +# CONFIG_SND_SIMPLE_SCU_CARD is not set +CONFIG_SND_AUDIO_GRAPH_CARD=m +# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +# CONFIG_HID_APPLEIR is not set +CONFIG_HID_ASUS=y +CONFIG_HID_AUREAL=y +CONFIG_HID_BELKIN=y +# CONFIG_HID_BETOP_FF is not set +CONFIG_HID_BIGBEN_FF=m +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CP2112 is not set +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELAN is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GOOGLE_HAMMER is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +CONFIG_HID_KYE=y +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +CONFIG_HID_GYRATION=y +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=y +# CONFIG_HID_LED is not set +CONFIG_HID_LENOVO=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=y +CONFIG_HID_LOGITECH_HIDPP=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_REDRAGON is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_MULTITOUCH=m +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +CONFIG_HID_ORTEK=y +CONFIG_HID_OUYA=y +CONFIG_HID_PANTHERLORD=y +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=y +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_SONY_FF=y +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +CONFIG_HID_SUNPLUS=y +CONFIG_HID_RMI=y +# CONFIG_HID_GREENASIA is not set +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=y +CONFIG_HID_TOPSEED=y +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_WACOM is not set +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=y +# CONFIG_HID_ZEROPLUS is not set +CONFIG_HID_ZYDACRON=y +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +# CONFIG_I2C_HID is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=y +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_DWCOTG=y +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_F8153X is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_IUU=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_UPD78F0730 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 +CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_SDHCI_IPROC=y +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_CQHCI is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_BCM2835 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MMC_SDHCI_OMAP is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=y +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_CR0014114 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_LM3601X is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_KTD2692 is not set +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_SYSCON is not set +# CONFIG_LEDS_MLXREG is not set +# CONFIG_LEDS_USER is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +# CONFIG_LEDS_TRIGGER_ACTIVITY is not set +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_LEDS_TRIGGER_INPUT=y +# CONFIG_LEDS_TRIGGER_PANIC is not set +# CONFIG_LEDS_TRIGGER_NETDEV is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +# CONFIG_RTC_DRV_DS1307_CENTURY is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF8523=m +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +CONFIG_RTC_DRV_PCF8563=m +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_DS3232_HWMON=y +CONFIG_RTC_DRV_PCF2127=m +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_R7301 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DMA_OF=y +# CONFIG_ALTERA_MSGDMA is not set +# CONFIG_AMBA_PL08X is not set +CONFIG_DMA_BCM2835=y +# CONFIG_DW_AXI_DMAC is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_BCM2708=y +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_VIRTIO_MENU is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +CONFIG_RTL8723BS=m +CONFIG_R8712U=m +# CONFIG_R8188EU is not set +# CONFIG_R8822BE is not set +# CONFIG_RTS5208 is not set +# CONFIG_VT6655 is not set +CONFIG_VT6656=m +# CONFIG_FB_SM750 is not set +# CONFIG_FB_XGI is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +CONFIG_STAGING_MEDIA=y + +# +# Android +# +# CONFIG_STAGING_BOARD is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_DGNC is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_UNISYSSPAR is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +# CONFIG_MOST is not set +# CONFIG_KS7010 is not set +# CONFIG_GREYBUS is not set +CONFIG_BCM_VIDEOCORE=y +CONFIG_BCM2835_VCHIQ=y +CONFIG_SND_BCM2835=m +# CONFIG_VIDEO_BCM2835 is not set +CONFIG_BCM2835_VCHIQ_MMAL=m +CONFIG_BCM_VC_SM_CMA=y +CONFIG_VIDEO_CODEC_BCM2835=m +# CONFIG_PI433 is not set +# CONFIG_MTK_MMC is not set + +# +# Gasket devices +# +# CONFIG_XIL_AXIS_FIFO is not set +# CONFIG_EROFS_FS is not set +# CONFIG_GOLDFISH is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_CLK_HSDK is not set +# CONFIG_COMMON_CLK_MAX9485 is not set +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_BCM2835_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_TIMER_SP804=y +CONFIG_MAILBOX=y +# CONFIG_ARM_MHU is not set +# CONFIG_PLATFORM_MHU is not set +# CONFIG_PL320_MBOX is not set +# CONFIG_ALTERA_MBOX is not set +CONFIG_BCM2835_MBOX=y +# CONFIG_MAILBOX_TEST is not set +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# + +# +# Broadcom SoC drivers +# +CONFIG_BCM2835_POWER=y +CONFIG_RASPBERRYPI_POWER=y +# CONFIG_SOC_BRCMSTB is not set + +# +# NXP/Freescale QorIQ SoC drivers +# + +# +# i.MX SoC drivers +# + +# +# Qualcomm SoC drivers +# +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# CONFIG_XILINX_VCU is not set +# CONFIG_PM_DEVFREQ is not set +CONFIG_EXTCON=m + +# +# Extcon Device Drivers +# +CONFIG_EXTCON_ARIZONA=m +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +CONFIG_PWM_BCM2835=m +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_IPACK_BUS is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +# CONFIG_GENERIC_PHY is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# CONFIG_ARM_CCI_PMU is not set +# CONFIG_ARM_CCN is not set +CONFIG_ARM_PMU=y +CONFIG_RPI_AXIPERF=m +# CONFIG_RAS is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_LIBNVDIMM is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# CONFIG_FPGA is not set +# CONFIG_FSI is not set +# CONFIG_TEE is not set +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_FS_IOMAP=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_FS_REF_VERIFY is not set +# CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +CONFIG_MANDATORY_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set +CONFIG_OVERLAY_FS=m +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set + +# +# Caches +# +CONFIG_FSCACHE=y +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_FAT_DEFAULT_UTF8 is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLBFS is not set +CONFIG_MEMFD_CREATE=y +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_FSCACHE=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_RSA=y +# CONFIG_CRYPTO_DH is not set +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=m +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIMD=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_AEGIS128 is not set +# CONFIG_CRYPTO_AEGIS128L is not set +# CONFIG_CRYPTO_AEGIS256 is not set +# CONFIG_CRYPTO_MORUS640 is not set +# CONFIG_CRYPTO_MORUS1280 is not set +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y +# CONFIG_CRYPTO_CRCT10DIF is not set +CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_SHA3 is not set +# CONFIG_CRYPTO_SM3 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SM4 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_ZSTD is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +# CONFIG_CRYPTO_HW is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC4 is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +# CONFIG_CRC8 is not set +CONFIG_XXHASH=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMPRESS=m +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SGL_ALLOC=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +# CONFIG_IRQ_POLL is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_SBITMAP=y +# CONFIG_STRING_SELFTEST is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +# CONFIG_DEBUG_INFO is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +CONFIG_TRACE_IRQFLAGS=y +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_PREEMPTIRQ_TRACEPOINTS=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_PREEMPTIRQ_EVENTS is not set +CONFIG_IRQSOFF_TRACER=y +CONFIG_SCHED_TRACER=y +# CONFIG_HWLAT_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +CONFIG_TRACER_SNAPSHOT=y +CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENTS=y +# CONFIG_UPROBE_EVENTS is not set +CONFIG_BPF_EVENTS=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +# CONFIG_MEMTEST is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_UBSAN is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM_PTDUMP_DEBUGFS is not set +# CONFIG_DEBUG_WX is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_ARM_KPROBES_TEST is not set +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_CORESIGHT is not set diff --git a/projects/RPi/devices/RPi4/options b/projects/RPi/devices/RPi4/options new file mode 100644 index 0000000000..6ddbf5a871 --- /dev/null +++ b/projects/RPi/devices/RPi4/options @@ -0,0 +1,14 @@ +################################################################################ +# Device defaults +################################################################################ + + # NOOBS supported hex versions (legacy) + NOOBS_HEX="1040,1041,2082" + + # NOOBS supported model versions + NOOBS_SUPPORTED_MODELS='"Pi 4"' + + OPENGLES="mesa" + GRAPHIC_DRIVERS="vc4" + KODIPLAYER_DRIVER="mesa" + unset KODI_VENDOR diff --git a/projects/RPi/options b/projects/RPi/options index 673babb5a5..4e80d70494 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -12,6 +12,9 @@ TARGET_CPU="arm1176jzf-s" elif [ "$DEVICE" = "RPi2" -o "$DEVICE" = "Slice3" ]; then TARGET_CPU="cortex-a7" + elif [ "$DEVICE" = "RPi4" ]; then + TARGET_CPU="cortex-a53" + TARGET_CPU_FLAGS="+crc" fi # TARGET_FLOAT: @@ -27,6 +30,8 @@ TARGET_FPU="vfp" elif [ "$DEVICE" = "RPi2" -o "$DEVICE" = "Slice3" ]; then TARGET_FPU="neon-vfpv4" + elif [ "$DEVICE" = "RPi4" ]; then + TARGET_FPU="neon-fp-armv8" fi TARGET_FEATURES="32bit" ;; From edf491d1c1ed8354fe7a38704c757f0d9e39ae83 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 3 Jun 2019 20:14:01 +0200 Subject: [PATCH 14/23] bcm2835-bootloader: use start4x/fixup4x for RPi4 Signed-off-by: Matthias Reichl --- packages/tools/bcm2835-bootloader/package.mk | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/tools/bcm2835-bootloader/package.mk b/packages/tools/bcm2835-bootloader/package.mk index 751e7e09cd..4c2e0cbef4 100644 --- a/packages/tools/bcm2835-bootloader/package.mk +++ b/packages/tools/bcm2835-bootloader/package.mk @@ -17,8 +17,13 @@ makeinstall_target() { mkdir -p $INSTALL/usr/share/bootloader cp -PRv LICENCE* $INSTALL/usr/share/bootloader cp -PRv bootcode.bin $INSTALL/usr/share/bootloader - cp -PRv fixup_x.dat $INSTALL/usr/share/bootloader/fixup.dat - cp -PRv start_x.elf $INSTALL/usr/share/bootloader/start.elf + if [ "$DEVICE" = "RPi4" ]; then + cp -PRv fixup4x.dat $INSTALL/usr/share/bootloader/fixup.dat + cp -PRv start4x.elf $INSTALL/usr/share/bootloader/start.elf + else + cp -PRv fixup_x.dat $INSTALL/usr/share/bootloader/fixup.dat + cp -PRv start_x.elf $INSTALL/usr/share/bootloader/start.elf + fi find_file_path config/dt-blob.bin && cp -PRv $FOUND_PATH $INSTALL/usr/share/bootloader From bde8334d50ae6cab83711a8c86c0c2382a683b66 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Fri, 17 May 2019 22:15:00 +0200 Subject: [PATCH 15/23] ffmpeg (RPi4): add patch to use HEVC hardware decoder Signed-off-by: Matthias Reichl --- .../ffmpeg-001-pfcd_hevc_optimisations.patch | 4102 +++++++++++++++++ 1 file changed, 4102 insertions(+) create mode 100644 projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch diff --git a/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 100644 index 0000000000..317adbdbf9 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1,4102 @@ +diff --git a/configure b/configure +index 2c9359273c..36258ed184 100755 +--- a/configure ++++ b/configure +@@ -1788,6 +1788,8 @@ HWACCEL_LIBRARY_LIST=" + omx + opencl + v4l2_request ++ rpi4_8 ++ rpi4_10 + " + + DOCUMENT_LIST=" +@@ -1849,6 +1851,7 @@ SUBSYSTEM_LIST=" + pixelutils + network + rdft ++ rpi + " + + # COMPONENT_LIST needs to come last to ensure correct dependency checking +@@ -2318,6 +2321,7 @@ CONFIG_EXTRA=" + rangecoder + riffdec + riffenc ++ rpi + rtpdec + rtpenc_chain + rv34dsp +diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c +index c0214c42d8..3f43b58cbb 100644 +--- a/fftools/ffmpeg.c ++++ b/fftools/ffmpeg.c +@@ -23,6 +23,11 @@ + * multimedia converter based on the FFmpeg libraries + */ + ++#ifdef RPI ++//#define RPI_DISPLAY ++#define RPI_DISPLAY_ALL 0 ++#endif ++ + #include "config.h" + #include + #include +@@ -70,6 +75,24 @@ + # include "libavfilter/buffersrc.h" + # include "libavfilter/buffersink.h" + ++#ifdef RPI_DISPLAY ++#pragma GCC diagnostic push ++// Many many redundant decls in the header files ++#pragma GCC diagnostic ignored "-Wredundant-decls" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#pragma GCC diagnostic pop ++#include "libavcodec/rpi_qpu.h" ++#include "libavcodec/rpi_zc.h" ++#endif ++ + #if HAVE_SYS_RESOURCE_H + #include + #include +@@ -162,6 +185,247 @@ static int restore_tty; + static void free_input_threads(void); + #endif + ++#ifdef RPI_DISPLAY ++ ++#define NUM_BUFFERS 4 ++ ++ ++typedef struct rpi_display_env_s ++{ ++ MMAL_COMPONENT_T* display; ++ MMAL_COMPONENT_T* isp; ++ MMAL_PORT_T * port_in; // Input port of either isp or display depending on pipe setup ++ MMAL_CONNECTION_T * conn; ++ ++ MMAL_POOL_T *rpi_pool; ++ volatile int rpi_display_count; ++ enum AVPixelFormat avfmt; ++} rpi_display_env_t; ++ ++static rpi_display_env_t * rpi_display_env = NULL; ++ ++ ++static MMAL_POOL_T* display_alloc_pool(MMAL_PORT_T* port) ++{ ++ MMAL_POOL_T* pool; ++ mmal_port_parameter_set_boolean(port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); // Does this mark that the buffer contains a vc_handle? Would have expected a vc_image? ++ pool = mmal_port_pool_create(port, NUM_BUFFERS, 0); ++ assert(pool); ++ ++ return pool; ++} ++ ++static void display_cb_input(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { ++ rpi_display_env_t *const de = (rpi_display_env_t *)port->userdata; ++ av_rpi_zc_unref(buffer->user_data); ++ atomic_fetch_add(&de->rpi_display_count, -1); ++ mmal_buffer_header_release(buffer); ++} ++ ++static void display_cb_control(MMAL_PORT_T *port,MMAL_BUFFER_HEADER_T *buffer) { ++ mmal_buffer_header_release(buffer); ++} ++ ++#define DISPLAY_PORT_DEPTH 4 ++ ++static rpi_display_env_t * ++display_init(const enum AVPixelFormat req_fmt, size_t x, size_t y, size_t w, size_t h) ++{ ++ MMAL_STATUS_T err; ++ MMAL_DISPLAYREGION_T region = ++ { ++ .hdr = {MMAL_PARAMETER_DISPLAYREGION, sizeof(region)}, ++ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_DEST_RECT, ++ .layer = 2, ++ .fullscreen = 0, ++ .dest_rect = {x, y, w, h} ++ }; ++#if RPI_ZC_SAND_8_IN_10_BUF ++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10 || av_rpi_is_sand_format(req_fmt)) ? AV_PIX_FMT_SAND128 : req_fmt; ++#else ++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10) ? AV_PIX_FMT_SAND128 : req_fmt; ++#endif ++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(fmt, w, h); ++ rpi_display_env_t * de; ++ int isp_req = (fmt == AV_PIX_FMT_SAND64_10); ++ ++ bcm_host_init(); // Needs to be done by someone... ++ ++ if ((de = av_mallocz(sizeof(*de))) == NULL) { ++ return NULL; ++ } ++ ++ mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &de->display); ++ av_assert0(de->display); ++ de->port_in = de->display->input[0]; ++ ++ if (isp_req) ++ { ++ mmal_component_create("vc.ril.isp", &de->isp); ++ de->port_in = de->isp->input[0]; ++ } ++ ++ mmal_port_parameter_set(de->display->input[0], ®ion.hdr); ++ ++ { ++ MMAL_PORT_T * const port = de->port_in; ++ MMAL_ES_FORMAT_T* const format = port->format; ++ port->userdata = (struct MMAL_PORT_USERDATA_T *)de; ++ port->buffer_num = DISPLAY_PORT_DEPTH; ++ format->encoding = ++ fmt == AV_PIX_FMT_SAND128 ? MMAL_ENCODING_YUVUV128 : ++ fmt == AV_PIX_FMT_RPI4_8 ? MMAL_ENCODING_YUVUV128 : ++ fmt == AV_PIX_FMT_RPI4_10 ? MMAL_ENCODING_YUV10_COL : ++ fmt == AV_PIX_FMT_SAND64_10 ? MMAL_ENCODING_YUVUV64_16 : ++ MMAL_ENCODING_I420; ++ format->es->video.width = geo.stride_y; ++ format->es->video.height = (fmt == AV_PIX_FMT_SAND128 || ++ fmt == AV_PIX_FMT_RPI4_8 || ++ fmt == AV_PIX_FMT_RPI4_10 || ++ fmt == AV_PIX_FMT_SAND64_10) ? ++ (h + 15) & ~15 : geo.height_y; // Magic ++ format->es->video.crop.x = 0; ++ format->es->video.crop.y = 0; ++ format->es->video.crop.width = w; ++ format->es->video.crop.height = h; ++ mmal_port_format_commit(port); ++ } ++ ++ de->rpi_pool = display_alloc_pool(de->port_in); ++ mmal_port_enable(de->port_in,display_cb_input); ++ ++ if (isp_req) { ++ MMAL_PORT_T * const port_out = de->isp->output[0]; ++ mmal_log_dump_port(de->port_in); ++ mmal_format_copy(port_out->format, de->port_in->format); ++ if (fmt == AV_PIX_FMT_SAND64_10) { ++ if ((err = mmal_port_parameter_set_int32(de->port_in, MMAL_PARAMETER_CCM_SHIFT, 5)) != MMAL_SUCCESS || ++ (err = mmal_port_parameter_set_int32(port_out, MMAL_PARAMETER_OUTPUT_SHIFT, 1)) != MMAL_SUCCESS) ++ { ++ av_log(NULL, AV_LOG_WARNING, "Failed to set ISP output port shift\n"); ++ } ++ else ++ av_log(NULL, AV_LOG_WARNING, "Set ISP output port shift OK\n"); ++ ++ } ++ port_out->format->encoding = MMAL_ENCODING_I420; ++ mmal_log_dump_port(port_out); ++ if ((err = mmal_port_format_commit(port_out)) != MMAL_SUCCESS) ++ { ++ av_log(NULL, AV_LOG_ERROR, "Failed to set ISP output port format\n"); ++ goto fail; ++ } ++ if ((err = mmal_connection_create(&de->conn, port_out, de->display->input[0], MMAL_CONNECTION_FLAG_TUNNELLING)) != MMAL_SUCCESS) { ++ av_log(NULL, AV_LOG_ERROR, "Failed to create connection\n"); ++ goto fail; ++ } ++ if ((err = mmal_connection_enable(de->conn)) != MMAL_SUCCESS) { ++ av_log(NULL, AV_LOG_ERROR, "Failed to enable connection\n"); ++ goto fail; ++ } ++ mmal_port_enable(de->isp->control,display_cb_control); ++ mmal_component_enable(de->isp); ++ } ++ ++ mmal_component_enable(de->display); ++ mmal_port_enable(de->display->control,display_cb_control); ++ de->avfmt = fmt; ++ ++ printf("Allocated display %dx%d in %dx%d, fmt=%d\n", w, h, geo.stride_y, geo.height_y, fmt); ++ ++ return de; ++ ++fail: ++ // **** Free stuff ++ return NULL; ++} ++ ++static void display_frame(struct AVCodecContext * const s, rpi_display_env_t * const de, const AVFrame* const fr) ++{ ++ MMAL_BUFFER_HEADER_T* buf; ++ ++ if (de == NULL) ++ return; ++ ++ if (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { ++ av_log(s, AV_LOG_VERBOSE, "Frame dropped\n"); ++ return; ++ } ++ ++ buf = mmal_queue_get(de->rpi_pool->queue); ++ if (!buf) { ++ // Running too fast so drop the frame ++ printf("Q alloc failure\n"); ++ return; ++ } ++ assert(buf); ++ buf->cmd = 0; ++ buf->offset = 0; // Offset to valid data ++ buf->flags = 0; ++ { ++ const AVRpiZcRefPtr fr_buf = av_rpi_zc_ref(s, fr, de->avfmt, 1); ++ if (fr_buf == NULL) { ++ mmal_buffer_header_release(buf); ++ return; ++ } ++ ++ buf->user_data = fr_buf; ++ buf->data = (uint8_t *)av_rpi_zc_vc_handle(fr_buf); // Cast our handle to a pointer for mmal ++ buf->offset = av_rpi_zc_offset(fr_buf); ++ buf->length = av_rpi_zc_length(fr_buf); ++ buf->alloc_size = av_rpi_zc_numbytes(fr_buf); ++ atomic_fetch_add(&de->rpi_display_count, 1); ++ } ++#if RPI_DISPLAY_ALL ++ while (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { ++ usleep(5000); ++ } ++#endif ++ ++ if (mmal_port_send_buffer(de->port_in, buf) != MMAL_SUCCESS) ++ { ++ av_log(s, AV_LOG_ERROR, "mmal_port_send_buffer failed: depth=%d\n", de->rpi_display_count); ++ display_cb_input(de->port_in, buf); ++ } ++} ++ ++static void display_exit(rpi_display_env_t ** const pde) ++{ ++ rpi_display_env_t * const de = *pde; ++ *pde = NULL; ++ ++ if (de != NULL) { ++// sleep(120); ++ ++ if (de->port_in != NULL) { ++ mmal_port_disable(de->port_in); ++ } ++ ++ // The above disable should kick out all buffers - check that ++ if (atomic_load(&de->rpi_display_count) != 0) { ++ av_log(NULL, AV_LOG_WARNING, "Exiting with display count non-zero:%d\n", atomic_load(&de->rpi_display_count)); ++ } ++ ++ if (de->conn != NULL) { ++ mmal_connection_destroy(de->conn); ++ } ++ if (de->isp != NULL) { ++ mmal_component_destroy(de->isp); ++ } ++ if (de->display != NULL) { ++ mmal_component_destroy(de->display); ++ } ++ if (de->rpi_pool != NULL) { ++ mmal_port_pool_destroy(de->display->input[0], de->rpi_pool); ++ } ++ ++ av_free(de); ++ } ++} ++ ++#endif ++ ++ + /* sub2video hack: + Convert subtitles to video with alpha to insert them in filter graphs. + This is a temporary solution until libavfilter gets real subtitles support. +@@ -583,6 +847,11 @@ static void ffmpeg_cleanup(int ret) + avformat_close_input(&input_files[i]->ctx); + av_freep(&input_files[i]); + } ++ ++#ifdef RPI_DISPLAY ++ display_exit(&rpi_display_env); ++#endif ++ + for (i = 0; i < nb_input_streams; i++) { + InputStream *ist = input_streams[i]; + +@@ -594,7 +863,9 @@ static void ffmpeg_cleanup(int ret) + av_freep(&ist->filters); + av_freep(&ist->hwaccel_device); + av_freep(&ist->dts_buffer); +- ++#ifdef RPI_DISPLAY ++ av_rpi_zc_uninit(ist->dec_ctx); ++#endif + avcodec_free_context(&ist->dec_ctx); + + av_freep(&input_streams[i]); +@@ -625,6 +896,7 @@ static void ffmpeg_cleanup(int ret) + } + term_exit(); + ffmpeg_exited = 1; ++ + } + + void remove_avoptions(AVDictionary **a, AVDictionary *b) +@@ -1060,6 +1332,15 @@ static void do_video_out(OutputFile *of, + if (ost->source_index >= 0) + ist = input_streams[ost->source_index]; + ++#ifdef RPI_DISPLAY ++ if (next_picture && ist != NULL) ++ { ++ if (rpi_display_env == NULL) ++ rpi_display_env = display_init(next_picture->format, 0, 0, next_picture->width, next_picture->height); ++ display_frame(ist->dec_ctx, rpi_display_env, next_picture); ++ } ++#endif ++ + frame_rate = av_buffersink_get_frame_rate(filter); + if (frame_rate.num > 0 && frame_rate.den > 0) + duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); +@@ -1275,7 +1556,7 @@ static void do_video_out(OutputFile *of, + + ost->frames_encoded++; + +- ret = avcodec_send_frame(enc, in_picture); ++ ret = 0;//avcodec_send_frame(enc, in_picture); + if (ret < 0) + goto error; + +@@ -2891,6 +3172,12 @@ static int init_input_stream(int ist_index, char *error, int error_len) + ist->dec_ctx->opaque = ist; + ist->dec_ctx->get_format = get_format; + ist->dec_ctx->get_buffer2 = get_buffer; ++ ++#ifdef RPI_DISPLAY ++ // Overrides the above get_buffer2 ++ av_rpi_zc_init(ist->dec_ctx); ++#endif ++ + ist->dec_ctx->thread_safe_callbacks = 1; + + av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); +diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h +index d44b7a5c72..0c5fa38f1d 100644 +--- a/fftools/ffmpeg.h ++++ b/fftools/ffmpeg.h +@@ -62,6 +62,7 @@ enum HWAccelID { + HWACCEL_VIDEOTOOLBOX, + HWACCEL_QSV, + HWACCEL_CUVID, ++ HWACCEL_RPI, + }; + + typedef struct HWAccel { +@@ -654,6 +655,7 @@ int ffmpeg_parse_options(int argc, char **argv); + int videotoolbox_init(AVCodecContext *s); + int qsv_init(AVCodecContext *s); + int cuvid_init(AVCodecContext *s); ++int rpi_init(AVCodecContext *s); + + HWDevice *hw_device_get_by_name(const char *name); + int hw_device_init_from_string(const char *arg, HWDevice **dev); +diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c +index d7a7eb0662..4ee87e742b 100644 +--- a/fftools/ffmpeg_opt.c ++++ b/fftools/ffmpeg_opt.c +@@ -74,6 +74,10 @@ const HWAccel hwaccels[] = { + #endif + #if CONFIG_CUVID + { "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA }, ++#endif ++#if CONFIG_RPI ++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_8 }, ++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_10 }, + #endif + { 0 }, + }; +diff --git a/libavcodec/Makefile b/libavcodec/Makefile +index 8b3eab6fb6..84f7e1a1e4 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -6,6 +6,10 @@ HEADERS = ac3_parser.h \ + avcodec.h \ + avdct.h \ + avfft.h \ ++ rpi_qpu.h \ ++ rpi_mailbox.h \ ++ rpi_zc.h \ ++ rpi_ctrl_ffmpeg.h \ + d3d11va.h \ + dirac.h \ + dv_profile.h \ +@@ -48,6 +52,10 @@ OBJS = ac3_parser.o \ + qsv_api.o \ + raw.o \ + utils.o \ ++ rpi_qpu.o \ ++ rpi_mailbox.o \ ++ rpi_zc.o \ ++ rpi_ctrl_ffmpeg.o \ + vorbis_parser.o \ + xiph.o \ + +@@ -361,6 +369,7 @@ OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o + OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ + hevc_cabac.o hevc_refs.o hevcpred.o \ + hevcdsp.o hevc_filter.o hevc_data.o ++OBJS-$(CONFIG_RPI) += rpi_hevc.o + OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o + OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o + OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o +diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h +index 4c4581c895..f519b1d8c4 100644 +--- a/libavcodec/avcodec.h ++++ b/libavcodec/avcodec.h +@@ -3212,7 +3212,13 @@ typedef struct AVCodecContext { + #endif + + /** +- * Audio only. The amount of padding (in samples) appended by the encoder to ++ * Opaque pointer for use by replacement get_buffer2 code ++ * ++ * @author jc (08/02/2016) ++ */ ++ void * get_buffer_context; ++ ++ /* Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. +diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c +index df33433150..a692e685c4 100644 +--- a/libavcodec/hevcdec.c ++++ b/libavcodec/hevcdec.c +@@ -365,12 +365,17 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) + CONFIG_HEVC_V4L2REQUEST_HWACCEL + \ + CONFIG_HEVC_VAAPI_HWACCEL + \ + CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ ++ CONFIG_HEVC_RPI4_8_HWACCEL + \ ++ CONFIG_HEVC_RPI4_10_HWACCEL + \ + CONFIG_HEVC_VDPAU_HWACCEL) + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; + + switch (sps->pix_fmt) { + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUVJ420P: ++#if CONFIG_HEVC_RPI4_8_HWACCEL ++ *fmt++ = AV_PIX_FMT_RPI4_8; ++#endif + #if CONFIG_HEVC_DXVA2_HWACCEL + *fmt++ = AV_PIX_FMT_DXVA2_VLD; + #endif +@@ -395,6 +400,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) + #endif + break; + case AV_PIX_FMT_YUV420P10: ++#if CONFIG_HEVC_RPI4_10_HWACCEL ++ *fmt++ = AV_PIX_FMT_RPI4_10; ++#endif + #if CONFIG_HEVC_DXVA2_HWACCEL + *fmt++ = AV_PIX_FMT_DXVA2_VLD; + #endif +@@ -3564,6 +3572,12 @@ AVCodec ff_hevc_decoder = { + #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + HWACCEL_VIDEOTOOLBOX(hevc), + #endif ++#if CONFIG_HEVC_RPI4_8_HWACCEL ++ HWACCEL_RPI4_8(hevc), ++#endif ++#if CONFIG_HEVC_RPI4_10_HWACCEL ++ HWACCEL_RPI4_10(hevc), ++#endif + #if CONFIG_HEVC_V4L2REQUEST_HWACCEL + HWACCEL_V4L2REQUEST(hevc), + #endif +diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h +index 2eefc91e7e..0e482f2265 100644 +--- a/libavcodec/hwaccel.h ++++ b/libavcodec/hwaccel.h +@@ -82,5 +82,9 @@ typedef struct AVCodecHWConfigInternal { + HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) + #define HWACCEL_V4L2REQUEST(codec) \ + HW_CONFIG_HWACCEL(1, 0, 0, DRM_PRIME, DRM, ff_ ## codec ## _v4l2request_hwaccel) ++#define HWACCEL_RPI4_8(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_8, NONE, ff_ ## codec ## _rpi4_8_hwaccel) ++#define HWACCEL_RPI4_10(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_10, NONE, ff_ ## codec ## _rpi4_10_hwaccel) + + #endif /* AVCODEC_HWACCEL_H */ +diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h +index d183675abe..31a4a94e28 100644 +--- a/libavcodec/hwaccels.h ++++ b/libavcodec/hwaccels.h +@@ -77,5 +77,7 @@ extern const AVHWAccel ff_wmv3_dxva2_hwaccel; + extern const AVHWAccel ff_wmv3_nvdec_hwaccel; + extern const AVHWAccel ff_wmv3_vaapi_hwaccel; + extern const AVHWAccel ff_wmv3_vdpau_hwaccel; ++extern const AVHWAccel ff_hevc_rpi4_8_hwaccel; ++extern const AVHWAccel ff_hevc_rpi4_10_hwaccel; + + #endif /* AVCODEC_HWACCELS_H */ +diff --git a/libavcodec/rpi_ctrl_ffmpeg.c b/libavcodec/rpi_ctrl_ffmpeg.c +new file mode 100644 +index 0000000000..6d93adba03 +--- /dev/null ++++ b/libavcodec/rpi_ctrl_ffmpeg.c +@@ -0,0 +1,427 @@ ++#include ++#include ++#include ++#include ++ ++// How to access GPIO registers from C-code on the Raspberry-Pi ++// Example program ++// 15-January-2012 ++// Dom and Gert ++ ++// Access from ARM Running Linux ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include "rpi_mailbox.h" ++#include "rpi_ctrl_ffmpeg.h" ++ ++#define av_assert0(x) assert(x) ++ ++// argon block doesn't see VC sdram alias bits ++#define MANGLE(x) ((x) &~0xc0000000) ++#ifdef AXI_BUFFERS ++#define AXI_MEM_SIZE (64*1024*1024) ++#else ++#define AXI_MEM_SIZE (64*1024*1024) ++#endif ++ ++#define PAGE_SIZE (4*1024) ++#define BLOCK_SIZE (0x10000) ++#define CACHED 0 ++#define VERBOSE 0 ++ ++static inline void __DMB2(void) {}//{ asm volatile ("dmb" ::: "memory"); } ++ ++ ++// GPU memory alloc fns (internal) ++typedef struct gpu_mem_ptr_s { ++ unsigned char *arm; // Pointer to memory mapped on ARM side ++ int vc_handle; // Videocore handle of relocatable memory ++ int vcsm_handle; // Handle for use by VCSM ++ unsigned int vc; // Address for use in GPU code ++ unsigned int numbytes; // Size of memory block ++} GPU_MEM_PTR_T; ++ ++typedef enum ++{ ++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, ++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, ++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 ++} rpi_cache_flush_mode_t; ++ ++// GPU_MEM_PTR_T alloc fns ++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = (numbytes + 255) & ~255; // Round up ++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++ printf("***** %s, %d\n", __func__, numbytes); ++ ++ return 0; ++} ++ ++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = numbytes; ++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++ printf("***** %s, %d\n", __func__, numbytes); ++ return 0; ++} ++ ++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { ++ mbox_mem_unlock(mb, p->vc_handle); ++ vcsm_unlock_ptr(p->arm); ++ vcsm_free(p->vcsm_handle); ++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again ++ printf("***** %s\n", __func__); ++} ++ ++static void gpu_clean_invalidate(GPU_MEM_PTR_T * const p, int mode) { ++ struct vcsm_user_clean_invalid_s iocache = {}; ++ iocache.s[0].handle = p->vcsm_handle; ++ iocache.s[0].cmd = mode; ++ iocache.s[0].addr = (int) p->arm; ++ iocache.s[0].size = p->numbytes; ++ vcsm_clean_invalid( &iocache ); ++ printf("***** %s mode:%d\n", __func__, mode); ++} ++ ++// ++// Set up a memory regions to access periperhals ++// ++static void *setup_io(const char *dev, unsigned long base) ++{ ++ void *gpio_map; ++ int mem_fd; ++ ++ /* open /dev/mem */ ++ if ((mem_fd = open(dev, O_RDWR|O_SYNC) ) < 0) { ++ printf("can't open %s\n", dev); ++ exit (-1); ++ } ++ // Now map it ++ gpio_map = (unsigned char *)mmap( ++ NULL, ++ BLOCK_SIZE, ++ PROT_READ|PROT_WRITE, ++ MAP_SHARED, ++ mem_fd, ++ base ++ ); ++ printf("%s: %08lx -> %p (fd:%d)\n", __FUNCTION__, base, gpio_map, mem_fd); ++ ++ if (gpio_map == MAP_FAILED) { ++ printf("mmap error %p\n", gpio_map); ++ //exit (-1); ++ } ++ ++ return gpio_map; ++} // setup_io ++ ++static void release_io(void *gpio_map) ++{ ++ int s = munmap(gpio_map, BLOCK_SIZE); ++ assert(s == 0); ++} ++ ++struct RPI_DEBUG { ++ FILE *fp_reg; ++ FILE *fp_bin; ++ int mbox; ++ GPU_MEM_PTR_T axi; ++ void *read_buf; ++ int32_t read_buf_size, read_buf_used; ++ volatile unsigned int *apb; ++ volatile unsigned int *interrupt; ++ //volatile unsigned int *sdram; ++}; ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++void rpi_apb_write_addr(void *id, uint16_t addr, uint32_t data) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "P %x %08x\n", addr, data); ++ __DMB2(); ++ rpi->apb[addr>>2] = data + (MANGLE(rpi->axi.vc)>>6); ++} ++ ++uint64_t rpi_axi_get_addr(void *id) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ return (uint64_t)MANGLE(rpi->axi.vc); ++} ++ ++void rpi_apb_write(void *id, uint16_t addr, uint32_t data) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "W %x %08x\n", addr, data); ++ __DMB2(); ++ rpi->apb[addr>>2] = data; ++} ++ ++uint32_t rpi_apb_read(void *id, uint16_t addr) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ uint32_t v = rpi->apb[addr>>2]; ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); ++ return v; ++} ++ ++void rpi_apb_read_drop(void *id, uint16_t addr) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ uint32_t v = rpi->apb[addr>>2]; ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); ++} ++ ++void rpi_axi_write(void *id, uint64_t addr, uint32_t size, void *buf) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "L %08" PRIx64 " %08x\n", addr, size); ++ assert(addr + size <= AXI_MEM_SIZE); ++ __DMB2(); ++ memcpy(rpi->axi.arm + addr, buf, size); ++} ++ ++void rpi_axi_read_alloc(void *id, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(rpi->read_buf == NULL); ++ rpi->read_buf = malloc(size); ++ rpi->read_buf_size = size; ++ rpi->read_buf_used = 0; ++} ++ ++void rpi_axi_read_tx(void *id, uint64_t addr, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(rpi->read_buf_used + size <= rpi->read_buf_size); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "S %08" PRIx64 " %08x\n", addr, size); ++ assert(addr + size <= AXI_MEM_SIZE); ++ __DMB2(); ++ memcpy((char *)rpi->read_buf + rpi->read_buf_used, rpi->axi.arm + addr, size); ++ rpi->read_buf_used += size; ++} ++ ++void rpi_axi_read_rx(void *id, uint32_t size, void *buf) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(size == rpi->read_buf_used); ++ fprintf(rpi->fp_reg, "Z " PRIx64 " %08x\n", size); ++ memcpy(buf, rpi->read_buf, size); ++ free(rpi->read_buf); ++ rpi->read_buf = NULL; ++ rpi->read_buf_size = 0; ++ rpi->read_buf_used = 0; ++} ++ ++static int getthreadnum(unsigned pid) ++{ ++ static unsigned pids[8]; ++ int i; ++ for (i = 0; i < 8; i++) ++ { ++ if (pids[i] == 0) ++ pids[i] = pid; ++ if (pids[i] == pid) ++ return i; ++ } ++ return -1; ++} ++ ++#define _NOP() //do { __asm__ __volatile__ ("nop"); } while (0) ++ ++static void yield(void) ++{ ++ int i; ++ for (i=0; i<0; i++) ++ _NOP(); ++ usleep(1000); ++} ++ ++ ++void rpi_wait_interrupt(void *id, int phase) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ static struct timespec tfirst={0,0}; ++ static __thread struct timespec tstart={0,0}; ++ struct timespec tend={0,0}; ++ unsigned pid = (unsigned)pthread_self(); ++ clock_gettime(CLOCK_MONOTONIC, &tend); ++ if (tstart.tv_sec == 0 && tstart.tv_nsec == 0) ++ tstart = tend; ++ if (tfirst.tv_sec == 0 && tfirst.tv_nsec == 0) ++ { ++ /*printf("%s: Resetting sdram stats\n", __FUNCTION__); ++ rpi->sdram[0x30/4] = 0;*/ ++ tfirst = tend; ++ } ++ if (VERBOSE) ++ printf("%08llu: %s: IN thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, ++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); ++ /*enum {IDL=0x30/4, RTC=0x34/4, WTC=0x38/4, RDC=0x3c/4, WDC=0x40/4, RAC=0x44/4, CYC=0x48/4, CMD=0x4c/4, DAT=0x50/4, RDCMD=0x78/4, RDSUB=0x7c/4, WRCMD=0x80/4, WRSUB=0x84/4, MWRCMD=0x88/4, MWRSUB=0x8c/4,}; ++ printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", ++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], ++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]); ++ rpi->sdram[0x30/4] = 0;*/ ++ ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "I %d\n", phase); ++ __DMB2(); ++#if 0 ++ assert(phase == 1 || phase == 2); ++ for (;;) { ++ if (phase==1 && rpi->apb[0x74>>2]==rpi->apb[0x70>>2]) break; ++ else if (phase==2 && (rpi->apb[0x8028/*STATUS2*/>>2]&1)==0) break; ++ } ++ fprintf(rpi->fp_reg, "I %d done\n", phase); ++#else ++ #define ARG_IC_ICTRL_ACTIVE1_INT_SET 0x00000001 ++ #define ARG_IC_ICTRL_ACTIVE1_EDGE_SET 0x00000002 ++ #define ARG_IC_ICTRL_ACTIVE1_EN_SET 0x00000004 ++ #define ARG_IC_ICTRL_ACTIVE1_STATUS_SET 0x00000008 ++ #define ARG_IC_ICTRL_ACTIVE2_INT_SET 0x00000010 ++ #define ARG_IC_ICTRL_ACTIVE2_EDGE_SET 0x00000020 ++ #define ARG_IC_ICTRL_ACTIVE2_EN_SET 0x00000040 ++ #define ARG_IC_ICTRL_ACTIVE2_STATUS_SET 0x00000080 ++ //if (rpi->interrupt[0] &~ (ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE1_STATUS_SET|ARG_IC_ICTRL_ACTIVE2_STATUS_SET)) ++ //fprintf(rpi->fp_reg, "I %d %x in\n", phase, rpi->interrupt[0]); ++ ++ if (phase == 1) { ++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE1_INT_SET)) ++ yield(); ++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE2_INT_SET; //ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; ++ } else if (phase == 2) { ++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE2_INT_SET)) ++ yield(); ++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE1_INT_SET; //ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; ++ } else assert(0); ++#endif ++ //fprintf(rpi->fp_reg, "I %d %x out\n", phase, rpi->interrupt[0]); ++ if (phase == 2) ++ { ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "YBASE:%08x CBASE:%08x\n", rpi->apb[0x8018>>2]*64, rpi->apb[0x8020>>2]*64); ++ } ++ clock_gettime(CLOCK_MONOTONIC, &tend); ++ ++ if (VERBOSE) ++ printf("%08llu: %s: OUT thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, ++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); ++ /*printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", ++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], ++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]);*/ ++ ++ tstart = tend; ++} ++ ++ ++void rpi_apb_dump_regs(void *id, uint16_t addr, int num) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ int i; ++ __DMB2(); ++ if (VERBOSE) ++ for (i=0; ifp_reg, "%08x: ", 0x7eb00000 + addr + 4*i); ++ fprintf(rpi->fp_reg, "%08x", rpi->apb[(addr>>2)+i]); ++ if ((i%4)==3 || i+1 == num) ++ fprintf(rpi->fp_reg, "\n"); ++ else ++ fprintf(rpi->fp_reg, " "); ++ } ++} ++ ++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ int i; ++ __DMB2(); ++ if (VERBOSE) ++ for (i=0; i>2; i++) ++ { ++ if ((i%4)==0) ++ fprintf(rpi->fp_reg, "%08x: ", MANGLE(rpi->axi.vc) + (uint32_t)addr + 4*i); ++ fprintf(rpi->fp_reg, "%08x", ((uint32_t*)rpi->axi.arm)[(addr>>2)+i]); ++ if ((i%4)==3 || i+1 == size>>2) ++ fprintf(rpi->fp_reg, "\n"); ++ else ++ fprintf(rpi->fp_reg, " "); ++ } ++} ++ ++void rpi_axi_flush(void *id, int mode) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (CACHED) ++ { ++ gpu_clean_invalidate(&rpi->axi, mode); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++const char * rpi_ctrl_ffmpeg_init(const char *hwaccel_device, void **id) { ++ struct RPI_DEBUG *rpi = calloc(1, sizeof(struct RPI_DEBUG)); ++ (void) hwaccel_device; ++ printf("%s\n id=%p\n", __FUNCTION__, rpi); ++ ++ if (!rpi) return "out of memory"; ++ ++ bcm_host_init(); ++ vcsm_init(); ++ rpi->apb = setup_io("/dev/argon-hevcmem", 0); ++ rpi->interrupt = setup_io("/dev/argon-intcmem", 0); ++ //rpi->sdram = setup_io(0xfe001000); ++ ++ rpi->fp_bin = stderr; ++ rpi->fp_reg = stderr; ++ ++ rpi->mbox = mbox_open(); ++ if ((CACHED ? gpu_malloc_cached_internal:gpu_malloc_uncached_internal)(rpi->mbox, AXI_MEM_SIZE, &rpi->axi) != 0) ++ return "out of memory"; ++ ++ fprintf(rpi->fp_reg, "A 100000000 apb:%p axi.arm:%p axi.vc:%08x\n", rpi->apb, rpi->axi.arm, MANGLE(rpi->axi.vc)); ++ *id = rpi; ++ return 0; ++} ++ ++void rpi_ctrl_ffmpeg_free(void *id) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ printf("%s id=%p\n", __FUNCTION__, rpi); ++ release_io(rpi->apb); ++ release_io(rpi->interrupt); ++ gpu_free_internal(rpi->mbox, &rpi->axi); ++ printf("%s freed axi mem\n", __FUNCTION__); ++ mbox_close(rpi->mbox); ++ printf("%s closed mbox\n", __FUNCTION__); ++ free(rpi); ++ printf("%s freed rpi\n", __FUNCTION__); ++ vcsm_exit(); ++ bcm_host_deinit(); ++} +diff --git a/libavcodec/rpi_ctrl_ffmpeg.h b/libavcodec/rpi_ctrl_ffmpeg.h +new file mode 100644 +index 0000000000..6a1d95f195 +--- /dev/null ++++ b/libavcodec/rpi_ctrl_ffmpeg.h +@@ -0,0 +1,29 @@ ++// rpi_ctrl_ffmpeg.h ++// ++// This file contains prototypes for the functions used to control the socket ++// interface when using ffmpeg. ++// ++ ++#ifndef __CTRL_FFMPEG_H__ ++#define __CTRL_FFMPEG_H__ ++ ++#include ++ ++const char *rpi_ctrl_ffmpeg_init (const char *hwaccel_device, void **id); ++void rpi_apb_write_addr (void *id, uint16_t addr, uint32_t data); ++void rpi_apb_write (void *id, uint16_t addr, uint32_t data); ++uint32_t rpi_apb_read (void *id, uint16_t addr); ++void rpi_apb_read_drop (void *id, uint16_t addr); ++void rpi_axi_write (void *id, uint64_t addr, uint32_t size, void *buf); ++void rpi_axi_read (void *id, uint64_t addr, uint32_t size, void *buf); ++void rpi_axi_read_alloc (void *id, uint32_t size); ++void rpi_axi_read_tx (void *id, uint64_t addr, uint32_t size); ++void rpi_axi_read_rx (void *id, uint32_t size, void *buf); ++void rpi_wait_interrupt (void *id, int phase); ++void rpi_ctrl_ffmpeg_free (void *id); ++uint64_t rpi_axi_get_addr (void *id); ++void rpi_apb_dump_regs(void *id, uint16_t addr, int num); ++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size); ++void rpi_axi_flush(void *id, int mode); ++ ++#endif // __CTRL_FILES_H__ +diff --git a/libavcodec/rpi_hevc.c b/libavcodec/rpi_hevc.c +new file mode 100644 +index 0000000000..a000077f33 +--- /dev/null ++++ b/libavcodec/rpi_hevc.c +@@ -0,0 +1,1065 @@ ++// FFMPEG HEVC decoder hardware accelerator ++// Andrew Holme, Argon Design Ltd ++// Copyright (c) June 2017 Raspberry Pi Ltd ++ ++#include ++#include ++ ++#include "fftools/ffmpeg.h" ++#include "libavutil/avassert.h" ++#include "libavutil/imgutils.h" ++#include "avcodec.h" ++#include "hwaccel.h" ++ ++#include "rpi_hevc.h" ++#include "rpi_zc.h" ++#include "rpi_qpu.h" ++ ++#include "rpi_ctrl_ffmpeg.h" ++////////////////////////////////////////////////////////////////////////////// ++ ++// Array of constants for scaling factors ++static const uint32_t scaling_factor_offsets[4][6] = { ++ // MID0 MID1 MID2 MID3 MID4 MID5 ++ {0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050}, // SID0 (4x4) ++ {0x0060, 0x00A0, 0x00E0, 0x0120, 0x0160, 0x01A0}, // SID1 (8x8) ++ {0x01E0, 0x02E0, 0x03E0, 0x04E0, 0x05E0, 0x06E0}, // SID2 (16x16) ++ {0x07E0, 0, 0, 0x0BE0, 0, 0}}; // SID3 (32x32) ++ ++// ffmpeg places SID3,MID1 where matrixID 3 normally is ++ ++////////////////////////////////////////////////////////////////////////////// ++// Scaling factors ++ ++static void expand_scaling_list( ++ RPI_T *rpi, ++ const ScalingList *scaling_list, // scaling list structure from ffmpeg ++ uint8_t sizeID, uint8_t matrixID) ++{ ++ uint8_t x, y, i, blkSize = 4<>1)<<3) + (x>>1); break; ++ case 3: i = ((y>>2)<<3) + (x>>2); ++ } ++ rpi->scaling_factors[index] = scaling_list->sl[sizeID][matrixID][i]; ++ } ++ } ++ if (sizeID>1) ++ rpi->scaling_factors[index_offset] = ++ scaling_list->sl_dc[sizeID-2][matrixID]; ++} ++ ++static void populate_scaling_factors(RPI_T *rpi, HEVCContext *s) { ++ const ScalingList *sl = ++ s->ps.pps->scaling_list_data_present_flag ? &s->ps.pps->scaling_list ++ : &s->ps.sps->scaling_list; ++ int sid, mid; ++ for (sid=0; sid<3; sid++) ++ for (mid=0; mid<6; mid++) ++ expand_scaling_list(rpi, sl, sid, mid); ++ ++ // second scaling matrix for 32x32 is at matrixID 3 not 1 in ffmpeg ++ expand_scaling_list(rpi, sl, 3, 0); ++ expand_scaling_list(rpi, sl, 3, 3); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Probabilities ++ ++static void populate_prob_tables(RPI_T *rpi, HEVCContext *s) { ++ struct RPI_PROB *dst = &rpi->probabilities; ++ struct FFM_PROB *src = (struct FFM_PROB *) s->HEVClc->cabac_state; ++ #define PROB_CPSZ(to, from, sz) memcpy(dst->to, src->from, sz) ++ #define PROB_COPY(to, from) memcpy(dst->to, src->from, sizeof(dst->to)) ++ memset(dst, 0, sizeof(*dst)); ++ PROB_COPY(SAO_MERGE_FLAG , sao_merge_flag ); ++ PROB_COPY(SAO_TYPE_IDX , sao_type_idx ); ++ PROB_COPY(SPLIT_FLAG , split_coding_unit_flag ); ++ PROB_COPY(CU_SKIP_FLAG , skip_flag ); ++ PROB_COPY(CU_TRANSQUANT_BYPASS_FLAG, cu_transquant_bypass_flag ); ++ PROB_COPY(PRED_MODE , pred_mode_flag ); ++ PROB_COPY(PART_SIZE , part_mode ); ++ PROB_COPY(INTRA_PRED_MODE , prev_intra_luma_pred_flag ); ++ PROB_COPY(CHROMA_PRED_MODE , intra_chroma_pred_mode ); ++ PROB_COPY(MERGE_FLAG_EXT , merge_flag ); ++ PROB_COPY(MERGE_IDX_EXT , merge_idx ); ++ PROB_COPY(INTER_DIR , inter_pred_idc ); ++ PROB_COPY(REF_PIC , ref_idx_l0 ); ++ PROB_COPY(MVP_IDX , mvp_lx_flag ); ++ PROB_CPSZ(MVD+0 , abs_mvd_greater0_flag+0 , 1); // ABS_MVD_GREATER0_FLAG[1] not used ++ PROB_CPSZ(MVD+1 , abs_mvd_greater1_flag+1 , 1); // ABS_MVD_GREATER1_FLAG[0] not used ++ PROB_COPY(QT_ROOT_CBF , no_residual_data_flag ); ++ PROB_COPY(TRANS_SUBDIV_FLAG , split_transform_flag ); ++ PROB_CPSZ(QT_CBF , cbf_luma , 2); ++ PROB_CPSZ(QT_CBF+2 , cbf_cb_cr , 4); ++ PROB_COPY(DQP , cu_qp_delta ); ++ PROB_COPY(ONE_FLAG , coeff_abs_level_greater1_flag ); ++ PROB_COPY(LASTX , last_significant_coeff_x_prefix); ++ PROB_COPY(LASTY , last_significant_coeff_y_prefix); ++ PROB_COPY(SIG_CG_FLAG , significant_coeff_group_flag ); ++ PROB_COPY(ABS_FLAG , coeff_abs_level_greater2_flag ); ++ PROB_COPY(TRANSFORMSKIP_FLAG , transform_skip_flag ); ++ PROB_CPSZ(SIG_FLAG , significant_coeff_flag , 42); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Read YUV data from socket server ++ ++static int bytes_per_line(const HEVCSPS *sps, int jump, int x) { ++ int width = FFMIN(jump, sps->width - x); ++ return sps->bit_depth>8? (width>48? 128:64) ++ : (width>64? 128:64); ++} ++ ++static void read_rect(RPI_T *rpi, char *buf, int addr64, int height, int bytes_per_line) { ++ rpi->axi_read_alloc(rpi->id, bytes_per_line*height); ++ if (bytes_per_line==128) ++ rpi->axi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 128*height); ++ else { ++ int y; ++ for (y=0; yaxi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 64); ++ } ++ rpi->axi_read_rx(rpi->id, bytes_per_line*height, buf); ++} ++ ++#ifdef AXI_BUFFERS ++////////////////////////////////////////////////////////////////////////////// ++// Copy YUV output data to FFMPEG frame buffer ++ ++static void copy_luma(char *buf, int bpl, int height, int x, uint8_t *data, int linesize) { ++ int y; ++ for (y=0; y> 0)&0x3ff; if(++j==linesize/2) break; ++ dst[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; ++ dst[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; ++ } ++ } ++} ++ ++static void copy_chroma10(char *buf, int bpl, int height, int x, uint8_t *u8, uint8_t *v8, int linesize) { ++ int i, j, y; ++ for (y=0; y> 0)&0x3ff; ++ v16[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; ++ u16[j] = (src[i]>>20)&0x3ff; i++; ++ v16[j] = (src[i]>> 0)&0x3ff; if(++j==linesize/2) break; ++ u16[j] = (src[i]>>10)&0x3ff; ++ v16[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; ++ } ++ } ++} ++#endif ++ ++////////////////////////////////////////////////////////////////////////////// ++// Phase 1 command and bit FIFOs ++ ++static int p1_apb_write(RPI_T *rpi, uint16_t addr, uint32_t data) { ++ if (rpi->cmd_len==rpi->cmd_max) ++ av_assert0(rpi->cmd_fifo = realloc(rpi->cmd_fifo, (rpi->cmd_max*=2)*sizeof(struct RPI_CMD))); ++ rpi->cmd_fifo[rpi->cmd_len].addr = addr; ++ rpi->cmd_fifo[rpi->cmd_len].data = data; ++ return rpi->cmd_len++; ++} ++ ++static void p1_axi_write(RPI_T *rpi, uint32_t len, const void *ptr, int cmd_idx) { ++ if (rpi->bit_len==rpi->bit_max) ++ av_assert0(rpi->bit_fifo = realloc(rpi->bit_fifo, (rpi->bit_max*=2)*sizeof(struct RPI_BIT))); ++ rpi->bit_fifo[rpi->bit_len].cmd = cmd_idx; ++ rpi->bit_fifo[rpi->bit_len].ptr = ptr; ++ rpi->bit_fifo[rpi->bit_len].len = len; ++ rpi->bit_len++; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Write probability and scaling factor memories ++ ++static void WriteProb(RPI_T *rpi) { ++ int i; ++ uint8_t *p = (uint8_t *) &rpi->probabilities; ++ for (i=0; iscaling_factors; ++ for (i=0; i= bd[i]; i++); // bd[] has num+1 elements; bd[0]=0; see hevc_ps.c ++ return i-1; ++} ++ ++static int ctb_to_slice_w_h (unsigned int ctb, int ctb_size, int width, unsigned int *bd, int num) { ++ if (ctb < bd[num-1]) return ctb_size; ++ else if (width % ctb_size) return width % ctb_size; ++ else return ctb_size; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void alloc_picture_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ const HEVCSPS *sps = s->ps.sps; ++ int CtbSizeY = 1<log2_ctb_size; ++ int x64 = AXI_BASE64; ++ ++ rpi->PicWidthInCtbsY = (sps->width + CtbSizeY - 1) / CtbSizeY; //7-15 ++ rpi->PicHeightInCtbsY = (sps->height + CtbSizeY - 1) / CtbSizeY; //7-17 ++#ifdef AXI_BUFFERS ++ rpi->lumabytes64 = ((sps->height+64) * ((sps->width+95)/96) * 2); ++ rpi->framebytes64 = ((rpi->lumabytes64 * 3)/2); ++ rpi->lumastride64 = ((sps->height+64) * 128) / 64; ++ rpi->chromastride64 = (((sps->height+64) * 128 ) / 2) / 64; ++ ++ x64 += 17 * rpi->framebytes64; ++#endif ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ // 128 bits = 16 bytes per MV, one for every 16*16 ++ int collocatedStride64 = (rpi->PicWidthInCtbsY * (CtbSizeY/16) * 16 + 63)>>6; ++ rpi->mvframebytes64 = rpi->PicHeightInCtbsY * (CtbSizeY/16) * collocatedStride64; ++ rpi->mvstorage64 = x64; ++ x64 += rpi->mvframebytes64 * 17; // Leave space for 17 reference pictures ++ rpi->colstride64 = collocatedStride64; ++ rpi->mvstride64 = collocatedStride64; ++ } ++ ++ rpi->pubase64[0] = x64; ++} ++ ++static int alloc_stream_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ int stride64, x64 = rpi->pubase64[0]; ++ ++ stride64 = 1 + (rpi->max_pu_msgs*2*rpi->PicWidthInCtbsY)/64; ++ rpi->pubase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; ++ rpi->pustep64 = stride64; ++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; ++ ++ stride64 = rpi->max_coeff64; ++ rpi->coeffbase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; ++ rpi->coeffstep64 = stride64; ++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; ++ return x64; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Start or restart phase 1 ++ ++static void phase1_begin(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ rpi->apb_write_addr(rpi->id, RPI_PUWBASE, rpi->pubase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_PUWSTRIDE, rpi->pustep64); ++ rpi->apb_write_addr(rpi->id, RPI_COEFFWBASE, rpi->coeffbase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_COEFFWSTRIDE, rpi->coeffstep64); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Wait until phase 2 idle ++ ++static void wait_idle(RPI_T *rpi, int last) { ++ for (;;) { ++ int order; ++ pthread_mutex_lock (&rpi->mutex_phase2); ++ order = rpi->phase2_order; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ if (order==last) return; ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Handle PU and COEFF stream overflow ++ ++static int check_status(RPI_T *rpi) { ++ int status, c, p; ++ status = rpi->apb_read(rpi->id, RPI_STATUS); ++ p = (status>>4)&1; ++ c = (status>>3)&1; ++ if (p|c) { // overflow? ++ wait_idle(rpi, rpi->phase1_order-1); // drain phase2 before changing memory layout ++ if (p) rpi->max_pu_msgs += rpi->max_pu_msgs/2; ++ if (c) rpi->max_coeff64 += rpi->max_coeff64/2; ++ return 1; ++ } ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Write STATUS register with expected end CTU address of previous slice ++ ++static void end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; ++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++} ++ ++static void wpp_pause(RPI_T *rpi, int ctb_row) { ++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + 0x25); ++ p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); ++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1?0x70000:0x30000); ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_row<<16) + 2); ++} ++ ++static void wpp_end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int new_x = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int new_y = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; ++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; ++ if (rpi->wpp_entry_x<2 && (rpi->wpp_entry_y2) && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++ if (new_x==2 || rpi->PicWidthInCtbsY==2 && rpi->wpp_entry_yps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ p1_apb_write(rpi, RPI_SPS0, ++ (sps->log2_min_cb_size << 0) + ++ (sps->log2_ctb_size << 4) + ++ (sps->log2_min_tb_size << 8) + ++ (sps->log2_max_trafo_size << 12) + ++ (sps->bit_depth << 16) + ++ (sps->bit_depth << 20) + ++ (sps->max_transform_hierarchy_depth_intra << 24) + ++ (sps->max_transform_hierarchy_depth_inter << 28)); ++ ++ p1_apb_write(rpi, RPI_SPS1, ++ (sps->pcm.bit_depth << 0) + ++ (sps->pcm.bit_depth_chroma << 4) + ++ (sps->pcm.log2_min_pcm_cb_size << 8) + ++ (sps->pcm.log2_max_pcm_cb_size << 12) + ++ (sps->separate_colour_plane_flag? 0:sps->chroma_format_idc << 16) + ++ (sps->amp_enabled_flag << 18) + ++ (sps->pcm_enabled_flag << 19) + ++ (sps->scaling_list_enable_flag << 20) + ++ (sps->sps_strong_intra_smoothing_enable_flag << 21)); ++ ++ p1_apb_write(rpi, RPI_PPS, ++ (sps->log2_ctb_size - pps->diff_cu_qp_delta_depth << 0) + ++ (pps->cu_qp_delta_enabled_flag << 4) + ++ (pps->transquant_bypass_enable_flag << 5) + ++ (pps->transform_skip_enabled_flag << 6) + ++ (pps->sign_data_hiding_flag << 7) + ++ (((pps->cb_qp_offset + s->sh.slice_cb_qp_offset)&255) << 8) + ++ (((pps->cr_qp_offset + s->sh.slice_cr_qp_offset)&255) << 16) + ++ (pps->constrained_intra_pred_flag << 24)); ++ ++ if (s->ps.sps->scaling_list_enable_flag) WriteScalingFactors(rpi); ++ ++ if (!s->sh.dependent_slice_segment_flag) { ++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; ++ rpi->reg_slicestart = (ctb_col<<0) + (ctb_row<<16); ++ } ++ ++ p1_apb_write(rpi, RPI_SLICESTART, rpi->reg_slicestart); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void write_slice(RPI_T *rpi, HEVCContext *s, uint8_t slice_w, uint8_t slice_h) { ++ uint32_t u32 = ++ (s->sh.slice_type << 12) ++ + (s->sh.slice_sample_adaptive_offset_flag[0] << 14) ++ + (s->sh.slice_sample_adaptive_offset_flag[1] << 15) ++ + (slice_w << 17) ++ + (slice_h << 24); ++ ++ if (s->sh.slice_type==HEVC_SLICE_B || s->sh.slice_type==HEVC_SLICE_P) u32 |= ++ (s->sh.max_num_merge_cand << 0) ++ + (s->sh.nb_refs[L0] << 4) ++ + (s->sh.nb_refs[L1] << 8); ++ ++ if (s->sh.slice_type==HEVC_SLICE_B) u32 |= s->sh.mvd_l1_zero_flag<<16; ++ p1_apb_write(rpi, RPI_SLICE, u32); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Wavefront mode ++ ++static void wpp_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int ctb_size = 1<log2_ctb_size; ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ ++ int ctb_col = rpi->wpp_entry_x = ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = rpi->wpp_entry_y = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ ++ int endx = rpi->PicWidthInCtbsY-1; ++ int endy = ctb_row; ++ ++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); ++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); ++ ++ p1_apb_write(rpi, RPI_TILESTART, 0); ++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); ++ ++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); ++ ++ write_slice(rpi, s, slice_w, ctb_row==rpi->PicHeightInCtbsY-1? slice_h : ctb_size); ++ ++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); ++ ++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1? 0x60001 : 0x20001); ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Tiles mode ++ ++static void new_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int ctb_col = pps->ctb_addr_ts_to_rs[ctb_addr_ts] % rpi->PicWidthInCtbsY; ++ int ctb_row = pps->ctb_addr_ts_to_rs[ctb_addr_ts] / rpi->PicWidthInCtbsY; ++ ++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); ++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); ++ ++ int endx = pps->col_bd[tile_x+1] - 1; ++ int endy = pps->row_bd[tile_y+1] - 1; ++ ++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, 1<log2_ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); ++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, 1<log2_ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); ++ ++ p1_apb_write(rpi, RPI_TILESTART, pps->col_bd[tile_x] + (pps->row_bd[tile_y]<<16)); ++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); ++ ++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); ++ ++ write_slice(rpi, s, slice_w, slice_h); ++ ++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); ++ ++ p1_apb_write(rpi, RPI_MODE, (0xFFFF << 0) ++ + (0x0 << 16) ++ + ((tile_x==pps->num_tile_columns-1) << 17) ++ + ((tile_y==pps->num_tile_rows-1) << 18)); ++ ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Workaround for 3 December 2016 commit 8dfba25ce89b62c80ba83e2116d549176c376144 ++// https://github.com/libav/libav/commit/8dfba25ce89b62c80ba83e2116d549176c376144 ++// This commit prevents multi-threaded hardware acceleration by locking hwaccel_mutex ++// around codec->decode() calls. Workaround is to unlock and relock before returning. ++ ++static void hwaccel_mutex(AVCodecContext *avctx, int (*action) (pthread_mutex_t *)) { ++ struct FrameThreadContext { ++ void *foo1, *foo2; // must match struct layout in pthread_frame.c ++ pthread_mutex_t foo3, hwaccel_mutex; ++ }; ++ struct PerThreadContext { ++ struct FrameThreadContext *parent; ++ }; ++ struct PerThreadContext *p = avctx->internal->thread_ctx; ++ if (avctx->thread_count>1) action(&p->parent->hwaccel_mutex); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int get_thread_idx(RPI_T *rpi, AVCodecContext *avctx) { ++ int idx; ++ for (idx=0; idxthread_avctx[idx]==avctx) break; ++ av_assert0(idxinternal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ ++ int thread_idx = get_thread_idx(rpi, 0); // Find first free slot ++ ++ rpi->thread_avctx[thread_idx] = avctx; ++ rpi->thread_order[thread_idx] = rpi->decode_order++; ++ ++ ff_thread_finish_setup(avctx); // Allow next thread to enter rpi_hevc_start_frame ++ hwaccel_mutex(avctx, pthread_mutex_unlock); ++ ++ // Enforcing phase 1 order precludes busy waiting for phase 2 ++ for (;;) { ++ pthread_mutex_lock (&rpi->mutex_phase1); ++ if (rpi->thread_order[thread_idx]==rpi->phase1_order) break; ++ pthread_mutex_unlock(&rpi->mutex_phase1); ++ } ++ rpi->phase1_order++; ++ ++ alloc_picture_space(rpi, s, thread_idx); ++ rpi->bit_len = rpi->cmd_len = 0; ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Slice messages ++ ++static void msg_slice(RPI_T *rpi, uint16_t msg) { ++ rpi->slice_msgs[rpi->num_slice_msgs++] = msg; ++} ++ ++static void program_slicecmds(RPI_T *rpi, int sliceid) { ++ int i; ++ p1_apb_write(rpi, RPI_SLICECMDS, rpi->num_slice_msgs+(sliceid<<8)); ++ for(i=0; inum_slice_msgs; i++) { ++ p1_apb_write(rpi, 0x4000+4*i, rpi->slice_msgs[i] & 0xffff); ++ } ++} ++ ++static void pre_slice_decode(RPI_T *rpi, HEVCContext *s) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ SliceHeader *sh = &s->sh; ++ ++ int weightedPredFlag, i, rIdx; ++ uint16_t cmd_slice; ++ ++ rpi->num_slice_msgs=0; ++ cmd_slice = 0; ++ if (sh->slice_type==HEVC_SLICE_I) cmd_slice = 1; ++ if (sh->slice_type==HEVC_SLICE_P) cmd_slice = 2; ++ if (sh->slice_type==HEVC_SLICE_B) cmd_slice = 3; ++ ++ if (sh->slice_type!=HEVC_SLICE_I) { ++ cmd_slice += sh->nb_refs[L0]<<2; ++ cmd_slice += sh->nb_refs[L1]<<6; ++ } ++ if (sh->slice_type==HEVC_SLICE_P ++ || sh->slice_type==HEVC_SLICE_B) rpi->max_num_merge_cand = sh->max_num_merge_cand; ++ ++ cmd_slice += rpi->max_num_merge_cand<<11; ++ ++ if (sh->slice_temporal_mvp_enabled_flag) { ++ if (sh->slice_type==HEVC_SLICE_B) rpi->collocated_from_l0_flag = sh->collocated_list==L0; ++ else if (sh->slice_type==HEVC_SLICE_P) rpi->collocated_from_l0_flag = 1; ++ } ++ cmd_slice += rpi->collocated_from_l0_flag<<14; ++ ++ if (sh->slice_type==HEVC_SLICE_P || sh->slice_type==HEVC_SLICE_B) { ++ ++ int NoBackwardPredFlag = 1; // Flag to say all reference pictures are from the past ++ for(i=L0; i<=L1; i++) { ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ if (c->poc < f->poc) NoBackwardPredFlag = 0; ++ } ++ } ++ ++ rpi->collocated_ref_idx = sh->collocated_ref_idx; ++ if (s->ref->refPicList && s->ref->collocated_ref) ++ for (i=0; inb_refs[L1]) rpi->RefPicList[1][i] = s->ref->refPicList[1].ref[i] - s->DPB; ++ if (inb_refs[L0]) rpi->RefPicList[0][i] = s->ref->refPicList[0].ref[i] - s->DPB; ++ } ++ ++ cmd_slice += NoBackwardPredFlag<<10; ++ msg_slice(rpi, cmd_slice); ++ ++ // Write reference picture descriptions ++ weightedPredFlag = sh->slice_type==HEVC_SLICE_P? pps->weighted_pred_flag : pps->weighted_bipred_flag; ++ ++ for(i=L0; i<=L1; i++) ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ int pic = f - s->DPB; ++ // Make sure pictures are in range 0 to 15 ++ int adjusted_pic = fref->refPicList[i].isLongTerm[rIdx]; ++ msg_slice(rpi, adjusted_pic+(lt<<4)+(weightedPredFlag<<5)+(weightedPredFlag<<6)); ++ msg_slice(rpi, f->poc); ++ if (weightedPredFlag) { ++ msg_slice(rpi, s->sh.luma_log2_weight_denom+(((i?s-> sh.luma_weight_l1: s->sh.luma_weight_l0)[rIdx] &0x1ff)<<3)); ++ msg_slice(rpi, (i?s-> sh.luma_offset_l1: s->sh.luma_offset_l0)[rIdx] & 0xff); ++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][0]&0x1ff)<<3)); ++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][0]& 0xff); ++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][1]&0x1ff)<<3)); ++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][1]& 0xff); ++ } ++ } ++ } ++ else ++ msg_slice(rpi, cmd_slice); ++ ++ msg_slice(rpi, ((sh->beta_offset/2)&15) ++ + (((sh->tc_offset/2)&15) << 4) ++ + (sh->disable_deblocking_filter_flag << 8) ++ + (sh->slice_loop_filter_across_slices_enabled_flag << 9) ++ + (pps->loop_filter_across_tiles_enabled_flag << 10)); // CMD_DEBLOCK ++ ++ msg_slice(rpi, ((sh->slice_cr_qp_offset&31)<<5) + (sh->slice_cb_qp_offset&31)); // CMD_QPOFF ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ int thread_idx = get_thread_idx(rpi, s->avctx); ++ int CurrentPicture = s->ref - s->DPB; ++ int colPic = rpi->RefPicList[sh->slice_type==HEVC_SLICE_B && rpi->collocated_from_l0_flag==0][rpi->collocated_ref_idx]; ++ rpi->mvbase64 [thread_idx] = rpi->mvstorage64 + CurrentPicture * rpi->mvframebytes64; ++ if (sh->slice_type==HEVC_SLICE_I) { ++ // Collocated picture not well defined here. Use mvbase or previous value ++ if (sh->first_slice_in_pic_flag) ++ rpi->colbase64[thread_idx] = rpi->mvbase64[thread_idx]; // Ensure we don't read garbage ++ } ++ else ++ rpi->colbase64[thread_idx] = rpi->mvstorage64 + colPic * rpi->mvframebytes64; ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// End frame ++ ++static int rpi_hevc_end_frame(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ const HEVCPPS *pps = s->ps.pps; ++ const HEVCSPS *sps = s->ps.sps; ++ int thread_idx = get_thread_idx(rpi, avctx); ++ int jump = sps->bit_depth>8?96:128; ++ int CurrentPicture = s->ref - s->DPB; ++ AVFrame *f = s->ref->frame; ++ int last_x = pps->col_bd[pps->num_tile_columns]-1; ++ int last_y = pps->row_bd[pps->num_tile_rows]-1; ++ ++ int i, a64, x; ++ char *buf; ++ ++ // End of phase 1 command compilation ++ if (pps->entropy_coding_sync_enabled_flag) { ++ if (rpi->wpp_entry_x<2 && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); ++ } ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++ ++ // Phase 1 ... ++ for (;;) { ++ // (Re-)allocate PU/COEFF stream space ++ a64 = alloc_stream_space(rpi, s, thread_idx); ++ // Send bitstream data ++ for (i=0; ibit_len; i++) { ++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->bit_fifo[i].len, rpi->bit_fifo[i].ptr); ++ rpi->cmd_fifo[rpi->bit_fifo[i].cmd].data = a64 + (rpi->axi_get_addr(rpi->id)>>6); // Set BFBASE ++ a64 += (rpi->bit_fifo[i].len+63)/64; ++ } ++ // Send phase 1 commands (cache flush on real hardware) ++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD), rpi->cmd_fifo); ++ rpi->axi_flush(rpi->id, 3); ++ phase1_begin(rpi, s, thread_idx); ++ // Trigger command FIFO ++ rpi->apb_write(rpi->id, RPI_CFNUM, rpi->cmd_len); ++ rpi->apb_dump_regs(rpi->id, 0x0, 32); ++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); ++ rpi->axi_dump(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD)); ++ rpi->apb_write_addr(rpi->id, RPI_CFBASE, a64); ++ rpi->wait_interrupt(rpi->id, 1); ++ if (check_status(rpi)==0) break; // No PU/COEFF overflow? ++ } ++ pthread_mutex_unlock(&rpi->mutex_phase1); ++ ++ // Phase 2 ... ++ for (;;) { ++ pthread_mutex_lock (&rpi->mutex_phase2); ++ if (rpi->thread_order[thread_idx]==rpi->phase2_order) break; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ } ++ rpi->phase2_order++; ++ ++ rpi->apb_write_addr(rpi->id, RPI_PURBASE, rpi->pubase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_PURSTRIDE, rpi->pustep64); ++ rpi->apb_write_addr(rpi->id, RPI_COEFFRBASE, rpi->coeffbase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_COEFFRSTRIDE, rpi->coeffstep64); ++ ++#if !defined(AXI_BUFFERS) ++#define MANGLE(x) (((x) &~0xc0000000)>>6) ++{ ++ const AVRpiZcRefPtr fr_buf = f ? av_rpi_zc_ref(avctx, f, f->format, 0) : NULL; ++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; ++// printf("%s cur:%d fr:%p handle:%d YUV:%x:%x ystride:%d ustride:%d ah:%d\n", __FUNCTION__, CurrentPicture, f, handle, get_vc_address_y(f), get_vc_address_u(f), f->linesize[0], f->linesize[1], f->linesize[3]); ++ rpi->apb_write(rpi->id, RPI_OUTYBASE, MANGLE(get_vc_address_y(f))); ++ rpi->apb_write(rpi->id, RPI_OUTCBASE, MANGLE(get_vc_address_u(f))); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, f->linesize[3] * 128 / 64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, f->linesize[3] * 128 / 64); ++ av_rpi_zc_unref(fr_buf); ++} ++#else ++ // Output frame and reference picture locations ++ rpi->apb_write_addr(rpi->id, RPI_OUTYBASE, CurrentPicture * rpi->framebytes64); ++ rpi->apb_write_addr(rpi->id, RPI_OUTCBASE, CurrentPicture * rpi->framebytes64 + rpi->lumabytes64); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, rpi->lumastride64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, rpi->chromastride64); ++#endif ++ ++#if !defined(AXI_BUFFERS) ++{ ++ SliceHeader *sh = &s->sh; ++ int rIdx; ++ for(i=0; i<16; i++) { ++ rpi->apb_write(rpi->id, 0x9000+16*i, 0); ++ rpi->apb_write(rpi->id, 0x9004+16*i, 0); ++ rpi->apb_write(rpi->id, 0x9008+16*i, 0); ++ rpi->apb_write(rpi->id, 0x900C+16*i, 0); ++ } ++ ++ for(i=L0; i<=L1; i++) ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f1 = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ int pic = f1 - s->DPB; ++ // Make sure pictures are in range 0 to 15 ++ int adjusted_pic = f1DPB[pic]; ++ AVFrame *fr = hevc ? hevc->frame : NULL; ++ const AVRpiZcRefPtr fr_buf = fr ? av_rpi_zc_ref(avctx, fr, fr->format, 0) : NULL; ++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; ++// printf("%s pic:%d (%d,%d,%d) fr:%p handle:%d YUV:%x:%x\n", __FUNCTION__, adjusted_pic, i, rIdx, pic, fr, handle, get_vc_address_y(fr), get_vc_address_u(fr)); ++ rpi->apb_write(rpi->id, 0x9000+16*adjusted_pic, MANGLE(get_vc_address_y(fr))); ++ rpi->apb_write(rpi->id, 0x9008+16*adjusted_pic, MANGLE(get_vc_address_u(fr))); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, fr->linesize[3] * 128 / 64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, fr->linesize[3] * 128 / 64); ++ av_rpi_zc_unref(fr_buf); ++ } ++} ++#else ++ for(i=0; i<16; i++) { ++ int pic = i < CurrentPicture ? i : i+1; ++ rpi->apb_write_addr(rpi->id, 0x9000+16*i, pic * rpi->framebytes64); ++ rpi->apb_write(rpi->id, 0x9004+16*i, rpi->lumastride64); ++ rpi->apb_write_addr(rpi->id, 0x9008+16*i, pic * rpi->framebytes64 + rpi->lumabytes64); ++ rpi->apb_write(rpi->id, 0x900C+16*i, rpi->chromastride64); ++ } ++#endif ++ ++ rpi->apb_write(rpi->id, RPI_CONFIG2, ++ (sps->bit_depth << 0) // BitDepthY ++ + (sps->bit_depth << 4) // BitDepthC ++ + ((sps->bit_depth>8) << 8) // BitDepthY ++ + ((sps->bit_depth>8) << 9) // BitDepthC ++ + (sps->log2_ctb_size <<10) ++ + (pps->constrained_intra_pred_flag <<13) ++ + (sps->sps_strong_intra_smoothing_enable_flag<<14) ++ + (sps->sps_temporal_mvp_enabled_flag <<15) ++ + (pps->log2_parallel_merge_level <<16) ++ + (s->sh.slice_temporal_mvp_enabled_flag <<19) ++ + (sps->pcm.loop_filter_disable_flag <<20) ++ + ((pps->cb_qp_offset&31) <<21) ++ + ((pps->cr_qp_offset&31) <<26)); ++ ++ rpi->apb_write(rpi->id, RPI_FRAMESIZE, (sps->height<<16) + sps->width); ++ rpi->apb_write(rpi->id, RPI_CURRPOC, s->poc); ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ rpi->apb_write(rpi->id, RPI_COLSTRIDE, rpi->colstride64); ++ rpi->apb_write(rpi->id, RPI_MVSTRIDE, rpi->mvstride64); ++ rpi->apb_write_addr(rpi->id, RPI_MVBASE, rpi->mvbase64 [thread_idx]); ++ rpi->apb_write_addr(rpi->id, RPI_COLBASE, rpi->colbase64[thread_idx]); ++ } ++ ++ rpi->apb_dump_regs(rpi->id, 0x0, 32); ++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); ++ rpi->apb_write(rpi->id, RPI_NUMROWS, rpi->PicHeightInCtbsY); ++ rpi->apb_read_drop(rpi->id, RPI_NUMROWS); // Read back to confirm write has reached block ++ rpi->wait_interrupt(rpi->id, 2); ++ ++//printf("%s: %dx%d %d\n", __FUNCTION__, f->width, f->height, f->linesize[0]); ++#if defined(AXI_BUFFERS) ++ // Copy YUV output frame ++ av_assert0(buf = malloc(128*sps->height)); ++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64; ++ for(x=0; xwidth; x+=jump) { ++ int bpl = bytes_per_line(sps, jump, x); ++ read_rect(rpi, buf, a64, sps->height, bpl); ++ (sps->bit_depth>8?copy_luma10:copy_luma)(buf, bpl, sps->height, x, f->data[0], f->linesize[0]); ++ a64 += rpi->lumastride64; ++ } ++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64 + rpi->lumabytes64; ++ for(x=0; xwidth; x+=jump) { ++ int bpl = bytes_per_line(sps, jump, x); ++ read_rect(rpi, buf, a64, sps->height/2, bpl); ++ (sps->bit_depth>8?copy_chroma10:copy_chroma)(buf, bpl, sps->height/2, x/2, f->data[1], f->data[2], f->linesize[1]); ++ a64 += rpi->chromastride64; ++ } ++ free(buf); ++#endif ++ rpi->thread_avctx[thread_idx] = 0; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ hwaccel_mutex(avctx, pthread_mutex_lock); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void WriteBitstream(RPI_T *rpi, HEVCContext *s) { ++ const int rpi_use_emu = 0; // FFmpeg removes emulation prevention bytes ++ const int offset = 0; // Always 64-byte aligned in sim, need not be on real hardware ++ GetBitContext *gb = &s->HEVClc->gb; ++ int len = 1 + gb->size_in_bits/8 - gb->index/8; ++ const void *ptr = &gb->buffer[gb->index/8]; ++ ++ p1_axi_write(rpi, len, ptr, p1_apb_write(rpi, RPI_BFBASE, 0)); // BFBASE set later ++ p1_apb_write(rpi, RPI_BFNUM, len); ++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (1<<7)); // Stop ++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (rpi_use_emu<<6)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Wavefront mode ++ ++static void wpp_decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int i, resetQPY=1; ++ int indep = !s->sh.dependent_slice_segment_flag; ++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ ++ if (ctb_addr_ts) wpp_end_previous_slice(rpi, s, ctb_addr_ts); ++ pre_slice_decode(rpi, s); ++ WriteBitstream(rpi, s); ++ if (ctb_addr_ts==0 || indep || rpi->PicWidthInCtbsY==1) WriteProb(rpi); ++ else if (ctb_col==0) p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); ++ else resetQPY=0; ++ program_slicecmds(rpi, s->slice_idx); ++ new_slice_segment(rpi, s); ++ wpp_entry_point(rpi, s, indep, resetQPY, ctb_addr_ts); ++ for (i=0; ish.num_entry_point_offsets; i++) { ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int last_x = rpi->PicWidthInCtbsY-1; ++ if (rpi->PicWidthInCtbsY>2) wpp_pause(rpi, ctb_row); ++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + (last_x<<5) + 2); ++ if (rpi->PicWidthInCtbsY==2) p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); ++ if (rpi->PicWidthInCtbsY==1) WriteProb(rpi); ++ else p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); ++ ctb_addr_ts += pps->column_width[0]; ++ wpp_entry_point(rpi, s, 0, 1, ctb_addr_ts); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Tiles mode ++ ++static void decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int i, resetQPY; ++ ++ if (ctb_addr_ts) end_previous_slice(rpi, s, ctb_addr_ts); ++ pre_slice_decode(rpi, s); ++ WriteBitstream(rpi, s); ++ resetQPY = ctb_addr_ts==0 ++ || pps->tile_id[ctb_addr_ts]!=pps->tile_id[ctb_addr_ts-1] ++ || !s->sh.dependent_slice_segment_flag; ++ if (resetQPY) WriteProb(rpi); ++ program_slicecmds(rpi, s->slice_idx); ++ new_slice_segment(rpi, s); ++ new_entry_point(rpi, s, !s->sh.dependent_slice_segment_flag, resetQPY, ctb_addr_ts); ++ for (i=0; ish.num_entry_point_offsets; i++) { ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ int ctb_col = ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); ++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); ++ int last_x = pps->col_bd[tile_x+1]-1; ++ int last_y = pps->row_bd[tile_y+1]-1; ++ p1_apb_write(rpi, RPI_STATUS, 2 + (last_x<<5) + (last_y<<18)); ++ WriteProb(rpi); ++ ctb_addr_ts += pps->column_width[tile_x] * pps->row_height[tile_y]; ++ new_entry_point(rpi, s, 0, 1, ctb_addr_ts); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_decode_slice( ++ AVCodecContext *avctx, ++ const uint8_t *buffer, ++ uint32_t size) { ++ ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ const HEVCPPS *pps = s->ps.pps; ++ int ctb_addr_ts = pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]; ++ ff_hevc_cabac_init(s, ctb_addr_ts); ++ if (s->ps.sps->scaling_list_enable_flag) populate_scaling_factors(rpi, s); ++ populate_prob_tables(rpi, s); ++ pps->entropy_coding_sync_enabled_flag? wpp_decode_slice(rpi, s, ctb_addr_ts) ++ : decode_slice(rpi, s, ctb_addr_ts); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Bind to socket client ++ ++static int open_socket_client(RPI_T *rpi, const char *so) { ++ *(void **) &rpi->ctrl_ffmpeg_init = rpi_ctrl_ffmpeg_init; ++ *(void **) &rpi->apb_write = rpi_apb_write; ++ *(void **) &rpi->apb_write_addr = rpi_apb_write_addr; ++ *(void **) &rpi->apb_read = rpi_apb_read; ++ *(void **) &rpi->apb_read_drop = rpi_apb_read_drop; ++ *(void **) &rpi->axi_write = rpi_axi_write; ++ *(void **) &rpi->axi_read_alloc = rpi_axi_read_alloc; ++ *(void **) &rpi->axi_read_tx = rpi_axi_read_tx; ++ *(void **) &rpi->axi_read_rx = rpi_axi_read_rx; ++ *(void **) &rpi->axi_get_addr = rpi_axi_get_addr; ++ *(void **) &rpi->apb_dump_regs = rpi_apb_dump_regs; ++ *(void **) &rpi->axi_dump = rpi_axi_dump; ++ *(void **) &rpi->axi_flush = rpi_axi_flush; ++ *(void **) &rpi->wait_interrupt = rpi_wait_interrupt; ++ *(void **) &rpi->ctrl_ffmpeg_free = rpi_ctrl_ffmpeg_free; ++ return 1; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_alloc_frame(AVCodecContext *avctx, AVFrame *f) { ++ HEVCContext *s = avctx->priv_data; ++ const HEVCSPS *sps = s->ps.sps; ++ const int ALIGN = 16; ++ ++ f->width = sps->width; ++ f->height = sps->height; ++ f->format = sps->pix_fmt; ++ f->buf[0] = av_buffer_alloc(1); ++ f->buf[1] = av_buffer_alloc(1); ++ f->buf[2] = av_buffer_alloc(1); ++ return av_image_alloc(f->data, f->linesize, f->width, f->height, f->format, ALIGN); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_init(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ const char *err, *so; ++ ++ so = "./rpi_ffmpeg.so"; ++ ++ if (avctx->width>4096 || avctx->height>4096) { ++ av_log(NULL, AV_LOG_FATAL, "Picture size %dx%d exceeds 4096x4096 maximum for HWAccel\n", avctx->width, avctx->height); ++ return AVERROR(ENOTSUP); ++ } ++ if (!open_socket_client(rpi, so)) { ++ av_log(NULL, AV_LOG_FATAL, "%s\n", dlerror()); ++ return AVERROR_EXTERNAL; ++ } ++ err = rpi->ctrl_ffmpeg_init(NULL, &rpi->id); ++ if (err) { ++ av_log(NULL, AV_LOG_FATAL, "Could not connect to RPI server: %s\n", err); ++ return AVERROR_EXTERNAL; ++ } ++ ++#ifdef RPI_DISPLAY ++ #include "rpi_zc.h" ++ // Whilst FFmpegs init fn is only called once the close fn is called as ++ // many times as we have threads (init_thread_copy is called for the ++ // threads). So to match init & term put the init here where it will be ++ // called by both init & copy ++ av_rpi_zc_init(avctx); ++#endif ++ ++ pthread_mutex_init(&rpi->mutex_phase1, NULL); ++ pthread_mutex_init(&rpi->mutex_phase2, NULL); ++ ++ // Initial PU/COEFF stream buffer sizes chosen so jellyfish40.265 requires 1 overflow/restart ++ rpi->max_pu_msgs = 2+340; // 7.2 says at most 1611 messages per CTU ++ rpi->max_coeff64 = 2+1404; ++ ++ av_assert0(rpi->cmd_fifo = malloc((rpi->cmd_max=1024)*sizeof(struct RPI_CMD))); ++ av_assert0(rpi->bit_fifo = malloc((rpi->bit_max=1024)*sizeof(struct RPI_BIT))); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_free(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ if (rpi->decode_order) wait_idle(rpi, rpi->decode_order); ++ if (rpi->cmd_fifo) free(rpi->cmd_fifo); ++ if (rpi->bit_fifo) free(rpi->bit_fifo); ++ pthread_mutex_destroy(&rpi->mutex_phase1); ++ pthread_mutex_destroy(&rpi->mutex_phase2); ++ if (rpi->id && rpi->ctrl_ffmpeg_free) rpi->ctrl_ffmpeg_free(rpi->id); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++const AVHWAccel ff_hevc_rpi4_8_hwaccel = { ++ .name = "hevc_rpi4_8", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_HEVC, ++ .pix_fmt = AV_PIX_FMT_RPI4_8, ++ //.alloc_frame = rpi_hevc_alloc_frame, ++ .start_frame = rpi_hevc_start_frame, ++ .end_frame = rpi_hevc_end_frame, ++ .decode_slice = rpi_hevc_decode_slice, ++ .init = rpi_hevc_init, ++ .uninit = rpi_hevc_free, ++ .priv_data_size = sizeof(RPI_T), ++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, ++}; ++ ++const AVHWAccel ff_hevc_rpi4_10_hwaccel = { ++ .name = "hevc_rpi4_10", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_HEVC, ++ .pix_fmt = AV_PIX_FMT_RPI4_10, ++ //.alloc_frame = rpi_hevc_alloc_frame, ++ .start_frame = rpi_hevc_start_frame, ++ .end_frame = rpi_hevc_end_frame, ++ .decode_slice = rpi_hevc_decode_slice, ++ .init = rpi_hevc_init, ++ .uninit = rpi_hevc_free, ++ .priv_data_size = sizeof(RPI_T), ++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, ++}; ++ ++ ++int rpi_init(AVCodecContext *avctx) { ++ return 0; ++} +diff --git a/libavcodec/rpi_hevc.h b/libavcodec/rpi_hevc.h +new file mode 100644 +index 0000000000..f54657a957 +--- /dev/null ++++ b/libavcodec/rpi_hevc.h +@@ -0,0 +1,219 @@ ++// FFMPEG HEVC decoder hardware accelerator ++// Andrew Holme, Argon Design Ltd ++// Copyright (c) June 2017 Raspberry Pi Ltd ++ ++#include ++#include ++ ++#include "hevc.h" ++#include "hevcdec.h" ++ ++#define MAX_THREADS 50 ++#define NUM_SCALING_FACTORS 4064 ++ ++#define AXI_BASE64 0 ++ ++#define PROB_BACKUP ((20<<12) + (20<<6) + (0<<0)) ++#define PROB_RELOAD ((20<<12) + (20<<0) + (0<<6)) ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++#define RPI_SPS0 0 ++#define RPI_SPS1 4 ++#define RPI_PPS 8 ++#define RPI_SLICE 12 ++#define RPI_TILESTART 16 ++#define RPI_TILEEND 20 ++#define RPI_SLICESTART 24 ++#define RPI_MODE 28 ++#define RPI_LEFT0 32 ++#define RPI_LEFT1 36 ++#define RPI_LEFT2 40 ++#define RPI_LEFT3 44 ++#define RPI_QP 48 ++#define RPI_CONTROL 52 ++#define RPI_STATUS 56 ++#define RPI_VERSION 60 ++#define RPI_BFBASE 64 ++#define RPI_BFNUM 68 ++#define RPI_BFCONTROL 72 ++#define RPI_BFSTATUS 76 ++#define RPI_PUWBASE 80 ++#define RPI_PUWSTRIDE 84 ++#define RPI_COEFFWBASE 88 ++#define RPI_COEFFWSTRIDE 92 ++#define RPI_SLICECMDS 96 ++#define RPI_BEGINTILEEND 100 ++#define RPI_TRANSFER 104 ++#define RPI_CFBASE 108 ++#define RPI_CFNUM 112 ++#define RPI_CFSTATUS 116 ++ ++#define RPI_PURBASE 0x8000 ++#define RPI_PURSTRIDE 0x8004 ++#define RPI_COEFFRBASE 0x8008 ++#define RPI_COEFFRSTRIDE 0x800C ++#define RPI_NUMROWS 0x8010 ++#define RPI_CONFIG2 0x8014 ++#define RPI_OUTYBASE 0x8018 ++#define RPI_OUTYSTRIDE 0x801C ++#define RPI_OUTCBASE 0x8020 ++#define RPI_OUTCSTRIDE 0x8024 ++#define RPI_STATUS2 0x8028 ++#define RPI_FRAMESIZE 0x802C ++#define RPI_MVBASE 0x8030 ++#define RPI_MVSTRIDE 0x8034 ++#define RPI_COLBASE 0x8038 ++#define RPI_COLSTRIDE 0x803C ++#define RPI_CURRPOC 0x8040 ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct FFM_PROB { ++ uint8_t sao_merge_flag [ 1]; ++ uint8_t sao_type_idx [ 1]; ++ uint8_t split_coding_unit_flag [ 3]; ++ uint8_t cu_transquant_bypass_flag [ 1]; ++ uint8_t skip_flag [ 3]; ++ uint8_t cu_qp_delta [ 3]; ++ uint8_t pred_mode_flag [ 1]; ++ uint8_t part_mode [ 4]; ++ uint8_t prev_intra_luma_pred_flag [ 1]; ++ uint8_t intra_chroma_pred_mode [ 2]; ++ uint8_t merge_flag [ 1]; ++ uint8_t merge_idx [ 1]; ++ uint8_t inter_pred_idc [ 5]; ++ uint8_t ref_idx_l0 [ 2]; ++ uint8_t ref_idx_l1 [ 2]; ++ uint8_t abs_mvd_greater0_flag [ 2]; ++ uint8_t abs_mvd_greater1_flag [ 2]; ++ uint8_t mvp_lx_flag [ 1]; ++ uint8_t no_residual_data_flag [ 1]; ++ uint8_t split_transform_flag [ 3]; ++ uint8_t cbf_luma [ 2]; ++ uint8_t cbf_cb_cr [ 4]; ++ uint8_t transform_skip_flag/*[][]*/ [ 2]; ++ uint8_t explicit_rdpcm_flag/*[][]*/ [ 2]; ++ uint8_t explicit_rdpcm_dir_flag/*[][]*/ [ 2]; ++ uint8_t last_significant_coeff_x_prefix [18]; ++ uint8_t last_significant_coeff_y_prefix [18]; ++ uint8_t significant_coeff_group_flag [ 4]; ++ uint8_t significant_coeff_flag [44]; ++ uint8_t coeff_abs_level_greater1_flag [24]; ++ uint8_t coeff_abs_level_greater2_flag [ 6]; ++ uint8_t log2_res_scale_abs [ 8]; ++ uint8_t res_scale_sign_flag [ 2]; ++ uint8_t cu_chroma_qp_offset_flag [ 1]; ++ uint8_t cu_chroma_qp_offset_idx [ 1]; ++} __attribute__((packed)); ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct RPI_PROB { ++ uint8_t SAO_MERGE_FLAG [ 1]; ++ uint8_t SAO_TYPE_IDX [ 1]; ++ uint8_t SPLIT_FLAG [ 3]; ++ uint8_t CU_SKIP_FLAG [ 3]; ++ uint8_t CU_TRANSQUANT_BYPASS_FLAG [ 1]; ++ uint8_t PRED_MODE [ 1]; ++ uint8_t PART_SIZE [ 4]; ++ uint8_t INTRA_PRED_MODE [ 1]; ++ uint8_t CHROMA_PRED_MODE [ 1]; ++ uint8_t MERGE_FLAG_EXT [ 1]; ++ uint8_t MERGE_IDX_EXT [ 1]; ++ uint8_t INTER_DIR [ 5]; ++ uint8_t REF_PIC [ 2]; ++ uint8_t MVP_IDX [ 1]; ++ uint8_t MVD [ 2]; ++ uint8_t QT_ROOT_CBF [ 1]; ++ uint8_t TRANS_SUBDIV_FLAG [ 3]; ++ uint8_t QT_CBF [ 6]; ++ uint8_t DQP [ 2]; ++ uint8_t ONE_FLAG [24]; ++ uint8_t LASTX [18]; ++ uint8_t LASTY [18]; ++ uint8_t SIG_CG_FLAG [ 4]; ++ uint8_t ABS_FLAG [ 6]; ++ uint8_t TRANSFORMSKIP_FLAG [ 2]; ++ uint8_t SIG_FLAG [42]; ++ uint8_t SIG_FLAG_unused [ 2]; ++} __attribute__((packed)); ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct RPI_CMD { ++ uint32_t addr; ++ uint32_t data; ++} __attribute__((packed)); ++ ++struct RPI_BIT { ++ int cmd; ++ const void *ptr; ++ int len; ++}; ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++typedef struct RPI_T { ++struct RPI_BIT *bit_fifo; ++struct RPI_CMD *cmd_fifo; ++ int bit_len, bit_max; ++ int cmd_len, cmd_max; ++ int max_pu_msgs; ++ int max_coeff64; ++AVCodecContext *thread_avctx[MAX_THREADS]; ++ int thread_order[MAX_THREADS]; ++ int decode_order; ++ int phase1_order; ++ int phase2_order; ++pthread_mutex_t mutex_phase1; ++pthread_mutex_t mutex_phase2; ++ uint8_t scaling_factors[NUM_SCALING_FACTORS]; ++struct RPI_PROB probabilities; ++ int num_slice_msgs; ++ uint16_t slice_msgs[2*HEVC_MAX_REFS*8+3]; ++ int pubase64[MAX_THREADS]; ++ int pustep64; ++ int coeffbase64[MAX_THREADS]; ++ int coeffstep64; ++ int PicWidthInCtbsY; ++ int PicHeightInCtbsY; ++#ifdef AXI_BUFFERS ++ int lumabytes64; ++ int framebytes64; ++ int lumastride64; ++ int chromastride64; ++#endif ++ int mvframebytes64; ++ int mvstorage64; ++ int colstride64; ++ int mvstride64; ++ int colbase64[MAX_THREADS]; ++ int mvbase64[MAX_THREADS]; ++ uint32_t reg_slicestart; ++ int collocated_from_l0_flag; ++ int max_num_merge_cand; ++ int RefPicList[2][HEVC_MAX_REFS]; ++ int collocated_ref_idx; ++ int wpp_entry_x; ++ int wpp_entry_y; ++ ++ void * dl_handle; ++ void * id; ++ char * (* ctrl_ffmpeg_init) (const char *hwaccel_device, void **id); ++ void (* apb_write) (void *id, uint16_t addr, uint32_t data); ++ void (* apb_write_addr) (void *id, uint16_t addr, uint32_t data); ++ uint32_t (* apb_read) (void *id, uint16_t addr); ++ void (* apb_read_drop) (void *id, uint16_t addr); ++ void (* axi_write) (void *id, uint64_t addr, uint32_t size, const void *buf); ++ void (* axi_read_alloc) (void *id, uint32_t size); ++ void (* axi_read_tx) (void *id, uint64_t addr, uint32_t size); ++ void (* axi_read_rx) (void *id, uint32_t size, void *buf); ++ uint64_t (* axi_get_addr) (void *id); ++ void (* apb_dump_regs) (void *id, uint16_t addr, int num); ++ void (* axi_dump) (void *id, uint64_t addr, uint32_t size); ++ void (* axi_flush) (void *id, int mode); ++ void (* wait_interrupt) (void *id, int phase); ++ void (* ctrl_ffmpeg_free) (void *id); ++ ++} RPI_T; +diff --git a/libavcodec/rpi_mailbox.c b/libavcodec/rpi_mailbox.c +new file mode 100644 +index 0000000000..5f23e9b36c +--- /dev/null ++++ b/libavcodec/rpi_mailbox.c +@@ -0,0 +1,149 @@ ++/* ++Copyright (c) 2012, Broadcom Europe Ltd. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ * 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. ++ * Neither the name of the copyright holder 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY ++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#if 1//defined(RPI) || defined (RPI_DISPLAY) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define MAJOR_NUM 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++#define DEVICE_FILE_NAME "/dev/vcio" ++ ++#include "rpi_mailbox.h" ++//#include ++ ++/* ++ * use ioctl to send mbox property message ++ */ ++ ++static int mbox_property(int file_desc, void *buf) ++{ ++ int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); ++ ++ if (ret_val < 0) { ++ printf("ioctl_set_msg failed:%d\n", ret_val); ++ } ++ ++#ifdef DEBUG ++ unsigned *p = buf; int i; unsigned size = *(unsigned *)buf; ++ for (i=0; i ++#include ++#include ++#include ++#include ++#include "libavutil/avassert.h" ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include ++ ++#include "rpi_mailbox.h" ++#include "rpi_qpu.h" ++ ++#pragma GCC diagnostic push ++// Many many redundant decls in the header files ++#pragma GCC diagnostic ignored "-Wredundant-decls" ++#include "interface/vmcs_host/vc_vchi_gpuserv.h" ++#pragma GCC diagnostic pop ++ ++// QPU "noflush" flags ++// a mixture of flushing & profiling ++ ++#define QPU_FLAGS_NO_FLUSH_VPU 1 // If unset VPU cache will be flushed ++#define QPU_FLAGS_PROF_CLEAR_AND_ENABLE 2 // Clear & Enable detailed QPU profiling registers ++#define QPU_FLAGS_PROF_OUTPUT_COUNTS 4 // Print the results ++#define QPU_FLAGS_OUTPUT_QPU_TIMES 8 // Print QPU times - independant of the profiling ++#define QPU_FLAGS_NO_FLUSH_QPU 16 // If unset flush QPU caches & TMUs (uniforms always flushed) ++ ++#define vcos_verify_ge0(x) ((x)>=0) ++ ++struct rpi_cache_flush_env_s { ++// unsigned int n; ++// struct vcsm_user_clean_invalid_s a[CFE_A_COUNT]; ++ struct vcsm_user_clean_invalid2_s v; ++}; ++ ++typedef struct gpu_env_s ++{ ++ int open_count; ++ int init_count; ++ int mb; ++ int vpu_i_cache_flushed; ++} gpu_env_t; ++ ++// Stop more than one thread trying to allocate memory or use the processing resources at once ++static pthread_mutex_t gpu_mutex = PTHREAD_MUTEX_INITIALIZER; ++static gpu_env_t * gpu = NULL; ++ ++ ++// GPU memory alloc fns (internal) ++ ++// GPU_MEM_PTR_T alloc fns ++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = (numbytes + 255) & ~255; // Round up ++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_VC, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_HOST_AND_VC, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++// printf("***** %s, %d\n", __func__, numbytes); ++ ++ return 0; ++} ++ ++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = numbytes; ++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++// printf("***** %s, %d\n", __func__, numbytes); ++ return 0; ++} ++ ++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { ++ mbox_mem_unlock(mb, p->vc_handle); ++ vcsm_unlock_ptr(p->arm); ++ vcsm_free(p->vcsm_handle); ++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again ++// printf("***** %s\n", __func__); ++} ++ ++ ++// GPU init, free, lock, unlock ++ ++static void gpu_term(void) ++{ ++ gpu_env_t * const ge = gpu; ++ ++ // We have to hope that eveything has terminated... ++ gpu = NULL; ++ ++ vc_gpuserv_deinit(); ++ ++ vcsm_exit(); ++ ++ mbox_close(ge->mb); ++ ++ free(ge); ++} ++ ++ ++// Connect to QPU, returns 0 on success. ++static int gpu_init(gpu_env_t ** const gpu) { ++ gpu_env_t * const ge = calloc(1, sizeof(gpu_env_t)); ++ *gpu = NULL; ++ ++ if (ge == NULL) ++ return -1; ++ ++ if ((ge->mb = mbox_open()) < 0) ++ return -1; ++ ++ vcsm_init(); ++ ++ *gpu = ge; ++ return 0; ++} ++ ++ ++ ++static void gpu_unlock(void) { ++ pthread_mutex_unlock(&gpu_mutex); ++} ++ ++// Make sure we have exclusive access to the mailbox, and enable qpu if necessary. ++static gpu_env_t * gpu_lock(void) { ++ pthread_mutex_lock(&gpu_mutex); ++ ++ av_assert0(gpu != NULL); ++ return gpu; ++} ++ ++static gpu_env_t * gpu_lock_ref(void) ++{ ++ pthread_mutex_lock(&gpu_mutex); ++ ++ if (gpu == NULL) { ++ int rv = gpu_init(&gpu); ++ if (rv != 0) { ++ gpu_unlock(); ++ return NULL; ++ } ++ } ++ ++ ++gpu->open_count; ++ return gpu; ++} ++ ++static void gpu_unlock_unref(gpu_env_t * const ge) ++{ ++ if (--ge->open_count == 0) ++ gpu_term(); ++ ++ gpu_unlock(); ++} ++ ++static inline gpu_env_t * gpu_ptr(void) ++{ ++ av_assert0(gpu != NULL); ++ return gpu; ++} ++ ++// Public gpu fns ++ ++// Allocate memory on GPU ++// Fills in structure

containing ARM pointer, videocore handle, videocore memory address, numbytes ++// Returns 0 on success. ++// This allocates memory that will not be cached in ARM's data cache. ++// Therefore safe to use without data cache flushing. ++int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p) ++{ ++ int r; ++ gpu_env_t * const ge = gpu_lock_ref(); ++ if (ge == NULL) ++ return -1; ++ r = gpu_malloc_uncached_internal(ge->mb, numbytes, p); ++ gpu_unlock(); ++ return r; ++} ++ ++// This allocates data that will be ++// Cached in ARM L2 ++// Uncached in VPU L2 ++int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p) ++{ ++ int r; ++ gpu_env_t * const ge = gpu_lock_ref(); ++ if (ge == NULL) ++ return -1; ++ r = gpu_malloc_cached_internal(ge->mb, numbytes, p); ++ gpu_unlock(); ++ return r; ++} ++ ++void gpu_free(GPU_MEM_PTR_T * const p) { ++ gpu_env_t * const ge = gpu_lock(); ++ gpu_free_internal(ge->mb, p); ++ gpu_unlock_unref(ge); ++} ++ ++int gpu_get_mailbox(void) ++{ ++ av_assert0(gpu); ++ return gpu->mb; ++} ++ ++void gpu_ref(void) ++{ ++ gpu_lock_ref(); ++ gpu_unlock(); ++} ++ ++void gpu_unref(void) ++{ ++ gpu_env_t * const ge = gpu_lock(); ++ gpu_unlock_unref(ge); ++} ++ ++// ---------------------------------------------------------------------------- ++// ++// Cache flush functions ++ ++#define CACHE_EL_MAX 16 ++ ++rpi_cache_flush_env_t * rpi_cache_flush_init() ++{ ++ rpi_cache_flush_env_t * const rfe = malloc(sizeof(rpi_cache_flush_env_t) + ++ sizeof(struct vcsm_user_clean_invalid2_block_s) * CACHE_EL_MAX); ++ if (rfe == NULL) ++ return NULL; ++ ++ rfe->v.op_count = 0; ++ return rfe; ++} ++ ++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe) ++{ ++ if (rfe != NULL) ++ free(rfe); ++} ++ ++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe) ++{ ++ int rc = 0; ++ ++ if (vcsm_clean_invalid2(&rfe->v) != 0) ++ rc = -1; ++ ++ free(rfe); ++ ++ if (rc == 0) ++ return 0; ++ ++ av_log(NULL, AV_LOG_ERROR, "vcsm_clean_invalid failed: errno=%d\n", errno); ++ return rc; ++} ++ ++inline void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride) ++{ ++ struct vcsm_user_clean_invalid2_block_s * const b = rfe->v.s + rfe->v.op_count++; ++ ++ av_assert0(rfe->v.op_count <= CACHE_EL_MAX); ++ ++ b->invalidate_mode = mode; ++ b->block_count = blocks; ++ b->start_address = gm->arm + offset0; ++ b->block_size = block_size; ++ b->inter_block_stride = block_stride; ++} ++ ++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset, const unsigned int size) ++{ ++ // Deal with empty pointer trivially ++ if (gm == NULL || size == 0) ++ return; ++ ++ av_assert0(offset <= gm->numbytes); ++ av_assert0(size <= gm->numbytes); ++ av_assert0(offset + size <= gm->numbytes); ++ ++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, offset, size, 1, 0); ++} ++ ++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode) ++{ ++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, 0, gm->numbytes, 1, 0); ++} ++ ++ ++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const unsigned int mode) ++{ ++#if !RPI_ONE_BUF ++#error Fixme! (NIF) ++#endif ++ if (gpu_is_buf1(frame)) { ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf1_gmem(frame), mode); ++ } ++ else ++ { ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 0), mode); ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 1), mode); ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 2), mode); ++ } ++} ++ ++// Call this to clean and invalidate a region of memory ++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T *const p, const rpi_cache_flush_mode_t mode) ++{ ++ rpi_cache_flush_env_t * rfe = rpi_cache_flush_init(); ++ rpi_cache_flush_add_gm_ptr(rfe, p, mode); ++ rpi_cache_flush_finish(rfe); ++} ++ ++ ++// ---------------------------------------------------------------------------- ++ ++#endif // RPI +diff --git a/libavcodec/rpi_qpu.h b/libavcodec/rpi_qpu.h +new file mode 100644 +index 0000000000..485a08f8ba +--- /dev/null ++++ b/libavcodec/rpi_qpu.h +@@ -0,0 +1,206 @@ ++#ifndef RPI_QPU_H ++#define RPI_QPU_H ++ ++#define RPI_ONE_BUF 1 ++ ++typedef struct gpu_mem_ptr_s { ++ unsigned char *arm; // Pointer to memory mapped on ARM side ++ int vc_handle; // Videocore handle of relocatable memory ++ int vcsm_handle; // Handle for use by VCSM ++ int vc; // Address for use in GPU code ++ int numbytes; // Size of memory block ++} GPU_MEM_PTR_T; ++ ++// General GPU functions ++extern int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p); ++extern int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p); ++extern void gpu_free(GPU_MEM_PTR_T * const p); ++ ++#include "libavutil/frame.h" ++#if !RPI_ONE_BUF ++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[0]); ++ return p->vc; ++} ++ ++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[1]); ++ return p->vc; ++} ++ ++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[2]); ++ return p->vc; ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[0]); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[1]); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[2]); ++} ++ ++#else ++ ++static inline int gpu_is_buf1(const AVFrame * const frame) ++{ ++ return frame->buf[1] == NULL; ++} ++ ++static inline GPU_MEM_PTR_T * gpu_buf1_gmem(const AVFrame * const frame) ++{ ++ return av_buffer_get_opaque(frame->buf[0]); ++} ++ ++static inline GPU_MEM_PTR_T * gpu_buf3_gmem(const AVFrame * const frame, const unsigned int n) ++{ ++ return av_buffer_pool_opaque(frame->buf[n]); ++} ++ ++static inline uint32_t get_vc_address3(const AVFrame * const frame, const unsigned int n) ++{ ++ const GPU_MEM_PTR_T * const gm = gpu_is_buf1(frame) ? gpu_buf1_gmem(frame) : gpu_buf3_gmem(frame, n); ++ return gm->vc + (frame->data[n] - gm->arm); ++} ++ ++ ++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { ++ return get_vc_address3(frame, 0); ++} ++ ++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { ++ return get_vc_address3(frame, 1); ++} ++ ++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { ++ return get_vc_address3(frame, 2); ++} ++ ++#if 0 ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.numbytes = frame->data[1] - frame->data[0]; ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 0); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.arm += frame->data[1] - frame->data[0]; ++ g.vc += frame->data[1] - frame->data[0]; ++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 1); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.arm += frame->data[2] - frame->data[0]; ++ g.vc += frame->data[2] - frame->data[0]; ++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 2); ++} ++#endif ++#endif ++ ++// Cache flush stuff ++ ++struct rpi_cache_flush_env_s; ++typedef struct rpi_cache_flush_env_s rpi_cache_flush_env_t; ++ ++rpi_cache_flush_env_t * rpi_cache_flush_init(void); ++// Free env without flushing ++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe); ++// Do the accumulated flush & free the env ++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe); ++ ++typedef enum ++{ ++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, ++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, ++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 ++} rpi_cache_flush_mode_t; ++ ++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode); ++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode, ++ const unsigned int offset, const unsigned int size); ++void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride); ++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode); ++void rpi_cache_flush_add_frame_block(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode, ++ const unsigned int x0, const unsigned int y0, const unsigned int width, const unsigned int height, ++ const unsigned int uv_shift, const int do_luma, const int do_chroma); ++ ++// init, add, finish for one gm ptr ++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T * const p, const rpi_cache_flush_mode_t mode); ++ ++ ++// QPU specific functions ++ ++typedef struct HEVCRpiQpu { ++ uint32_t c_pxx; ++ uint32_t c_pxx_l1; ++ uint32_t c_bxx; ++ uint32_t y_pxx; ++ uint32_t y_bxx; ++ uint32_t y_p00; ++ uint32_t y_b00; ++} HEVCRpiQpu; ++ ++int rpi_hevc_qpu_init_fn(HEVCRpiQpu * const qf, const unsigned int bit_depth); ++ ++uint32_t qpu_fn(const int * const mc_fn); ++ ++#define QPU_N_GRP 4 ++#define QPU_N_MAX 12 ++ ++#define QPU_MAIL_EL_VALS 2 ++ ++struct vpu_qpu_wait_s; ++typedef struct vq_wait_s * vpu_qpu_wait_h; ++ ++// VPU specific functions ++ ++struct vpu_qpu_job_env_s; ++typedef struct vpu_qpu_job_env_s * vpu_qpu_job_h; ++ ++vpu_qpu_job_h vpu_qpu_job_new(void); ++void vpu_qpu_job_delete(const vpu_qpu_job_h vqj); ++void vpu_qpu_job_add_vpu(const vpu_qpu_job_h vqj, const uint32_t vpu_code, ++ const unsigned r0, const unsigned r1, const unsigned r2, const unsigned r3, const unsigned r4, const unsigned r5); ++void vpu_qpu_job_add_qpu(const vpu_qpu_job_h vqj, const unsigned int n, const uint32_t * const mail); ++void vpu_qpu_job_add_sync_this(const vpu_qpu_job_h vqj, vpu_qpu_wait_h * const wait_h); ++int vpu_qpu_job_start(const vpu_qpu_job_h vqj); ++int vpu_qpu_job_finish(const vpu_qpu_job_h vqj); ++ ++extern unsigned int vpu_get_fn(const unsigned int bit_depth); ++extern unsigned int vpu_get_constants(void); ++ ++// Waits for previous post_codee to complete and Will null out *wait_h after use ++void vpu_qpu_wait(vpu_qpu_wait_h * const wait_h); ++int vpu_qpu_init(void); ++void vpu_qpu_term(void); ++ ++extern int gpu_get_mailbox(void); ++void gpu_ref(void); ++void gpu_unref(void); ++ ++#endif +diff --git a/libavcodec/rpi_zc.c b/libavcodec/rpi_zc.c +new file mode 100644 +index 0000000000..3bf1da4083 +--- /dev/null ++++ b/libavcodec/rpi_zc.c +@@ -0,0 +1,743 @@ ++#include "config.h" ++#if 1 //defined(RPI) //|| defined (RPI_DISPLAY) ++#include "libavcodec/avcodec.h" ++#include "rpi_qpu.h" ++#include "rpi_mailbox.h" ++#include "rpi_zc.h" ++#include "libavutil/avassert.h" ++#include ++ ++#include "libavutil/buffer_internal.h" ++#include ++ ++#define TRACE_ALLOC 0 ++ ++struct ZcPoolEnt; ++ ++typedef struct ZcPool ++{ ++ int numbytes; ++ unsigned int n; ++ struct ZcPoolEnt * head; ++ pthread_mutex_t lock; ++} ZcPool; ++ ++typedef struct ZcPoolEnt ++{ ++ // It is important that we start with gmem as other bits of code will expect to see that ++ GPU_MEM_PTR_T gmem; ++ unsigned int n; ++ struct ZcPoolEnt * next; ++ struct ZcPool * pool; ++} ZcPoolEnt; ++ ++#define ALLOC_PAD 0 ++#define ALLOC_ROUND 0x1000 ++#define ALLOC_N_OFFSET 0 ++#define STRIDE_ROUND 64 ++#define STRIDE_OR 0 ++ ++#define DEBUG_ZAP0_BUFFERS 0 ++ ++static inline int av_rpi_is_sand_format(const int format) ++{ ++ return (format >= AV_PIX_FMT_SAND128 && format <= AV_PIX_FMT_SAND64_16) || ++ (format == AV_PIX_FMT_RPI4_8 || format == AV_PIX_FMT_RPI4_10); ++} ++ ++static inline int av_rpi_is_sand_frame(const AVFrame * const frame) ++{ ++ return av_rpi_is_sand_format(frame->format); ++} ++ ++static ZcPoolEnt * zc_pool_ent_alloc(ZcPool * const pool, const unsigned int req_size) ++{ ++ ZcPoolEnt * const zp = av_malloc(sizeof(ZcPoolEnt)); ++ ++ // Round up to 4k & add 4k ++ const unsigned int alloc_size = (req_size + ALLOC_PAD + ALLOC_ROUND - 1) & ~(ALLOC_ROUND - 1); ++ ++ if (zp == NULL) { ++ av_log(NULL, AV_LOG_ERROR, "av_malloc(ZcPoolEnt) failed\n"); ++ goto fail0; ++ } ++ ++ if (gpu_malloc_cached(alloc_size, &zp->gmem) != 0) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_gpu_malloc_cached(%d) failed\n", alloc_size); ++ goto fail1; ++ } ++ ++#if TRACE_ALLOC ++ printf("%s: Alloc %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); ++#endif ++ ++ pool->numbytes = zp->gmem.numbytes; ++ zp->next = NULL; ++ zp->pool = pool; ++ zp->n = pool->n++; ++ return zp; ++ ++fail1: ++ av_free(zp); ++fail0: ++ return NULL; ++} ++ ++static void zc_pool_ent_free(ZcPoolEnt * const zp) ++{ ++#if TRACE_ALLOC ++ printf("%s: Free %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); ++#endif ++ ++ gpu_free(&zp->gmem); ++ av_free(zp); ++} ++ ++static void zc_pool_flush(ZcPool * const pool) ++{ ++ ZcPoolEnt * p = pool->head; ++ pool->head = NULL; ++ pool->numbytes = -1; ++ ++ while (p != NULL) ++ { ++ ZcPoolEnt * const zp = p; ++ p = p->next; ++ zc_pool_ent_free(zp); ++ } ++} ++ ++static ZcPoolEnt * zc_pool_alloc(ZcPool * const pool, const int req_bytes) ++{ ++ ZcPoolEnt * zp; ++ int numbytes; ++ ++ pthread_mutex_lock(&pool->lock); ++ ++ numbytes = pool->numbytes; ++ ++ // If size isn't close then dump the pool ++ // Close in this context means within 128k ++ if (req_bytes > numbytes || req_bytes + 0x20000 < numbytes) ++ { ++ zc_pool_flush(pool); ++ numbytes = req_bytes; ++ } ++ ++ if (pool->head != NULL) ++ { ++ zp = pool->head; ++ pool->head = zp->next; ++ } ++ else ++ { ++ zp = zc_pool_ent_alloc(pool, numbytes); ++ } ++ ++ pthread_mutex_unlock(&pool->lock); ++ ++ // Start with our buffer empty of preconceptions ++// rpi_cache_flush_one_gm_ptr(&zp->gmem, RPI_CACHE_FLUSH_MODE_INVALIDATE); ++ ++ return zp; ++} ++ ++static void zc_pool_free(ZcPoolEnt * const zp) ++{ ++ ZcPool * const pool = zp == NULL ? NULL : zp->pool; ++ if (zp != NULL) ++ { ++ pthread_mutex_lock(&pool->lock); ++#if TRACE_ALLOC ++ printf("%s: Recycle %#x, %#x\n", __func__, pool->numbytes, zp->gmem.numbytes); ++#endif ++ ++ if (pool->numbytes == zp->gmem.numbytes) ++ { ++ zp->next = pool->head; ++ pool->head = zp; ++ pthread_mutex_unlock(&pool->lock); ++ } ++ else ++ { ++ pthread_mutex_unlock(&pool->lock); ++ zc_pool_ent_free(zp); ++ } ++ } ++} ++ ++static void ++zc_pool_init(ZcPool * const pool) ++{ ++ pool->numbytes = -1; ++ pool->head = NULL; ++ pthread_mutex_init(&pool->lock, NULL); ++} ++ ++static void ++zc_pool_destroy(ZcPool * const pool) ++{ ++ pool->numbytes = -1; ++ zc_pool_flush(pool); ++ pthread_mutex_destroy(&pool->lock); ++} ++ ++typedef struct ZcOldCtxVals ++{ ++ int thread_safe_callbacks; ++ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); ++ void * get_buffer_context; ++} ZcOldCtxVals; ++ ++typedef struct AVZcEnv ++{ ++ unsigned int refcount; ++ ZcPool pool; ++ ZcOldCtxVals old; ++} ZcEnv; ++ ++// Callback when buffer unrefed to zero ++static void rpi_free_display_buffer(void *opaque, uint8_t *data) ++{ ++ ZcPoolEnt *const zp = opaque; ++// printf("%s: data=%p\n", __func__, data); ++ zc_pool_free(zp); ++} ++ ++static inline GPU_MEM_PTR_T * pic_gm_ptr(AVBufferRef * const buf) ++{ ++ // Kludge where we check the free fn to check this is really ++ // one of our buffers - can't think of a better way ++ return buf == NULL || buf->buffer->free != rpi_free_display_buffer ? NULL : ++ av_buffer_get_opaque(buf); ++} ++ ++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( ++ const int format, const unsigned int video_width, const unsigned int video_height) ++{ ++ AVRpiZcFrameGeometry geo; ++ ++ switch (format) ++ { ++ case AV_PIX_FMT_YUV420P: ++ geo.stride_y = ((video_width + 32 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; ++ geo.stride_c = geo.stride_y / 2; ++ geo.height_y = (video_height + 32 + 31) & ~31; ++ geo.height_c = geo.height_y / 2; ++ geo.planes_c = 2; ++ geo.stripes = 1; ++ geo.bytes_per_pel = 1; ++ geo.stripe_is_yc = 1; ++ break; ++ ++ case AV_PIX_FMT_YUV420P10: ++ geo.stride_y = ((video_width * 2 + 64 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; ++ geo.stride_c = geo.stride_y / 2; ++ geo.height_y = (video_height + 32 + 31) & ~31; ++ geo.height_c = geo.height_y / 2; ++ geo.planes_c = 2; ++ geo.stripes = 1; ++ geo.bytes_per_pel = 2; ++ geo.stripe_is_yc = 1; ++ break; ++ ++ case AV_PIX_FMT_SAND128: ++ case AV_PIX_FMT_RPI4_8: ++ { ++ const unsigned int stripe_w = 128; ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV_UV, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.stripe_is_yc = 1; ++ if (geo.height_y * stripe_w > img.pitch) ++ { ++ // "tall" sand - all C blocks now follow Y ++ geo.height_y = img.pitch / stripe_w; ++ geo.height_c = geo.height_y; ++ geo.stripe_is_yc = 0; ++ } ++ geo.planes_c = 1; ++ geo.stripes = (video_width + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++#if 0 ++ printf("Req: %dx%d: stride=%d/%d, height=%d/%d, stripes=%d, img.pitch=%d\n", ++ video_width, video_height, ++ geo.stride_y, geo.stride_c, ++ geo.height_y, geo.height_c, ++ geo.stripes, img.pitch); ++#endif ++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); ++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); ++ break; ++ } ++ ++ case AV_PIX_FMT_RPI4_10: ++ { ++ const unsigned int stripe_w = 128; // bytes ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV10COL, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.planes_c = 1; ++ geo.stripes = ((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 1; ++ geo.stripe_is_yc = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++ ++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); ++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); ++ break; ++ } ++ ++ case AV_PIX_FMT_SAND64_16: ++ case AV_PIX_FMT_SAND64_10: ++ { ++ const unsigned int stripe_w = 128; // bytes ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV_UV_16, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.planes_c = 1; ++ geo.stripes = (video_width * 2 + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 2; ++ geo.stripe_is_yc = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++ break; ++ } ++ ++ default: ++ memset(&geo, 0, sizeof(geo)); ++ break; ++ } ++ return geo; ++} ++ ++ ++static AVBufferRef * rpi_buf_pool_alloc(ZcPool * const pool, int size) ++{ ++ ZcPoolEnt *const zp = zc_pool_alloc(pool, size); ++ AVBufferRef * buf; ++ intptr_t idata = (intptr_t)zp->gmem.arm; ++#if ALLOC_N_OFFSET != 0 ++ intptr_t noff = (zp->n * ALLOC_N_OFFSET) & (ALLOC_PAD - 1); ++#endif ++ ++ if (zp == NULL) { ++ av_log(NULL, AV_LOG_ERROR, "zc_pool_alloc(%d) failed\n", size); ++ goto fail0; ++ } ++ ++#if ALLOC_N_OFFSET != 0 ++ idata = ((idata & ~(ALLOC_PAD - 1)) | noff) + (((idata & (ALLOC_PAD - 1)) > noff) ? ALLOC_PAD : 0); ++#endif ++ ++#if DEBUG_ZAP0_BUFFERS ++ memset((void*)idata, 0, size); ++#endif ++ ++ if ((buf = av_buffer_create((void *)idata, size, rpi_free_display_buffer, zp, AV_BUFFER_FLAG_READONLY)) == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_buffer_create() failed\n"); ++ goto fail2; ++ } ++ ++ return buf; ++ ++fail2: ++ zc_pool_free(zp); ++fail0: ++ return NULL; ++} ++ ++static int rpi_get_display_buffer(ZcEnv *const zc, AVFrame * const frame) ++{ ++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(frame->format, frame->width, frame->height); ++ const unsigned int size_y = geo.stride_y * geo.height_y; ++ const unsigned int size_c = geo.stride_c * geo.height_c; ++ const unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes; ++ AVBufferRef * buf; ++ unsigned int i; ++ ++// printf("Do local alloc: format=%#x, %dx%d: %u\n", frame->format, frame->width, frame->height, size_pic); ++ ++ if ((buf = rpi_buf_pool_alloc(&zc->pool, size_pic)) == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "rpi_get_display_buffer: Failed to get buffer from pool\n"); ++ return AVERROR(ENOMEM); ++ } ++ ++ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { ++ frame->buf[i] = NULL; ++ frame->data[i] = NULL; ++ frame->linesize[i] = 0; ++ } ++ ++ frame->buf[0] = buf; ++ ++ frame->linesize[0] = geo.stride_y; ++ frame->linesize[1] = geo.stride_c; ++ frame->linesize[2] = geo.stride_c; ++ // abuse: linesize[3] = "stripe stride" ++ // stripe_stride is NOT the stride between slices it is (that / geo.stride_y). ++ // In a general case this makes the calculation an xor and multiply rather ++ // than a divide and multiply ++ if (geo.stripes > 1) ++ frame->linesize[3] = geo.stripe_is_yc ? geo.height_y + geo.height_c : geo.height_y; ++ ++ frame->data[0] = buf->data; ++ frame->data[1] = frame->data[0] + (geo.stripe_is_yc ? size_y : size_y * geo.stripes); ++ if (geo.planes_c > 1) ++ frame->data[2] = frame->data[1] + size_c; ++ ++ frame->extended_data = frame->data; ++ // Leave extended buf alone ++ ++#if RPI_ZC_SAND_8_IN_10_BUF != 0 ++ // *** If we intend to use this for real we will want a 2nd buffer pool ++ frame->buf[RPI_ZC_SAND_8_IN_10_BUF] = rpi_buf_pool_alloc(&zc->pool, size_pic); // *** 2 * wanted size - kludge ++#endif ++ ++ return 0; ++} ++ ++#define RPI_GET_BUFFER2 1 ++ ++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags) ++{ ++#if !RPI_GET_BUFFER2 ++ return avcodec_default_get_buffer2(s, frame, flags); ++#else ++ int rv; ++ ++ if ((s->codec->capabilities & AV_CODEC_CAP_DR1) == 0) ++ { ++// printf("Do default alloc: format=%#x\n", frame->format); ++ rv = avcodec_default_get_buffer2(s, frame, flags); ++ } ++ else if (frame->format == AV_PIX_FMT_YUV420P || ++ av_rpi_is_sand_frame(frame)) ++ { ++ rv = rpi_get_display_buffer(s->get_buffer_context, frame); ++ } ++ else ++ { ++ rv = avcodec_default_get_buffer2(s, frame, flags); ++ } ++ ++#if 0 ++ printf("%s: fmt:%d, %dx%d lsize=%d/%d/%d/%d data=%p/%p/%p bref=%p/%p/%p opaque[0]=%p\n", __func__, ++ frame->format, frame->width, frame->height, ++ frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3], ++ frame->data[0], frame->data[1], frame->data[2], ++ frame->buf[0], frame->buf[1], frame->buf[2], ++ av_buffer_get_opaque(frame->buf[0])); ++#endif ++ return rv; ++#endif ++} ++ ++ ++static AVBufferRef * zc_copy(struct AVCodecContext * const s, ++ const AVFrame * const src) ++{ ++ AVFrame dest_frame; ++ AVFrame * const dest = &dest_frame; ++ unsigned int i; ++ uint8_t * psrc, * pdest; ++ ++ dest->format = src->format; ++ dest->width = src->width; ++ dest->height = src->height; ++ ++ if (rpi_get_display_buffer(s->get_buffer_context, dest) != 0) ++ { ++ return NULL; ++ } ++ ++ for (i = 0, psrc = src->data[0], pdest = dest->data[0]; ++ i != dest->height; ++ ++i, psrc += src->linesize[0], pdest += dest->linesize[0]) ++ { ++ memcpy(pdest, psrc, dest->width); ++ } ++ for (i = 0, psrc = src->data[1], pdest = dest->data[1]; ++ i != dest->height / 2; ++ ++i, psrc += src->linesize[1], pdest += dest->linesize[1]) ++ { ++ memcpy(pdest, psrc, dest->width / 2); ++ } ++ for (i = 0, psrc = src->data[2], pdest = dest->data[2]; ++ i != dest->height / 2; ++ ++i, psrc += src->linesize[2], pdest += dest->linesize[2]) ++ { ++ memcpy(pdest, psrc, dest->width / 2); ++ } ++ ++ return dest->buf[0]; ++} ++ ++ ++static AVBufferRef * zc_420p10_to_sand128(struct AVCodecContext * const s, ++ const AVFrame * const src) ++{ ++ assert(0); ++ return NULL; ++} ++ ++ ++static AVBufferRef * zc_sand64_16_to_sand128(struct AVCodecContext * const s, ++ const AVFrame * const src, const unsigned int src_bits) ++{ ++ assert(0); ++ return NULL; ++} ++ ++ ++ ++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, ++ const AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy) ++{ ++ assert(s != NULL); ++ ++ if (frame->format != AV_PIX_FMT_YUV420P && ++ frame->format != AV_PIX_FMT_YUV420P10 && ++ !av_rpi_is_sand_frame(frame)) ++ { ++ av_log(s, AV_LOG_WARNING, "%s: *** Format not SAND/YUV420P: %d\n", __func__, frame->format); ++ return NULL; ++ } ++ ++ if (frame->buf[1] != NULL || frame->format != expected_format) ++ { ++#if RPI_ZC_SAND_8_IN_10_BUF ++ if (frame->format == AV_PIX_FMT_SAND64_10 && expected_format == AV_PIX_FMT_SAND128 && frame->buf[RPI_ZC_SAND_8_IN_10_BUF] != NULL) ++ { ++// av_log(s, AV_LOG_INFO, "%s: --- found buf[4]\n", __func__); ++ return av_buffer_ref(frame->buf[RPI_ZC_SAND_8_IN_10_BUF]); ++ } ++#endif ++ ++ if (maycopy) ++ { ++ if (frame->buf[1] != NULL) ++ av_log(s, AV_LOG_INFO, "%s: *** Not a single buf frame: copying\n", __func__); ++ else ++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format %d: copying to %d\n", __func__, frame->format, expected_format); ++ ++ switch (frame->format) ++ { ++ case AV_PIX_FMT_YUV420P10: ++ return zc_420p10_to_sand128(s, frame); ++ ++ case AV_PIX_FMT_SAND64_10: ++ return zc_sand64_16_to_sand128(s, frame, 10); ++ ++ default: ++ return zc_copy(s, frame); ++ } ++ } ++ else ++ { ++ if (frame->buf[1] != NULL) ++ av_log(s, AV_LOG_WARNING, "%s: *** Not a single buf frame: buf[1] != NULL\n", __func__); ++ else ++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format: %d != %d\n", __func__, frame->format, expected_format); ++ return NULL; ++ } ++ } ++ ++ if (pic_gm_ptr(frame->buf[0]) == NULL) ++ { ++ if (maycopy) ++ { ++ av_log(s, AV_LOG_INFO, "%s: *** Not one of our buffers: copying\n", __func__); ++ return zc_copy(s, frame); ++ } ++ else ++ { ++ av_log(s, AV_LOG_WARNING, "%s: *** Not one of our buffers: NULL\n", __func__); ++ return NULL; ++ } ++ } ++ ++ return av_buffer_ref(frame->buf[0]); ++} ++ ++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? -1 : p->vc_handle; ++} ++ ++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? 0 : fr_ref->data - p->arm; ++} ++ ++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref) ++{ ++ return fr_ref == NULL ? 0 : fr_ref->size; ++} ++ ++ ++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? 0 : p->numbytes; ++} ++ ++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref) ++{ ++ if (fr_ref != NULL) ++ { ++ av_buffer_unref(&fr_ref); ++ } ++} ++ ++AVZcEnvPtr av_rpi_zc_env_alloc(void) ++{ ++ ZcEnv * const zc = av_mallocz(sizeof(ZcEnv)); ++ if (zc == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_rpi_zc_env_alloc: Context allocation failed\n"); ++ return NULL; ++ } ++ ++ zc_pool_init(&zc->pool); ++ return zc; ++} ++ ++void av_rpi_zc_env_free(AVZcEnvPtr zc) ++{ ++ if (zc != NULL) ++ { ++ zc_pool_destroy(&zc->pool); ; ++ av_free(zc); ++ } ++} ++ ++int av_rpi_zc_in_use(const struct AVCodecContext * const s) ++{ ++ return s->get_buffer2 == av_rpi_zc_get_buffer2; ++} ++ ++int av_rpi_zc_init(struct AVCodecContext * const s) ++{ ++ if (av_rpi_zc_in_use(s)) ++ { ++ ZcEnv * const zc = s->get_buffer_context; ++ ++zc->refcount; ++ } ++ else ++ { ++ ZcEnv *const zc = av_rpi_zc_env_alloc(); ++ if (zc == NULL) ++ { ++ return AVERROR(ENOMEM); ++ } ++ ++ zc->refcount = 1; ++ zc->old.get_buffer_context = s->get_buffer_context; ++ zc->old.get_buffer2 = s->get_buffer2; ++ zc->old.thread_safe_callbacks = s->thread_safe_callbacks; ++ ++ s->get_buffer_context = zc; ++ s->get_buffer2 = av_rpi_zc_get_buffer2; ++ s->thread_safe_callbacks = 1; ++ } ++ return 0; ++} ++ ++void av_rpi_zc_uninit(struct AVCodecContext * const s) ++{ ++ if (av_rpi_zc_in_use(s)) ++ { ++ ZcEnv * const zc = s->get_buffer_context; ++ if (--zc->refcount == 0) ++ { ++ s->get_buffer2 = zc->old.get_buffer2; ++ s->get_buffer_context = zc->old.get_buffer_context; ++ s->thread_safe_callbacks = zc->old.thread_safe_callbacks; ++ av_rpi_zc_env_free(zc); ++ } ++ } ++} ++ ++#endif // RPI ++ +diff --git a/libavcodec/rpi_zc.h b/libavcodec/rpi_zc.h +new file mode 100644 +index 0000000000..0e39b8e3b3 +--- /dev/null ++++ b/libavcodec/rpi_zc.h +@@ -0,0 +1,106 @@ ++#ifndef LIBAVCODEC_RPI_ZC_H ++#define LIBAVCODEC_RPI_ZC_H ++ ++// Zero-Copy frame code for RPi ++// RPi needs Y/U/V planes to be contiguous for display. By default ++// ffmpeg will allocate separated planes so a memcpy is needed before ++// display. This code provides a method a making ffmpeg allocate a single ++// bit of memory for the frame when can then be reference counted until ++// display has finished with it. ++ ++// Frame buffer number in which to stuff an 8-bit copy of a 16-bit frame ++// 0 disables ++// *** This option still in development ++// Only works if SAO active ++// Allocates buffers that are twice the required size ++#define RPI_ZC_SAND_8_IN_10_BUF 0 ++ ++struct AVBufferRef; ++struct AVFrame; ++struct AVCodecContext; ++enum AVPixelFormat; ++ ++// "Opaque" pointer to whatever we are using as a buffer reference ++typedef struct AVBufferRef * AVRpiZcRefPtr; ++ ++struct AVZcEnv; ++typedef struct AVZcEnv * AVZcEnvPtr; ++ ++typedef struct AVRpiZcFrameGeometry ++{ ++ unsigned int stride_y; // Luma stride (bytes) ++ unsigned int height_y; // Luma height (lines) ++ unsigned int stride_c; // Chroma stride (bytes) ++ unsigned int height_c; // Chroma stride (lines) ++ unsigned int planes_c; // Chroma plane count (U, V = 2, interleaved = 1) ++ unsigned int stripes; // Number of stripes (sand) ++ unsigned int bytes_per_pel; ++ int stripe_is_yc; // A single stripe is Y then C (false for tall sand) ++} AVRpiZcFrameGeometry; ++ ++ ++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( ++ const int format, ++ const unsigned int video_width, const unsigned int video_height); ++ ++// Replacement fn for avctx->get_buffer2 ++// Should be set before calling avcodec_decode_open2 ++// ++// N.B. in addition to to setting avctx->get_buffer2, avctx->refcounted_frames ++// must be set to 1 as otherwise the buffer info is killed before being returned ++// by avcodec_decode_video2. Note also that this means that the AVFrame that is ++// returned must be manually derefed with av_frame_unref. This should be done ++// after av_rpi_zc_ref has been called. ++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags); ++ ++// Generate a ZC reference to the buffer(s) in this frame ++// If the buffer doesn't appear to be one allocated by _get_buffer_2 ++// then the behaviour depends on maycopy: ++// If maycopy=0 then return NULL ++// If maycopy=1 && the src frame is in a form where we can easily copy ++// the data, then allocate a new buffer and copy the data into it ++// Otherwise return NULL ++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, ++ const struct AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy); ++ ++// Get the vc_handle from the frame ref ++// Returns -1 if ref doesn't look valid ++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref); ++// Get offset from the start of the memory referenced ++// by the vc_handle to valid data ++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref); ++// Length of buffer data ++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref); ++// Get the number of bytes allocated from the frame ref ++// Returns 0 if ref doesn't look valid ++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref); ++ ++// Unreference the buffer refed/allocated by _zc_ref ++// If fr_ref is NULL then this will NOP ++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref); ++ ++// Allocate an environment for the buffer pool used by the ZC code ++// This should be put in avctx->get_buffer_context so it can be found by ++// av_rpi_zc_get_buffer2 when it is called from ffmpeg ++AVZcEnvPtr av_rpi_zc_env_alloc(void); ++ ++// Allocate the environment used by the ZC code ++void av_rpi_zc_env_free(AVZcEnvPtr); ++ ++// Test to see if the context is using zc (checks get_buffer2) ++int av_rpi_zc_in_use(const struct AVCodecContext * const s); ++ ++// Init ZC into a context ++// There is nothing magic in this fn - it just packages setting ++// get_buffer2 & get_buffer_context ++int av_rpi_zc_init(struct AVCodecContext * const s); ++ ++// Free ZC from a context ++// There is nothing magic in this fn - it just packages unsetting ++// get_buffer2 & get_buffer_context ++void av_rpi_zc_uninit(struct AVCodecContext * const s); ++ ++ ++ ++#endif ++ +diff --git a/libavutil/buffer.c b/libavutil/buffer.c +index 9c5d530c7a..e07f947cdc 100644 +--- a/libavutil/buffer.c ++++ b/libavutil/buffer.c +@@ -368,3 +368,9 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) + + return ret; + } ++ ++// Return the opaque for the underlying frame (gives us a GPU_MEM_PTR_T) ++void *av_buffer_pool_opaque(AVBufferRef *ref) { ++ BufferPoolEntry *buf = av_buffer_get_opaque(ref); ++ return buf->opaque; ++} +diff --git a/libavutil/buffer.h b/libavutil/buffer.h +index fab745f853..d0271e50fc 100644 +--- a/libavutil/buffer.h ++++ b/libavutil/buffer.h +@@ -289,6 +289,9 @@ void av_buffer_pool_uninit(AVBufferPool **pool); + */ + AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); + ++// Return the opaque for the underlying frame ++void *av_buffer_pool_opaque(AVBufferRef *ref); ++ + /** + * @} + */ +diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c +index 8ed52751c1..5e2b5ec3bc 100644 +--- a/libavutil/pixdesc.c ++++ b/libavutil/pixdesc.c +@@ -1989,6 +1989,18 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { + .name = "cuda", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, ++ [AV_PIX_FMT_RPI] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, ++ [AV_PIX_FMT_RPI4_10] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, ++ [AV_PIX_FMT_RPI4_8] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, + [AV_PIX_FMT_AYUV64LE] = { + .name = "ayuv64le", + .nb_components = 4, +diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h +index 34a1531489..0a6ff1f482 100644 +--- a/libavutil/pixfmt.h ++++ b/libavutil/pixfmt.h +@@ -234,6 +234,11 @@ enum AVPixelFormat { + */ + AV_PIX_FMT_CUDA, + ++ /** ++ * HW acceleration through RPI. ++ */ ++ AV_PIX_FMT_RPI, ++ + 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 +@@ -334,6 +339,14 @@ enum AVPixelFormat { + */ + AV_PIX_FMT_OPENCL, + ++// RPI - not on ifdef so can be got at by calling progs ++ AV_PIX_FMT_SAND128, ///< 4:2:0 8-bit 128x*Y stripe, 64x*UV stripe, then next x stripe, mysterious padding ++ AV_PIX_FMT_SAND64_10, ///< 4:2:0 10-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding ++ AV_PIX_FMT_SAND64_16, ///< 4:2:0 16-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding ++ ++ AV_PIX_FMT_RPI4_8, ++ AV_PIX_FMT_RPI4_10, ++ + 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 + }; + +diff --git a/pi-util/conf_pi1.sh b/pi-util/conf_pi1.sh +new file mode 100644 +index 0000000000..ec25b81c31 +--- /dev/null ++++ b/pi-util/conf_pi1.sh +@@ -0,0 +1,31 @@ ++echo "Configure for Pi1" ++ ++RPI_TOOLROOT=`pwd`/../tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf ++RPI_OPT_VC=`pwd`/../firmware/opt/vc ++ ++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" ++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI=1" ++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" ++#RPI_KEEPS="-save-temps=obj" ++RPI_KEEPS="" ++ ++./configure --enable-cross-compile\ ++ --cpu=arm1176jzf-s\ ++ --arch=arm\ ++ --disable-neon\ ++ --target-os=linux\ ++ --disable-stripping\ ++ --enable-mmal\ ++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ ++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ ++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ ++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ ++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- ++ ++ ++# --enable-extra-warnings\ ++# --arch=armv71\ ++# --enable-shared\ ++ ++# gcc option for getting asm listing ++# -Wa,-ahls +diff --git a/pi-util/conf_pi2.sh b/pi-util/conf_pi2.sh +new file mode 100644 +index 0000000000..7ec0402ce8 +--- /dev/null ++++ b/pi-util/conf_pi2.sh +@@ -0,0 +1,34 @@ ++echo "Configure for Pi2/3" ++ ++RPI_TOOLROOT=/home/dom/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf ++RPI_OPT_VC=/opt/bcm-rootfs/opt/vc ++ ++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" ++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI_DISPLAY=1" ++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" ++#RPI_KEEPS="-save-temps=obj" ++RPI_KEEPS="" ++ ++./configure --enable-cross-compile\ ++ --arch=armv6t2\ ++ --cpu=cortex-a7\ ++ --target-os=linux\ ++ --disable-stripping\ ++ --disable-thumb\ ++ --enable-mmal\ ++ --enable-rpi\ ++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ ++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ ++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ ++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ ++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- \ ++ --prefix=$HOME/buster/home/pi/projects/fpga \ ++ --extra-libs="-ldl" ++ ++# --disable-decoders --enable-decoder=hevc --disable-hwaccels --enable-hwaccel=hevc_rpi --disable-encoders --enable-encoder=rawvideo --enable-muxer=rawvideo \ ++# --enable-extra-warnings\ ++# --arch=armv71\ ++# --enable-shared\ ++ ++# gcc option for getting asm listing ++# -Wa,-ahls From 67de71621041ab33fca4b69f5f0314d9c68f51ef Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Wed, 6 Mar 2019 14:24:36 +0100 Subject: [PATCH 16/23] brcmfmac_sdio-firmware-rpi: add patch to sync with rasbian buster The boardflags3 change in brcmfmac43455-sdio.txt is needed to get bluetooth working on RPi4. Replace this patch with a PKG_VERSION bump once the brcmfmac43455-sdio.txt file is publically available. Signed-off-by: Matthias Reichl --- ...re-rpi-001-sync-with-raspbian-buster.patch | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch diff --git a/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch b/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch new file mode 100644 index 0000000000..a3201b9d00 --- /dev/null +++ b/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch @@ -0,0 +1,21 @@ +diff -ru brcmfmac_sdio-firmware-rpi.orig/firmware/brcm/brcmfmac43455-sdio.txt brcmfmac_sdio-firmware-rpi/firmware/brcm/brcmfmac43455-sdio.txt +--- brcmfmac_sdio-firmware-rpi.orig/firmware/brcm/brcmfmac43455-sdio.txt 2019-01-28 20:44:58.000000000 +0100 ++++ brcmfmac_sdio-firmware-rpi/firmware/brcm/brcmfmac43455-sdio.txt 2019-06-11 13:09:30.388579306 +0200 +@@ -21,7 +21,7 @@ + # bit1 for btcoex + boardflags=0x00480201 + boardflags2=0x40800000 +-boardflags3=0x48200100 ++boardflags3=0x44200100 + phycal_tempdelta=15 + rxchain=1 + txchain=1 +@@ -91,7 +91,7 @@ + cbfilttype=1 + fdsslevel_ch11=6 + +-# Experimental Bluetooth coexistence parameters from Cypress ++# Improved Bluetooth coexistence parameters from Cypress + btc_mode=1 + btc_params8=0x4e20 + btc_params1=0x7530 From 4c7e6a19d2a55e9c0ca8e707116460a8a54b7e84 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Wed, 24 Apr 2019 00:02:52 +0200 Subject: [PATCH 17/23] bcmstat: add patch from milhouse Replace this patch with a PKG_VERSION bump once a newer version is publically available. Signed-off-by: Matthias Reichl --- .../bcmstat-001-add-patch-from-milhouse.patch | 400 ++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch diff --git a/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch b/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch new file mode 100644 index 0000000000..4ab97f6720 --- /dev/null +++ b/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch @@ -0,0 +1,400 @@ +From c13ba8541ba6701dc4a851ea0940884e2e6020f2 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Fri, 1 Mar 2019 15:58:44 +0000 +Subject: [PATCH 1/5] add rpi4 + +--- + bcmstat.sh | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index fa8ee7e..b90392e 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -44,7 +44,7 @@ else: + + GITHUB = "https://raw.github.com/MilhouseVH/bcmstat/master" + ANALYTICS = "http://goo.gl/edu1jG" +-VERSION = "0.5.1" ++VERSION = "0.5.2" + + VCGENCMD = None + VCDBGCMD = None +@@ -60,7 +60,7 @@ SYSINFO = {} + # NEW 23: will be 1 for the new scheme, 0 for the old scheme + # MEMSIZE 20: 0=256M 1=512M 2=1G + # MANUFACTURER 16: 0=SONY 1=EGOMAN 2=EMBEST 3=SONY JAPAN 4=EMBEST +-# PROCESSOR 12: 0=2835 1=2836 2=2837 ++# PROCESSOR 12: 0=2835 1=2836 2=2837, 3=2838 + # TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODELB 5=ALPHA 6=CM 8=Pi3 9=Pi0 10=CM3 12=Pi0W + # REV 00: 0=REV0 1=REV1 2=REV2 3=REV3 + +@@ -84,10 +84,10 @@ class RPIHardware(): + + # Note: Some of these memory sizes and processors are fictional and relate to unannounced products - logic would + # dictate such products may exist at some point in the future, but it's only guesswork. +- self.memsizes = ["256MB", "512MB", "1GB", "2GB", "4GB"] ++ self.memsizes = ["256MB", "512MB", "1GB", "2GB", "4GB", "8GB"] + self.manufacturers = ["Sony UK", "Egoman", "Embest", "Sony Japan", "Embest", "Stadium"] + self.processors = ["2835", "2836", "2837", "2838", "2839", "2840"] +- self.models = ["Model A", "Model B", "Model A+", "Model B+", "Pi2 Model B", "Alpha", "CM1", "Unknown", "Pi3", "Pi0", "CM3", "Unknown", "Pi0 W", "Pi3 Model B+"] ++ self.models = ["Model A", "Model B", "Model A+", "Model B+", "Pi2 Model B", "Alpha", "CM1", "Unknown", "Pi3", "Pi0", "CM3", "Unknown", "Pi0 W", "Pi3 Model B+", "Pi3 Model A+", "Unknown", "CM3+", "Pi4 Model B"] + self.pcbs = ["Unknown", "Pi3 Rev1.0", "Pi3 Rev1.2", "Pi2 2837 Rev1.1", "Pi2 2836", "Pi1 B+ Rev 1.1", "Pi0", "Pi1 B Rev2.0", "Pi2 (2837) Rev1.0", "Pi0 W", "Pi2 (2837) Rev1.2", "Pi3 B+"] + + self.set_rev_code(rev_code) +@@ -909,8 +909,8 @@ def ShowHeadings(display_flags, sysinfo): + HDR1 = "%s RX kB/s TX kB/s" % HDR1 + HDR2 = "%s ======= =======" % HDR2 + else: +- HDR1 = "%s RX B/s TX B/s" % HDR1 +- HDR2 = "%s ========== ==========" % HDR2 ++ HDR1 = "%s RX B/s TX B/s" % HDR1 ++ HDR2 = "%s =========== ===========" % HDR2 + + if display_flags["utilisation"]: + HDR1 = "%s %%user %%nice %%sys %%idle %%iowt %%irq %%s/irq %%total" % HDR1 +@@ -937,8 +937,12 @@ def ShowHeadings(display_flags, sysinfo): + HDR2 = "%s ===========" % HDR2 + + if display_flags["cpu_mem"]: +- HDR1 = "%s Mem Free / %%used" % HDR1 +- HDR2 = "%s ================" % HDR2 ++ if display_flags["human_readable"]: ++ HDR1 = "%s MemFreeMB / %%used" % HDR1 ++ HDR2 = "%s =================" % HDR2 ++ else: ++ HDR1 = "%s MemFreeKB / %%used" % HDR1 ++ HDR2 = "%s =================" % HDR2 + if display_flags["swap"]: + HDR1 = "%s(SwUse)" % HDR1 + HDR2 = "%s=======" % HDR2 +@@ -1025,8 +1029,8 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + else: + LINE = "%s %s %s" % \ + (LINE, +- colourise(network[0], "%10s", 0.5e6, 2.5e6, 5.0e6, True), +- colourise(network[1], "%10s", 0.5e6, 2.5e6, 5.0e6, True)) ++ colourise(network[0], "%11s", 0.5e6, 2.5e6, 5.0e6, True), ++ colourise(network[1], "%11s", 0.5e6, 2.5e6, 5.0e6, True)) + + if display_flags["utilisation"]: + LINE = "%s %s %s %s %s %s %s %s %s" % \ +@@ -1071,12 +1075,12 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + if display_flags["human_readable"]: + LINE = "%s %s / %s" % \ + (LINE, +- colourise(memory[1]/1024, "%5s MB", 60, 75, 85, True, compare=memory[2]), +- colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) ++ colourise(memory[1]/1024, "%9s", 60, 75, 85, True, compare=memory[2]), ++ colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) + else : +- LINE = "%s %s/%s" % \ ++ LINE = "%s %s / %s" % \ + (LINE, +- colourise(memory[1], "%7s kB", 60, 75, 85, True, compare=memory[2]), ++ colourise(memory[1], "%9s", 60, 75, 85, True, compare=memory[2]), + colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) + + # Swap memory +-- +2.14.1 + + +From 390cc573319fd918dc23ee78e4ab914b30965304 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Wed, 6 Mar 2019 11:44:40 +0000 +Subject: [PATCH 2/5] irqs: don't fail if missing + +--- + bcmstat.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index b90392e..3e13c97 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -452,7 +452,8 @@ def getIRQ(storage): + + irq = 0 + for i in grep("dwc", readfile("/proc/interrupts"), 1).split("\n"): +- irq += int(i) ++ if i: ++ irq += int(i) + + storage[1] = (time.time(), irq) + +-- +2.14.1 + + +From 28ffb2a403af013ad2408dd6cfad485f01a9240b Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Wed, 6 Mar 2019 12:29:29 +0000 +Subject: [PATCH 3/5] irqs: accumulate all of them + +--- + bcmstat.sh | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 3e13c97..1db3df4 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -447,13 +447,19 @@ def colourise(display, nformat, green, yellow, red, withcomma, compare=None, add + + return nformat % cnum + +-def getIRQ(storage): ++def getIRQ(storage, sysinfo): + storage[2] = storage[1] + ++ nproc = sysinfo["nproc"] + irq = 0 +- for i in grep("dwc", readfile("/proc/interrupts"), 1).split("\n"): +- if i: +- irq += int(i) ++ for line in grep(":", readfile("/proc/interrupts")).split("\n"): ++ fields = line.split(" ") ++ if fields[0] == "FIQ:": ++ continue ++ if fields[0] == "Err:": ++ break ++ for n in range(1, nproc + 1): ++ irq += int(fields[n]) + + storage[1] = (time.time(), irq) + +@@ -1600,7 +1606,7 @@ def main(args): + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + + getBCM283X(BCM, STATS_WITH_VOLTS) +- getIRQ(IRQ) ++ getIRQ(IRQ, sysinfo) + getNetwork(NET, INTERFACE) + + STATS_NETWORK = (NET[1][1] != "") +@@ -1655,7 +1661,7 @@ def main(args): + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + + getBCM283X(BCM, STATS_WITH_VOLTS) +- getIRQ(IRQ) ++ getIRQ(IRQ, sysinfo) + + if STATS_NETWORK: + getNetwork(NET, INTERFACE) +-- +2.14.1 + + +From 19097fd9d91dd69ce05fe10957dfb72a2c470fcb Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Fri, 26 Apr 2019 18:30:49 +0100 +Subject: [PATCH 4/5] pmic: measure temp with option t + +--- + bcmstat.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 58 insertions(+), 16 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 1db3df4..50fa11c 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -51,7 +51,8 @@ VCDBGCMD = None + GPU_ALLOCATED_R = None + GPU_ALLOCATED_M = None + SUDO = "" +-TMAX = 0.0 ++TCMAX = 0.0 ++TPMAX = 0.0 + LIMIT_TEMP = True + COLOUR = False + SYSINFO = {} +@@ -570,15 +571,27 @@ def getNetwork(storage, interface): + dTX = cTX - pTX + storage[0] = (dTime, [int(dRX/dTime), int(dTX/dTime), dRX, dTX]) + +-def getBCM283X(storage, STATS_WITH_VOLTS): +- global TMAX, LIMIT_TEMP ++def getBCM283X(storage, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP): ++ global TCMAX, LIMIT_TEMP, TPMAX + #Grab temp - ignore temps of 85C as this seems to be an occasional aberration in the reading + tCore = float(readfile("/sys/class/thermal/thermal_zone0/temp")) + tCore = 0 if tCore < 0 else tCore + if LIMIT_TEMP: +- TMAX = tCore if (tCore > TMAX and tCore < 85000) else TMAX ++ TCMAX = tCore if (tCore > TCMAX and tCore < 85000) else TCMAX + else: +- TMAX = tCore if tCore > TMAX else TMAX ++ TCMAX = tCore if tCore > TCMAX else TCMAX ++ ++ if STATS_WITH_PMIC_TEMP: ++ tPMIC = vcgencmd("measure_temp pmic", split=False) ++ if tPMIC.find("error") != -1: ++ tPMIC = None ++ tPMIC_MAX = None ++ else: ++ tPMIC = float(tPMIC.split("=")[1].replace("'C","")) ++ TPMAX = tPMIC if tPMIC > TPMAX else TPMAX ++ else: ++ tPMIC = None ++ tPMIC_MAX = None + + if STATS_WITH_VOLTS: + volts = vcgencmd("measure_volts core") +@@ -594,8 +607,8 @@ def getBCM283X(storage, STATS_WITH_VOLTS): + [int(vcgencmd("measure_clock arm")) + 500000, + int(vcgencmd("measure_clock core")) + 500000, + int(vcgencmd("measure_clock h264")) + 500000, +- tCore, +- TMAX, ++ tCore, TCMAX, ++ tPMIC, TPMAX, + volts]) + + if storage[2][0] != 0: +@@ -908,8 +921,15 @@ def ShowHeadings(display_flags, sysinfo): + HDR1 = "%s Vcore " % HDR1 + HDR2 = "%s ======" % HDR2 + +- HDR1 = "%s ARM Core H264 Core Temp (Max) IRQ/s" % HDR1 +- HDR2 = "%s ======= ======= ======= =============== ======" % HDR2 ++ HDR1 = "%s ARM Core H264 Core Temp (Max)" % HDR1 ++ HDR2 = "%s ======= ======= ======= ===============" % HDR2 ++ ++ if display_flags["temp_pmic"]: ++ HDR1 = "%s PMIC Temp (Max)" % HDR1 ++ HDR2 = "%s ===============" % HDR2 ++ ++ HDR1 = "%s IRQ/s" % HDR1 ++ HDR2 = "%s ======" % HDR2 + + if display_flags["network"]: + if display_flags["human_readable"]: +@@ -1016,15 +1036,26 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + fTM = "%5.2fC" if bcm2385[4] < 100000 else "%5.1fC" + + if display_flags["core_volts"]: +- LINE = "%s %s" % (LINE, bcm2385[5]) ++ LINE = "%s %s" % (LINE, bcm2385[7]) + +- LINE = "%s %s %s %s %s (%s) %s" % \ ++ LINE = "%s %s %s %s %s (%s)" % \ + (LINE, + colourise(bcm2385[0]/1000000, "%4dMhz", arm_min, None, arm_max, False), + colourise(bcm2385[1]/1000000, "%4dMhz",core_min, None, core_max, False), + colourise(bcm2385[2]/1000000, "%4dMhz", 0, h264_min, h264_max, False), + colourise(bcm2385[3]/1000, fTC, 50.0, 70.0, 80.0, False), +- colourise(bcm2385[4]/1000, fTM, 50.0, 70.0, 80.0, False), ++ colourise(bcm2385[4]/1000, fTM, 50.0, 70.0, 80.0, False)) ++ ++ if display_flags["temp_pmic"]: ++ fTC = "%5.2fC" if bcm2385[5] < 100000 else "%5.1fC" ++ fTM = "%5.2fC" if bcm2385[6] < 100000 else "%5.1fC" ++ LINE = "%s %s (%s)" % \ ++ (LINE, ++ colourise(bcm2385[5], fTC, 50.0, 70.0, 80.0, False), ++ colourise(bcm2385[6], fTM, 50.0, 70.0, 80.0, False)) ++ ++ LINE = "%s %s" % \ ++ (LINE, + colourise(irq[0], "%6s", 500, 2500, 5000, True)) + + if display_flags["network"]: +@@ -1145,7 +1176,7 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + printn("\n%s" % LINE) + + def ShowHelp(): +- print("Usage: %s [c|m] [d#] [H#] [i ] [k] [L|N|M] [y|Y] [x|X|r|R] [p|P] [T] [g|G] [f|F] [D][A] [s|S] [q|Q] [V|U|W|C] [Z] [h]" % os.path.basename(__file__)) ++ print("Usage: %s [c|m] [d#] [H#] [i ] [k] [L|N|M] [y|Y] [x|X|r|R] [p|P] [T] [t] [g|G] [f|F] [D][A] [s|S] [q|Q] [V|U|W|C] [Z] [h]" % os.path.basename(__file__)) + print() + print("c Colourise output (white: minimal load or usage, then ascending through green, amber and red).") + print("m Monochrome output (no colourise)") +@@ -1168,6 +1199,7 @@ def ShowHelp(): + print("D Show delta memory - negative: memory allocated, positive: memory freed") + print("A Show accumulated delta memory - negative: memory allocated, positive: memory freed") + print("T Maximum temperature is normally capped at 85C - use this option to disable temperature cap") ++ print("t Show PMIC temperature (if available, ignore if not)") + print() + print("V Check version") + print("U Update to latest version if an update is available") +@@ -1365,6 +1397,7 @@ def main(args): + STATS_THRESHOLD = False + STATS_THRESHOLD_CLEAR = False + STATS_WITH_VOLTS = False ++ STATS_WITH_PMIC_TEMP = False + STATS_CPU_MEM = False + STATS_UTILISATION = False + SIMPLE_UTILISATION = False +@@ -1495,6 +1528,9 @@ def main(args): + elif a1 == "T": + LIMIT_TEMP = False + ++ elif a1 == "t": ++ STATS_WITH_PMIC_TEMP = True ++ + elif a1 == "D": + STATS_DELTAS = True + +@@ -1605,8 +1641,12 @@ def main(args): + if STATS_THRESHOLD: + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + +- getBCM283X(BCM, STATS_WITH_VOLTS) ++ getBCM283X(BCM, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP) ++ if BCM[1][1][5] == None: ++ STATS_WITH_PMIC_TEMP = False ++ + getIRQ(IRQ, sysinfo) ++ + getNetwork(NET, INTERFACE) + + STATS_NETWORK = (NET[1][1] != "") +@@ -1642,7 +1682,8 @@ def main(args): + "gpu_malloc": STATS_GPU_M, + "swap": (SWAP_ENABLED and INCLUDE_SWAP), + "deltas": STATS_DELTAS, +- "accumulated": STATS_ACCUMULATED} ++ "accumulated": STATS_ACCUMULATED, ++ "temp_pmic": STATS_WITH_PMIC_TEMP} + + #Store peak values + PEAKVALUES = {"01#IRQ":0, "02#RX":0, "03#TX":0} +@@ -1660,7 +1701,8 @@ def main(args): + if STATS_THRESHOLD: + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + +- getBCM283X(BCM, STATS_WITH_VOLTS) ++ getBCM283X(BCM, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP) ++ + getIRQ(IRQ, sysinfo) + + if STATS_NETWORK: +-- +2.14.1 + + +From 987ad9c3dd102df5c7f027f8fb0cbc6d7e989d79 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Tue, 11 Jun 2019 02:31:07 +0100 +Subject: [PATCH 5/5] memory: treat SReclaimable as free mem + +--- + bcmstat.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 50fa11c..6a2a549 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -629,7 +629,7 @@ def getMemory(storage, include_swap): + + for line in readfile("/proc/meminfo").split("\n"): + field_groups = re.search("^(.*):[ ]*([0-9]*) .*$", line) +- if field_groups.group(1) in ["MemFree", "Buffers", "Cached"]: ++ if field_groups.group(1) in ["MemFree", "Buffers", "Cached", "SReclaimable"]: + MEMFREE += int(field_groups.group(2)) + elif field_groups.group(1) == "MemTotal": + MEMTOTAL = int(field_groups.group(2)) +-- +2.14.1 + From bdd90f6c23fac7767f996a713c46bb9cc219b1b0 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 24 Mar 2019 11:11:29 +0100 Subject: [PATCH 18/23] kodi: always depend on bcm2835-driver when building for RPi Signed-off-by: Matthias Reichl --- packages/mediacenter/kodi/package.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 60e6686f10..443565d2f7 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -31,6 +31,10 @@ case $KODI_VENDOR in ;; esac +if [ "$PROJECT" = "RPi" ]; then + PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" +fi + configure_package() { # Single threaded LTO is very slow so rely on Kodi for parallel LTO support if [ "$LTO_SUPPORT" = "yes" ] && ! build_with_debug; then From a8cffb11428d13d57190dc173bca87a206546040 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Wed, 24 Apr 2019 10:42:35 +0200 Subject: [PATCH 19/23] kodi (RPi4): use MMAL renderer with gbm Signed-off-by: Matthias Reichl --- .../patches/kodi/kodi-001-hack-in-mmal.patch | 5273 +++++++++++++++++ 1 file changed, 5273 insertions(+) create mode 100644 projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch new file mode 100644 index 0000000000..c46c5cdd47 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch @@ -0,0 +1,5273 @@ +From a67cb967b02cfb59c448d3c6a5a2bc1ecfe933a6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 24 Apr 2019 17:01:32 +0100 +Subject: [PATCH 01/14] hack: Nobble gles3 detection + +--- + cmake/modules/FindOpenGLES.cmake | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cmake/modules/FindOpenGLES.cmake b/cmake/modules/FindOpenGLES.cmake +index 0191d9e78c..c85a17928a 100644 +--- a/cmake/modules/FindOpenGLES.cmake ++++ b/cmake/modules/FindOpenGLES.cmake +@@ -42,7 +42,7 @@ find_path(OPENGLES3_INCLUDE_DIR GLES3/gl3.h + + if(OPENGLES_FOUND) + set(OPENGLES_LIBRARIES ${OPENGLES_gl_LIBRARY}) +- if(OPENGLES3_INCLUDE_DIR) ++ if(OPENGLES3x_INCLUDE_DIR) + set(OPENGLES_INCLUDE_DIRS ${OPENGLES_INCLUDE_DIR} ${OPENGLES3_INCLUDE_DIR}) + set(OPENGLES_DEFINITIONS -DHAS_GLES=3) + mark_as_advanced(OPENGLES_INCLUDE_DIR OPENGLES3_INCLUDE_DIR OPENGLES_gl_LIBRARY) +-- +2.20.1 + + +From 3cb1b595f36b6f6ba8befad52912ab245b91c0ab Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 4 Jun 2019 13:38:44 +0100 +Subject: [PATCH 02/14] ffmpeg: hevc: Add gpu based hevc optimisation + +--- + tools/depends/target/ffmpeg/Makefile | 6 +- + .../ffmpeg/pfcd_hevc_optimisations.patch | 4102 +++++++++++++++++ + 2 files changed, 4107 insertions(+), 1 deletion(-) + create mode 100644 tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch + +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index 47acb73bdd..0bb9eb375e 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -1,6 +1,7 @@ + include ../../Makefile.include + include FFMPEG-VERSION +-DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ++DEPS= ../../Makefile.include FFMPEG-VERSION Makefile \ ++ pfcd_hevc_optimisations.patch \ + + # set to "yes" to enable patching + # we don't apply patches until we move to a vanilla ffmpeg tarball +@@ -68,6 +69,8 @@ ifeq ($(Configuration), Release) + ffmpg_config += --disable-debug + endif + ++ffmpg_config += --enable-rpi ++ + all: .installed-$(PLATFORM) + + $(TARBALLS_LOCATION)/$(ARCHIVE): +@@ -77,6 +80,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) + rm -rf $(PLATFORM); mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig \&\& pkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure ++ cd $(PLATFORM); patch -p1 < ../pfcd_hevc_optimisations.patch + cd $(PLATFORM);\ + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ + ./configure $(ffmpg_config) +diff --git a/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch b/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch +new file mode 100644 +index 0000000000..fbdc27f516 +--- /dev/null ++++ b/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch +@@ -0,0 +1,4102 @@ ++diff --git a/configure b/configure ++index 172611bb4a..fa204fca71 100755 ++--- a/configure +++++ b/configure ++@@ -1782,6 +1782,8 @@ HWACCEL_LIBRARY_LIST=" ++ mmal ++ omx ++ opencl +++ rpi4_8 +++ rpi4_10 ++ " ++ ++ DOCUMENT_LIST=" ++@@ -1843,6 +1845,7 @@ SUBSYSTEM_LIST=" ++ pixelutils ++ network ++ rdft +++ rpi ++ " ++ ++ # COMPONENT_LIST needs to come last to ensure correct dependency checking ++@@ -2312,6 +2315,7 @@ CONFIG_EXTRA=" ++ rangecoder ++ riffdec ++ riffenc +++ rpi ++ rtpdec ++ rtpenc_chain ++ rv34dsp ++diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c ++index c0214c42d8..3f43b58cbb 100644 ++--- a/fftools/ffmpeg.c +++++ b/fftools/ffmpeg.c ++@@ -23,6 +23,11 @@ ++ * multimedia converter based on the FFmpeg libraries ++ */ ++ +++#ifdef RPI +++//#define RPI_DISPLAY +++#define RPI_DISPLAY_ALL 0 +++#endif +++ ++ #include "config.h" ++ #include ++ #include ++@@ -70,6 +75,24 @@ ++ # include "libavfilter/buffersrc.h" ++ # include "libavfilter/buffersink.h" ++ +++#ifdef RPI_DISPLAY +++#pragma GCC diagnostic push +++// Many many redundant decls in the header files +++#pragma GCC diagnostic ignored "-Wredundant-decls" +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#pragma GCC diagnostic pop +++#include "libavcodec/rpi_qpu.h" +++#include "libavcodec/rpi_zc.h" +++#endif +++ ++ #if HAVE_SYS_RESOURCE_H ++ #include ++ #include ++@@ -162,6 +185,247 @@ static int restore_tty; ++ static void free_input_threads(void); ++ #endif ++ +++#ifdef RPI_DISPLAY +++ +++#define NUM_BUFFERS 4 +++ +++ +++typedef struct rpi_display_env_s +++{ +++ MMAL_COMPONENT_T* display; +++ MMAL_COMPONENT_T* isp; +++ MMAL_PORT_T * port_in; // Input port of either isp or display depending on pipe setup +++ MMAL_CONNECTION_T * conn; +++ +++ MMAL_POOL_T *rpi_pool; +++ volatile int rpi_display_count; +++ enum AVPixelFormat avfmt; +++} rpi_display_env_t; +++ +++static rpi_display_env_t * rpi_display_env = NULL; +++ +++ +++static MMAL_POOL_T* display_alloc_pool(MMAL_PORT_T* port) +++{ +++ MMAL_POOL_T* pool; +++ mmal_port_parameter_set_boolean(port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); // Does this mark that the buffer contains a vc_handle? Would have expected a vc_image? +++ pool = mmal_port_pool_create(port, NUM_BUFFERS, 0); +++ assert(pool); +++ +++ return pool; +++} +++ +++static void display_cb_input(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { +++ rpi_display_env_t *const de = (rpi_display_env_t *)port->userdata; +++ av_rpi_zc_unref(buffer->user_data); +++ atomic_fetch_add(&de->rpi_display_count, -1); +++ mmal_buffer_header_release(buffer); +++} +++ +++static void display_cb_control(MMAL_PORT_T *port,MMAL_BUFFER_HEADER_T *buffer) { +++ mmal_buffer_header_release(buffer); +++} +++ +++#define DISPLAY_PORT_DEPTH 4 +++ +++static rpi_display_env_t * +++display_init(const enum AVPixelFormat req_fmt, size_t x, size_t y, size_t w, size_t h) +++{ +++ MMAL_STATUS_T err; +++ MMAL_DISPLAYREGION_T region = +++ { +++ .hdr = {MMAL_PARAMETER_DISPLAYREGION, sizeof(region)}, +++ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_DEST_RECT, +++ .layer = 2, +++ .fullscreen = 0, +++ .dest_rect = {x, y, w, h} +++ }; +++#if RPI_ZC_SAND_8_IN_10_BUF +++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10 || av_rpi_is_sand_format(req_fmt)) ? AV_PIX_FMT_SAND128 : req_fmt; +++#else +++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10) ? AV_PIX_FMT_SAND128 : req_fmt; +++#endif +++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(fmt, w, h); +++ rpi_display_env_t * de; +++ int isp_req = (fmt == AV_PIX_FMT_SAND64_10); +++ +++ bcm_host_init(); // Needs to be done by someone... +++ +++ if ((de = av_mallocz(sizeof(*de))) == NULL) { +++ return NULL; +++ } +++ +++ mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &de->display); +++ av_assert0(de->display); +++ de->port_in = de->display->input[0]; +++ +++ if (isp_req) +++ { +++ mmal_component_create("vc.ril.isp", &de->isp); +++ de->port_in = de->isp->input[0]; +++ } +++ +++ mmal_port_parameter_set(de->display->input[0], ®ion.hdr); +++ +++ { +++ MMAL_PORT_T * const port = de->port_in; +++ MMAL_ES_FORMAT_T* const format = port->format; +++ port->userdata = (struct MMAL_PORT_USERDATA_T *)de; +++ port->buffer_num = DISPLAY_PORT_DEPTH; +++ format->encoding = +++ fmt == AV_PIX_FMT_SAND128 ? MMAL_ENCODING_YUVUV128 : +++ fmt == AV_PIX_FMT_RPI4_8 ? MMAL_ENCODING_YUVUV128 : +++ fmt == AV_PIX_FMT_RPI4_10 ? MMAL_ENCODING_YUV10_COL : +++ fmt == AV_PIX_FMT_SAND64_10 ? MMAL_ENCODING_YUVUV64_16 : +++ MMAL_ENCODING_I420; +++ format->es->video.width = geo.stride_y; +++ format->es->video.height = (fmt == AV_PIX_FMT_SAND128 || +++ fmt == AV_PIX_FMT_RPI4_8 || +++ fmt == AV_PIX_FMT_RPI4_10 || +++ fmt == AV_PIX_FMT_SAND64_10) ? +++ (h + 15) & ~15 : geo.height_y; // Magic +++ format->es->video.crop.x = 0; +++ format->es->video.crop.y = 0; +++ format->es->video.crop.width = w; +++ format->es->video.crop.height = h; +++ mmal_port_format_commit(port); +++ } +++ +++ de->rpi_pool = display_alloc_pool(de->port_in); +++ mmal_port_enable(de->port_in,display_cb_input); +++ +++ if (isp_req) { +++ MMAL_PORT_T * const port_out = de->isp->output[0]; +++ mmal_log_dump_port(de->port_in); +++ mmal_format_copy(port_out->format, de->port_in->format); +++ if (fmt == AV_PIX_FMT_SAND64_10) { +++ if ((err = mmal_port_parameter_set_int32(de->port_in, MMAL_PARAMETER_CCM_SHIFT, 5)) != MMAL_SUCCESS || +++ (err = mmal_port_parameter_set_int32(port_out, MMAL_PARAMETER_OUTPUT_SHIFT, 1)) != MMAL_SUCCESS) +++ { +++ av_log(NULL, AV_LOG_WARNING, "Failed to set ISP output port shift\n"); +++ } +++ else +++ av_log(NULL, AV_LOG_WARNING, "Set ISP output port shift OK\n"); +++ +++ } +++ port_out->format->encoding = MMAL_ENCODING_I420; +++ mmal_log_dump_port(port_out); +++ if ((err = mmal_port_format_commit(port_out)) != MMAL_SUCCESS) +++ { +++ av_log(NULL, AV_LOG_ERROR, "Failed to set ISP output port format\n"); +++ goto fail; +++ } +++ if ((err = mmal_connection_create(&de->conn, port_out, de->display->input[0], MMAL_CONNECTION_FLAG_TUNNELLING)) != MMAL_SUCCESS) { +++ av_log(NULL, AV_LOG_ERROR, "Failed to create connection\n"); +++ goto fail; +++ } +++ if ((err = mmal_connection_enable(de->conn)) != MMAL_SUCCESS) { +++ av_log(NULL, AV_LOG_ERROR, "Failed to enable connection\n"); +++ goto fail; +++ } +++ mmal_port_enable(de->isp->control,display_cb_control); +++ mmal_component_enable(de->isp); +++ } +++ +++ mmal_component_enable(de->display); +++ mmal_port_enable(de->display->control,display_cb_control); +++ de->avfmt = fmt; +++ +++ printf("Allocated display %dx%d in %dx%d, fmt=%d\n", w, h, geo.stride_y, geo.height_y, fmt); +++ +++ return de; +++ +++fail: +++ // **** Free stuff +++ return NULL; +++} +++ +++static void display_frame(struct AVCodecContext * const s, rpi_display_env_t * const de, const AVFrame* const fr) +++{ +++ MMAL_BUFFER_HEADER_T* buf; +++ +++ if (de == NULL) +++ return; +++ +++ if (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { +++ av_log(s, AV_LOG_VERBOSE, "Frame dropped\n"); +++ return; +++ } +++ +++ buf = mmal_queue_get(de->rpi_pool->queue); +++ if (!buf) { +++ // Running too fast so drop the frame +++ printf("Q alloc failure\n"); +++ return; +++ } +++ assert(buf); +++ buf->cmd = 0; +++ buf->offset = 0; // Offset to valid data +++ buf->flags = 0; +++ { +++ const AVRpiZcRefPtr fr_buf = av_rpi_zc_ref(s, fr, de->avfmt, 1); +++ if (fr_buf == NULL) { +++ mmal_buffer_header_release(buf); +++ return; +++ } +++ +++ buf->user_data = fr_buf; +++ buf->data = (uint8_t *)av_rpi_zc_vc_handle(fr_buf); // Cast our handle to a pointer for mmal +++ buf->offset = av_rpi_zc_offset(fr_buf); +++ buf->length = av_rpi_zc_length(fr_buf); +++ buf->alloc_size = av_rpi_zc_numbytes(fr_buf); +++ atomic_fetch_add(&de->rpi_display_count, 1); +++ } +++#if RPI_DISPLAY_ALL +++ while (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { +++ usleep(5000); +++ } +++#endif +++ +++ if (mmal_port_send_buffer(de->port_in, buf) != MMAL_SUCCESS) +++ { +++ av_log(s, AV_LOG_ERROR, "mmal_port_send_buffer failed: depth=%d\n", de->rpi_display_count); +++ display_cb_input(de->port_in, buf); +++ } +++} +++ +++static void display_exit(rpi_display_env_t ** const pde) +++{ +++ rpi_display_env_t * const de = *pde; +++ *pde = NULL; +++ +++ if (de != NULL) { +++// sleep(120); +++ +++ if (de->port_in != NULL) { +++ mmal_port_disable(de->port_in); +++ } +++ +++ // The above disable should kick out all buffers - check that +++ if (atomic_load(&de->rpi_display_count) != 0) { +++ av_log(NULL, AV_LOG_WARNING, "Exiting with display count non-zero:%d\n", atomic_load(&de->rpi_display_count)); +++ } +++ +++ if (de->conn != NULL) { +++ mmal_connection_destroy(de->conn); +++ } +++ if (de->isp != NULL) { +++ mmal_component_destroy(de->isp); +++ } +++ if (de->display != NULL) { +++ mmal_component_destroy(de->display); +++ } +++ if (de->rpi_pool != NULL) { +++ mmal_port_pool_destroy(de->display->input[0], de->rpi_pool); +++ } +++ +++ av_free(de); +++ } +++} +++ +++#endif +++ +++ ++ /* sub2video hack: ++ Convert subtitles to video with alpha to insert them in filter graphs. ++ This is a temporary solution until libavfilter gets real subtitles support. ++@@ -583,6 +847,11 @@ static void ffmpeg_cleanup(int ret) ++ avformat_close_input(&input_files[i]->ctx); ++ av_freep(&input_files[i]); ++ } +++ +++#ifdef RPI_DISPLAY +++ display_exit(&rpi_display_env); +++#endif +++ ++ for (i = 0; i < nb_input_streams; i++) { ++ InputStream *ist = input_streams[i]; ++ ++@@ -594,7 +863,9 @@ static void ffmpeg_cleanup(int ret) ++ av_freep(&ist->filters); ++ av_freep(&ist->hwaccel_device); ++ av_freep(&ist->dts_buffer); ++- +++#ifdef RPI_DISPLAY +++ av_rpi_zc_uninit(ist->dec_ctx); +++#endif ++ avcodec_free_context(&ist->dec_ctx); ++ ++ av_freep(&input_streams[i]); ++@@ -625,6 +896,7 @@ static void ffmpeg_cleanup(int ret) ++ } ++ term_exit(); ++ ffmpeg_exited = 1; +++ ++ } ++ ++ void remove_avoptions(AVDictionary **a, AVDictionary *b) ++@@ -1060,6 +1332,15 @@ static void do_video_out(OutputFile *of, ++ if (ost->source_index >= 0) ++ ist = input_streams[ost->source_index]; ++ +++#ifdef RPI_DISPLAY +++ if (next_picture && ist != NULL) +++ { +++ if (rpi_display_env == NULL) +++ rpi_display_env = display_init(next_picture->format, 0, 0, next_picture->width, next_picture->height); +++ display_frame(ist->dec_ctx, rpi_display_env, next_picture); +++ } +++#endif +++ ++ frame_rate = av_buffersink_get_frame_rate(filter); ++ if (frame_rate.num > 0 && frame_rate.den > 0) ++ duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); ++@@ -1275,7 +1556,7 @@ static void do_video_out(OutputFile *of, ++ ++ ost->frames_encoded++; ++ ++- ret = avcodec_send_frame(enc, in_picture); +++ ret = 0;//avcodec_send_frame(enc, in_picture); ++ if (ret < 0) ++ goto error; ++ ++@@ -2891,6 +3172,12 @@ static int init_input_stream(int ist_index, char *error, int error_len) ++ ist->dec_ctx->opaque = ist; ++ ist->dec_ctx->get_format = get_format; ++ ist->dec_ctx->get_buffer2 = get_buffer; +++ +++#ifdef RPI_DISPLAY +++ // Overrides the above get_buffer2 +++ av_rpi_zc_init(ist->dec_ctx); +++#endif +++ ++ ist->dec_ctx->thread_safe_callbacks = 1; ++ ++ av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); ++diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h ++index d44b7a5c72..0c5fa38f1d 100644 ++--- a/fftools/ffmpeg.h +++++ b/fftools/ffmpeg.h ++@@ -62,6 +62,7 @@ enum HWAccelID { ++ HWACCEL_VIDEOTOOLBOX, ++ HWACCEL_QSV, ++ HWACCEL_CUVID, +++ HWACCEL_RPI, ++ }; ++ ++ typedef struct HWAccel { ++@@ -654,6 +655,7 @@ int ffmpeg_parse_options(int argc, char **argv); ++ int videotoolbox_init(AVCodecContext *s); ++ int qsv_init(AVCodecContext *s); ++ int cuvid_init(AVCodecContext *s); +++int rpi_init(AVCodecContext *s); ++ ++ HWDevice *hw_device_get_by_name(const char *name); ++ int hw_device_init_from_string(const char *arg, HWDevice **dev); ++diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c ++index d7a7eb0662..4ee87e742b 100644 ++--- a/fftools/ffmpeg_opt.c +++++ b/fftools/ffmpeg_opt.c ++@@ -74,6 +74,10 @@ const HWAccel hwaccels[] = { ++ #endif ++ #if CONFIG_CUVID ++ { "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA }, +++#endif +++#if CONFIG_RPI +++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_8 }, +++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_10 }, ++ #endif ++ { 0 }, ++ }; ++diff --git a/libavcodec/Makefile b/libavcodec/Makefile ++index 4b8ad121db..40ec4691ef 100644 ++--- a/libavcodec/Makefile +++++ b/libavcodec/Makefile ++@@ -6,6 +6,10 @@ HEADERS = ac3_parser.h \ ++ avcodec.h \ ++ avdct.h \ ++ avfft.h \ +++ rpi_qpu.h \ +++ rpi_mailbox.h \ +++ rpi_zc.h \ +++ rpi_ctrl_ffmpeg.h \ ++ d3d11va.h \ ++ dirac.h \ ++ dv_profile.h \ ++@@ -48,6 +52,10 @@ OBJS = ac3_parser.o \ ++ qsv_api.o \ ++ raw.o \ ++ utils.o \ +++ rpi_qpu.o \ +++ rpi_mailbox.o \ +++ rpi_zc.o \ +++ rpi_ctrl_ffmpeg.o \ ++ vorbis_parser.o \ ++ xiph.o \ ++ ++@@ -360,6 +368,7 @@ OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o ++ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ ++ hevc_cabac.o hevc_refs.o hevcpred.o \ ++ hevcdsp.o hevc_filter.o hevc_data.o +++OBJS-$(CONFIG_RPI) += rpi_hevc.o ++ OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o ++ OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o ++ OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o ++diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h ++index fb0c6fae70..798d0903eb 100644 ++--- a/libavcodec/avcodec.h +++++ b/libavcodec/avcodec.h ++@@ -3208,7 +3208,13 @@ typedef struct AVCodecContext { ++ #endif ++ ++ /** ++- * Audio only. The amount of padding (in samples) appended by the encoder to +++ * Opaque pointer for use by replacement get_buffer2 code +++ * +++ * @author jc (08/02/2016) +++ */ +++ void * get_buffer_context; +++ +++ /* Audio only. The amount of padding (in samples) appended by the encoder to ++ * the end of the audio. I.e. this number of decoded samples must be ++ * discarded by the caller from the end of the stream to get the original ++ * audio without any trailing padding. ++diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c ++index c8877626d2..da769116ec 100644 ++--- a/libavcodec/hevcdec.c +++++ b/libavcodec/hevcdec.c ++@@ -364,12 +364,17 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) ++ CONFIG_HEVC_NVDEC_HWACCEL + \ ++ CONFIG_HEVC_VAAPI_HWACCEL + \ ++ CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ +++ CONFIG_HEVC_RPI4_8_HWACCEL + \ +++ CONFIG_HEVC_RPI4_10_HWACCEL + \ ++ CONFIG_HEVC_VDPAU_HWACCEL) ++ enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; ++ ++ switch (sps->pix_fmt) { ++ case AV_PIX_FMT_YUV420P: ++ case AV_PIX_FMT_YUVJ420P: +++#if CONFIG_HEVC_RPI4_8_HWACCEL +++ *fmt++ = AV_PIX_FMT_RPI4_8; +++#endif ++ #if CONFIG_HEVC_DXVA2_HWACCEL ++ *fmt++ = AV_PIX_FMT_DXVA2_VLD; ++ #endif ++@@ -391,6 +396,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) ++ #endif ++ break; ++ case AV_PIX_FMT_YUV420P10: +++#if CONFIG_HEVC_RPI4_10_HWACCEL +++ *fmt++ = AV_PIX_FMT_RPI4_10; +++#endif ++ #if CONFIG_HEVC_DXVA2_HWACCEL ++ *fmt++ = AV_PIX_FMT_DXVA2_VLD; ++ #endif ++@@ -3556,6 +3564,12 @@ AVCodec ff_hevc_decoder = { ++ #endif ++ #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL ++ HWACCEL_VIDEOTOOLBOX(hevc), +++#endif +++#if CONFIG_HEVC_RPI4_8_HWACCEL +++ HWACCEL_RPI4_8(hevc), +++#endif +++#if CONFIG_HEVC_RPI4_10_HWACCEL +++ HWACCEL_RPI4_10(hevc), ++ #endif ++ NULL ++ }, ++diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h ++index 3aaa92571c..c6bc36b3e3 100644 ++--- a/libavcodec/hwaccel.h +++++ b/libavcodec/hwaccel.h ++@@ -80,5 +80,9 @@ typedef struct AVCodecHWConfigInternal { ++ HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD, NONE, ff_ ## codec ## _d3d11va_hwaccel) ++ #define HWACCEL_XVMC(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) +++#define HWACCEL_RPI4_8(codec) \ +++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_8, NONE, ff_ ## codec ## _rpi4_8_hwaccel) +++#define HWACCEL_RPI4_10(codec) \ +++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_10, NONE, ff_ ## codec ## _rpi4_10_hwaccel) ++ ++ #endif /* AVCODEC_HWACCEL_H */ ++diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h ++index 7d73da8676..01799f869a 100644 ++--- a/libavcodec/hwaccels.h +++++ b/libavcodec/hwaccels.h ++@@ -74,5 +74,7 @@ extern const AVHWAccel ff_wmv3_dxva2_hwaccel; ++ extern const AVHWAccel ff_wmv3_nvdec_hwaccel; ++ extern const AVHWAccel ff_wmv3_vaapi_hwaccel; ++ extern const AVHWAccel ff_wmv3_vdpau_hwaccel; +++extern const AVHWAccel ff_hevc_rpi4_8_hwaccel; +++extern const AVHWAccel ff_hevc_rpi4_10_hwaccel; ++ ++ #endif /* AVCODEC_HWACCELS_H */ ++diff --git a/libavcodec/rpi_ctrl_ffmpeg.c b/libavcodec/rpi_ctrl_ffmpeg.c ++new file mode 100644 ++index 0000000000..6d93adba03 ++--- /dev/null +++++ b/libavcodec/rpi_ctrl_ffmpeg.c ++@@ -0,0 +1,427 @@ +++#include +++#include +++#include +++#include +++ +++// How to access GPIO registers from C-code on the Raspberry-Pi +++// Example program +++// 15-January-2012 +++// Dom and Gert +++ +++// Access from ARM Running Linux +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#include +++#include +++#include +++#include +++#include "rpi_mailbox.h" +++#include "rpi_ctrl_ffmpeg.h" +++ +++#define av_assert0(x) assert(x) +++ +++// argon block doesn't see VC sdram alias bits +++#define MANGLE(x) ((x) &~0xc0000000) +++#ifdef AXI_BUFFERS +++#define AXI_MEM_SIZE (64*1024*1024) +++#else +++#define AXI_MEM_SIZE (64*1024*1024) +++#endif +++ +++#define PAGE_SIZE (4*1024) +++#define BLOCK_SIZE (0x10000) +++#define CACHED 0 +++#define VERBOSE 0 +++ +++static inline void __DMB2(void) {}//{ asm volatile ("dmb" ::: "memory"); } +++ +++ +++// GPU memory alloc fns (internal) +++typedef struct gpu_mem_ptr_s { +++ unsigned char *arm; // Pointer to memory mapped on ARM side +++ int vc_handle; // Videocore handle of relocatable memory +++ int vcsm_handle; // Handle for use by VCSM +++ unsigned int vc; // Address for use in GPU code +++ unsigned int numbytes; // Size of memory block +++} GPU_MEM_PTR_T; +++ +++typedef enum +++{ +++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, +++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, +++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 +++} rpi_cache_flush_mode_t; +++ +++// GPU_MEM_PTR_T alloc fns +++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = (numbytes + 255) & ~255; // Round up +++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++ printf("***** %s, %d\n", __func__, numbytes); +++ +++ return 0; +++} +++ +++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = numbytes; +++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++ printf("***** %s, %d\n", __func__, numbytes); +++ return 0; +++} +++ +++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { +++ mbox_mem_unlock(mb, p->vc_handle); +++ vcsm_unlock_ptr(p->arm); +++ vcsm_free(p->vcsm_handle); +++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again +++ printf("***** %s\n", __func__); +++} +++ +++static void gpu_clean_invalidate(GPU_MEM_PTR_T * const p, int mode) { +++ struct vcsm_user_clean_invalid_s iocache = {}; +++ iocache.s[0].handle = p->vcsm_handle; +++ iocache.s[0].cmd = mode; +++ iocache.s[0].addr = (int) p->arm; +++ iocache.s[0].size = p->numbytes; +++ vcsm_clean_invalid( &iocache ); +++ printf("***** %s mode:%d\n", __func__, mode); +++} +++ +++// +++// Set up a memory regions to access periperhals +++// +++static void *setup_io(const char *dev, unsigned long base) +++{ +++ void *gpio_map; +++ int mem_fd; +++ +++ /* open /dev/mem */ +++ if ((mem_fd = open(dev, O_RDWR|O_SYNC) ) < 0) { +++ printf("can't open %s\n", dev); +++ exit (-1); +++ } +++ // Now map it +++ gpio_map = (unsigned char *)mmap( +++ NULL, +++ BLOCK_SIZE, +++ PROT_READ|PROT_WRITE, +++ MAP_SHARED, +++ mem_fd, +++ base +++ ); +++ printf("%s: %08lx -> %p (fd:%d)\n", __FUNCTION__, base, gpio_map, mem_fd); +++ +++ if (gpio_map == MAP_FAILED) { +++ printf("mmap error %p\n", gpio_map); +++ //exit (-1); +++ } +++ +++ return gpio_map; +++} // setup_io +++ +++static void release_io(void *gpio_map) +++{ +++ int s = munmap(gpio_map, BLOCK_SIZE); +++ assert(s == 0); +++} +++ +++struct RPI_DEBUG { +++ FILE *fp_reg; +++ FILE *fp_bin; +++ int mbox; +++ GPU_MEM_PTR_T axi; +++ void *read_buf; +++ int32_t read_buf_size, read_buf_used; +++ volatile unsigned int *apb; +++ volatile unsigned int *interrupt; +++ //volatile unsigned int *sdram; +++}; +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++void rpi_apb_write_addr(void *id, uint16_t addr, uint32_t data) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "P %x %08x\n", addr, data); +++ __DMB2(); +++ rpi->apb[addr>>2] = data + (MANGLE(rpi->axi.vc)>>6); +++} +++ +++uint64_t rpi_axi_get_addr(void *id) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ return (uint64_t)MANGLE(rpi->axi.vc); +++} +++ +++void rpi_apb_write(void *id, uint16_t addr, uint32_t data) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "W %x %08x\n", addr, data); +++ __DMB2(); +++ rpi->apb[addr>>2] = data; +++} +++ +++uint32_t rpi_apb_read(void *id, uint16_t addr) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ uint32_t v = rpi->apb[addr>>2]; +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); +++ return v; +++} +++ +++void rpi_apb_read_drop(void *id, uint16_t addr) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ uint32_t v = rpi->apb[addr>>2]; +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); +++} +++ +++void rpi_axi_write(void *id, uint64_t addr, uint32_t size, void *buf) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "L %08" PRIx64 " %08x\n", addr, size); +++ assert(addr + size <= AXI_MEM_SIZE); +++ __DMB2(); +++ memcpy(rpi->axi.arm + addr, buf, size); +++} +++ +++void rpi_axi_read_alloc(void *id, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(rpi->read_buf == NULL); +++ rpi->read_buf = malloc(size); +++ rpi->read_buf_size = size; +++ rpi->read_buf_used = 0; +++} +++ +++void rpi_axi_read_tx(void *id, uint64_t addr, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(rpi->read_buf_used + size <= rpi->read_buf_size); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "S %08" PRIx64 " %08x\n", addr, size); +++ assert(addr + size <= AXI_MEM_SIZE); +++ __DMB2(); +++ memcpy((char *)rpi->read_buf + rpi->read_buf_used, rpi->axi.arm + addr, size); +++ rpi->read_buf_used += size; +++} +++ +++void rpi_axi_read_rx(void *id, uint32_t size, void *buf) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(size == rpi->read_buf_used); +++ fprintf(rpi->fp_reg, "Z " PRIx64 " %08x\n", size); +++ memcpy(buf, rpi->read_buf, size); +++ free(rpi->read_buf); +++ rpi->read_buf = NULL; +++ rpi->read_buf_size = 0; +++ rpi->read_buf_used = 0; +++} +++ +++static int getthreadnum(unsigned pid) +++{ +++ static unsigned pids[8]; +++ int i; +++ for (i = 0; i < 8; i++) +++ { +++ if (pids[i] == 0) +++ pids[i] = pid; +++ if (pids[i] == pid) +++ return i; +++ } +++ return -1; +++} +++ +++#define _NOP() //do { __asm__ __volatile__ ("nop"); } while (0) +++ +++static void yield(void) +++{ +++ int i; +++ for (i=0; i<0; i++) +++ _NOP(); +++ usleep(1000); +++} +++ +++ +++void rpi_wait_interrupt(void *id, int phase) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ static struct timespec tfirst={0,0}; +++ static __thread struct timespec tstart={0,0}; +++ struct timespec tend={0,0}; +++ unsigned pid = (unsigned)pthread_self(); +++ clock_gettime(CLOCK_MONOTONIC, &tend); +++ if (tstart.tv_sec == 0 && tstart.tv_nsec == 0) +++ tstart = tend; +++ if (tfirst.tv_sec == 0 && tfirst.tv_nsec == 0) +++ { +++ /*printf("%s: Resetting sdram stats\n", __FUNCTION__); +++ rpi->sdram[0x30/4] = 0;*/ +++ tfirst = tend; +++ } +++ if (VERBOSE) +++ printf("%08llu: %s: IN thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, +++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); +++ /*enum {IDL=0x30/4, RTC=0x34/4, WTC=0x38/4, RDC=0x3c/4, WDC=0x40/4, RAC=0x44/4, CYC=0x48/4, CMD=0x4c/4, DAT=0x50/4, RDCMD=0x78/4, RDSUB=0x7c/4, WRCMD=0x80/4, WRSUB=0x84/4, MWRCMD=0x88/4, MWRSUB=0x8c/4,}; +++ printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", +++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], +++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]); +++ rpi->sdram[0x30/4] = 0;*/ +++ +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "I %d\n", phase); +++ __DMB2(); +++#if 0 +++ assert(phase == 1 || phase == 2); +++ for (;;) { +++ if (phase==1 && rpi->apb[0x74>>2]==rpi->apb[0x70>>2]) break; +++ else if (phase==2 && (rpi->apb[0x8028/*STATUS2*/>>2]&1)==0) break; +++ } +++ fprintf(rpi->fp_reg, "I %d done\n", phase); +++#else +++ #define ARG_IC_ICTRL_ACTIVE1_INT_SET 0x00000001 +++ #define ARG_IC_ICTRL_ACTIVE1_EDGE_SET 0x00000002 +++ #define ARG_IC_ICTRL_ACTIVE1_EN_SET 0x00000004 +++ #define ARG_IC_ICTRL_ACTIVE1_STATUS_SET 0x00000008 +++ #define ARG_IC_ICTRL_ACTIVE2_INT_SET 0x00000010 +++ #define ARG_IC_ICTRL_ACTIVE2_EDGE_SET 0x00000020 +++ #define ARG_IC_ICTRL_ACTIVE2_EN_SET 0x00000040 +++ #define ARG_IC_ICTRL_ACTIVE2_STATUS_SET 0x00000080 +++ //if (rpi->interrupt[0] &~ (ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE1_STATUS_SET|ARG_IC_ICTRL_ACTIVE2_STATUS_SET)) +++ //fprintf(rpi->fp_reg, "I %d %x in\n", phase, rpi->interrupt[0]); +++ +++ if (phase == 1) { +++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE1_INT_SET)) +++ yield(); +++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE2_INT_SET; //ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; +++ } else if (phase == 2) { +++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE2_INT_SET)) +++ yield(); +++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE1_INT_SET; //ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; +++ } else assert(0); +++#endif +++ //fprintf(rpi->fp_reg, "I %d %x out\n", phase, rpi->interrupt[0]); +++ if (phase == 2) +++ { +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "YBASE:%08x CBASE:%08x\n", rpi->apb[0x8018>>2]*64, rpi->apb[0x8020>>2]*64); +++ } +++ clock_gettime(CLOCK_MONOTONIC, &tend); +++ +++ if (VERBOSE) +++ printf("%08llu: %s: OUT thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, +++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); +++ /*printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", +++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], +++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]);*/ +++ +++ tstart = tend; +++} +++ +++ +++void rpi_apb_dump_regs(void *id, uint16_t addr, int num) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ int i; +++ __DMB2(); +++ if (VERBOSE) +++ for (i=0; ifp_reg, "%08x: ", 0x7eb00000 + addr + 4*i); +++ fprintf(rpi->fp_reg, "%08x", rpi->apb[(addr>>2)+i]); +++ if ((i%4)==3 || i+1 == num) +++ fprintf(rpi->fp_reg, "\n"); +++ else +++ fprintf(rpi->fp_reg, " "); +++ } +++} +++ +++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ int i; +++ __DMB2(); +++ if (VERBOSE) +++ for (i=0; i>2; i++) +++ { +++ if ((i%4)==0) +++ fprintf(rpi->fp_reg, "%08x: ", MANGLE(rpi->axi.vc) + (uint32_t)addr + 4*i); +++ fprintf(rpi->fp_reg, "%08x", ((uint32_t*)rpi->axi.arm)[(addr>>2)+i]); +++ if ((i%4)==3 || i+1 == size>>2) +++ fprintf(rpi->fp_reg, "\n"); +++ else +++ fprintf(rpi->fp_reg, " "); +++ } +++} +++ +++void rpi_axi_flush(void *id, int mode) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (CACHED) +++ { +++ gpu_clean_invalidate(&rpi->axi, mode); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++const char * rpi_ctrl_ffmpeg_init(const char *hwaccel_device, void **id) { +++ struct RPI_DEBUG *rpi = calloc(1, sizeof(struct RPI_DEBUG)); +++ (void) hwaccel_device; +++ printf("%s\n id=%p\n", __FUNCTION__, rpi); +++ +++ if (!rpi) return "out of memory"; +++ +++ bcm_host_init(); +++ vcsm_init(); +++ rpi->apb = setup_io("/dev/argon-hevcmem", 0); +++ rpi->interrupt = setup_io("/dev/argon-intcmem", 0); +++ //rpi->sdram = setup_io(0xfe001000); +++ +++ rpi->fp_bin = stderr; +++ rpi->fp_reg = stderr; +++ +++ rpi->mbox = mbox_open(); +++ if ((CACHED ? gpu_malloc_cached_internal:gpu_malloc_uncached_internal)(rpi->mbox, AXI_MEM_SIZE, &rpi->axi) != 0) +++ return "out of memory"; +++ +++ fprintf(rpi->fp_reg, "A 100000000 apb:%p axi.arm:%p axi.vc:%08x\n", rpi->apb, rpi->axi.arm, MANGLE(rpi->axi.vc)); +++ *id = rpi; +++ return 0; +++} +++ +++void rpi_ctrl_ffmpeg_free(void *id) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ printf("%s id=%p\n", __FUNCTION__, rpi); +++ release_io(rpi->apb); +++ release_io(rpi->interrupt); +++ gpu_free_internal(rpi->mbox, &rpi->axi); +++ printf("%s freed axi mem\n", __FUNCTION__); +++ mbox_close(rpi->mbox); +++ printf("%s closed mbox\n", __FUNCTION__); +++ free(rpi); +++ printf("%s freed rpi\n", __FUNCTION__); +++ vcsm_exit(); +++ bcm_host_deinit(); +++} ++diff --git a/libavcodec/rpi_ctrl_ffmpeg.h b/libavcodec/rpi_ctrl_ffmpeg.h ++new file mode 100644 ++index 0000000000..6a1d95f195 ++--- /dev/null +++++ b/libavcodec/rpi_ctrl_ffmpeg.h ++@@ -0,0 +1,29 @@ +++// rpi_ctrl_ffmpeg.h +++// +++// This file contains prototypes for the functions used to control the socket +++// interface when using ffmpeg. +++// +++ +++#ifndef __CTRL_FFMPEG_H__ +++#define __CTRL_FFMPEG_H__ +++ +++#include +++ +++const char *rpi_ctrl_ffmpeg_init (const char *hwaccel_device, void **id); +++void rpi_apb_write_addr (void *id, uint16_t addr, uint32_t data); +++void rpi_apb_write (void *id, uint16_t addr, uint32_t data); +++uint32_t rpi_apb_read (void *id, uint16_t addr); +++void rpi_apb_read_drop (void *id, uint16_t addr); +++void rpi_axi_write (void *id, uint64_t addr, uint32_t size, void *buf); +++void rpi_axi_read (void *id, uint64_t addr, uint32_t size, void *buf); +++void rpi_axi_read_alloc (void *id, uint32_t size); +++void rpi_axi_read_tx (void *id, uint64_t addr, uint32_t size); +++void rpi_axi_read_rx (void *id, uint32_t size, void *buf); +++void rpi_wait_interrupt (void *id, int phase); +++void rpi_ctrl_ffmpeg_free (void *id); +++uint64_t rpi_axi_get_addr (void *id); +++void rpi_apb_dump_regs(void *id, uint16_t addr, int num); +++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size); +++void rpi_axi_flush(void *id, int mode); +++ +++#endif // __CTRL_FILES_H__ ++diff --git a/libavcodec/rpi_hevc.c b/libavcodec/rpi_hevc.c ++new file mode 100644 ++index 0000000000..a000077f33 ++--- /dev/null +++++ b/libavcodec/rpi_hevc.c ++@@ -0,0 +1,1065 @@ +++// FFMPEG HEVC decoder hardware accelerator +++// Andrew Holme, Argon Design Ltd +++// Copyright (c) June 2017 Raspberry Pi Ltd +++ +++#include +++#include +++ +++#include "fftools/ffmpeg.h" +++#include "libavutil/avassert.h" +++#include "libavutil/imgutils.h" +++#include "avcodec.h" +++#include "hwaccel.h" +++ +++#include "rpi_hevc.h" +++#include "rpi_zc.h" +++#include "rpi_qpu.h" +++ +++#include "rpi_ctrl_ffmpeg.h" +++////////////////////////////////////////////////////////////////////////////// +++ +++// Array of constants for scaling factors +++static const uint32_t scaling_factor_offsets[4][6] = { +++ // MID0 MID1 MID2 MID3 MID4 MID5 +++ {0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050}, // SID0 (4x4) +++ {0x0060, 0x00A0, 0x00E0, 0x0120, 0x0160, 0x01A0}, // SID1 (8x8) +++ {0x01E0, 0x02E0, 0x03E0, 0x04E0, 0x05E0, 0x06E0}, // SID2 (16x16) +++ {0x07E0, 0, 0, 0x0BE0, 0, 0}}; // SID3 (32x32) +++ +++// ffmpeg places SID3,MID1 where matrixID 3 normally is +++ +++////////////////////////////////////////////////////////////////////////////// +++// Scaling factors +++ +++static void expand_scaling_list( +++ RPI_T *rpi, +++ const ScalingList *scaling_list, // scaling list structure from ffmpeg +++ uint8_t sizeID, uint8_t matrixID) +++{ +++ uint8_t x, y, i, blkSize = 4<>1)<<3) + (x>>1); break; +++ case 3: i = ((y>>2)<<3) + (x>>2); +++ } +++ rpi->scaling_factors[index] = scaling_list->sl[sizeID][matrixID][i]; +++ } +++ } +++ if (sizeID>1) +++ rpi->scaling_factors[index_offset] = +++ scaling_list->sl_dc[sizeID-2][matrixID]; +++} +++ +++static void populate_scaling_factors(RPI_T *rpi, HEVCContext *s) { +++ const ScalingList *sl = +++ s->ps.pps->scaling_list_data_present_flag ? &s->ps.pps->scaling_list +++ : &s->ps.sps->scaling_list; +++ int sid, mid; +++ for (sid=0; sid<3; sid++) +++ for (mid=0; mid<6; mid++) +++ expand_scaling_list(rpi, sl, sid, mid); +++ +++ // second scaling matrix for 32x32 is at matrixID 3 not 1 in ffmpeg +++ expand_scaling_list(rpi, sl, 3, 0); +++ expand_scaling_list(rpi, sl, 3, 3); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Probabilities +++ +++static void populate_prob_tables(RPI_T *rpi, HEVCContext *s) { +++ struct RPI_PROB *dst = &rpi->probabilities; +++ struct FFM_PROB *src = (struct FFM_PROB *) s->HEVClc->cabac_state; +++ #define PROB_CPSZ(to, from, sz) memcpy(dst->to, src->from, sz) +++ #define PROB_COPY(to, from) memcpy(dst->to, src->from, sizeof(dst->to)) +++ memset(dst, 0, sizeof(*dst)); +++ PROB_COPY(SAO_MERGE_FLAG , sao_merge_flag ); +++ PROB_COPY(SAO_TYPE_IDX , sao_type_idx ); +++ PROB_COPY(SPLIT_FLAG , split_coding_unit_flag ); +++ PROB_COPY(CU_SKIP_FLAG , skip_flag ); +++ PROB_COPY(CU_TRANSQUANT_BYPASS_FLAG, cu_transquant_bypass_flag ); +++ PROB_COPY(PRED_MODE , pred_mode_flag ); +++ PROB_COPY(PART_SIZE , part_mode ); +++ PROB_COPY(INTRA_PRED_MODE , prev_intra_luma_pred_flag ); +++ PROB_COPY(CHROMA_PRED_MODE , intra_chroma_pred_mode ); +++ PROB_COPY(MERGE_FLAG_EXT , merge_flag ); +++ PROB_COPY(MERGE_IDX_EXT , merge_idx ); +++ PROB_COPY(INTER_DIR , inter_pred_idc ); +++ PROB_COPY(REF_PIC , ref_idx_l0 ); +++ PROB_COPY(MVP_IDX , mvp_lx_flag ); +++ PROB_CPSZ(MVD+0 , abs_mvd_greater0_flag+0 , 1); // ABS_MVD_GREATER0_FLAG[1] not used +++ PROB_CPSZ(MVD+1 , abs_mvd_greater1_flag+1 , 1); // ABS_MVD_GREATER1_FLAG[0] not used +++ PROB_COPY(QT_ROOT_CBF , no_residual_data_flag ); +++ PROB_COPY(TRANS_SUBDIV_FLAG , split_transform_flag ); +++ PROB_CPSZ(QT_CBF , cbf_luma , 2); +++ PROB_CPSZ(QT_CBF+2 , cbf_cb_cr , 4); +++ PROB_COPY(DQP , cu_qp_delta ); +++ PROB_COPY(ONE_FLAG , coeff_abs_level_greater1_flag ); +++ PROB_COPY(LASTX , last_significant_coeff_x_prefix); +++ PROB_COPY(LASTY , last_significant_coeff_y_prefix); +++ PROB_COPY(SIG_CG_FLAG , significant_coeff_group_flag ); +++ PROB_COPY(ABS_FLAG , coeff_abs_level_greater2_flag ); +++ PROB_COPY(TRANSFORMSKIP_FLAG , transform_skip_flag ); +++ PROB_CPSZ(SIG_FLAG , significant_coeff_flag , 42); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Read YUV data from socket server +++ +++static int bytes_per_line(const HEVCSPS *sps, int jump, int x) { +++ int width = FFMIN(jump, sps->width - x); +++ return sps->bit_depth>8? (width>48? 128:64) +++ : (width>64? 128:64); +++} +++ +++static void read_rect(RPI_T *rpi, char *buf, int addr64, int height, int bytes_per_line) { +++ rpi->axi_read_alloc(rpi->id, bytes_per_line*height); +++ if (bytes_per_line==128) +++ rpi->axi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 128*height); +++ else { +++ int y; +++ for (y=0; yaxi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 64); +++ } +++ rpi->axi_read_rx(rpi->id, bytes_per_line*height, buf); +++} +++ +++#ifdef AXI_BUFFERS +++////////////////////////////////////////////////////////////////////////////// +++// Copy YUV output data to FFMPEG frame buffer +++ +++static void copy_luma(char *buf, int bpl, int height, int x, uint8_t *data, int linesize) { +++ int y; +++ for (y=0; y> 0)&0x3ff; if(++j==linesize/2) break; +++ dst[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; +++ dst[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; +++ } +++ } +++} +++ +++static void copy_chroma10(char *buf, int bpl, int height, int x, uint8_t *u8, uint8_t *v8, int linesize) { +++ int i, j, y; +++ for (y=0; y> 0)&0x3ff; +++ v16[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; +++ u16[j] = (src[i]>>20)&0x3ff; i++; +++ v16[j] = (src[i]>> 0)&0x3ff; if(++j==linesize/2) break; +++ u16[j] = (src[i]>>10)&0x3ff; +++ v16[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; +++ } +++ } +++} +++#endif +++ +++////////////////////////////////////////////////////////////////////////////// +++// Phase 1 command and bit FIFOs +++ +++static int p1_apb_write(RPI_T *rpi, uint16_t addr, uint32_t data) { +++ if (rpi->cmd_len==rpi->cmd_max) +++ av_assert0(rpi->cmd_fifo = realloc(rpi->cmd_fifo, (rpi->cmd_max*=2)*sizeof(struct RPI_CMD))); +++ rpi->cmd_fifo[rpi->cmd_len].addr = addr; +++ rpi->cmd_fifo[rpi->cmd_len].data = data; +++ return rpi->cmd_len++; +++} +++ +++static void p1_axi_write(RPI_T *rpi, uint32_t len, const void *ptr, int cmd_idx) { +++ if (rpi->bit_len==rpi->bit_max) +++ av_assert0(rpi->bit_fifo = realloc(rpi->bit_fifo, (rpi->bit_max*=2)*sizeof(struct RPI_BIT))); +++ rpi->bit_fifo[rpi->bit_len].cmd = cmd_idx; +++ rpi->bit_fifo[rpi->bit_len].ptr = ptr; +++ rpi->bit_fifo[rpi->bit_len].len = len; +++ rpi->bit_len++; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Write probability and scaling factor memories +++ +++static void WriteProb(RPI_T *rpi) { +++ int i; +++ uint8_t *p = (uint8_t *) &rpi->probabilities; +++ for (i=0; iscaling_factors; +++ for (i=0; i= bd[i]; i++); // bd[] has num+1 elements; bd[0]=0; see hevc_ps.c +++ return i-1; +++} +++ +++static int ctb_to_slice_w_h (unsigned int ctb, int ctb_size, int width, unsigned int *bd, int num) { +++ if (ctb < bd[num-1]) return ctb_size; +++ else if (width % ctb_size) return width % ctb_size; +++ else return ctb_size; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void alloc_picture_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ const HEVCSPS *sps = s->ps.sps; +++ int CtbSizeY = 1<log2_ctb_size; +++ int x64 = AXI_BASE64; +++ +++ rpi->PicWidthInCtbsY = (sps->width + CtbSizeY - 1) / CtbSizeY; //7-15 +++ rpi->PicHeightInCtbsY = (sps->height + CtbSizeY - 1) / CtbSizeY; //7-17 +++#ifdef AXI_BUFFERS +++ rpi->lumabytes64 = ((sps->height+64) * ((sps->width+95)/96) * 2); +++ rpi->framebytes64 = ((rpi->lumabytes64 * 3)/2); +++ rpi->lumastride64 = ((sps->height+64) * 128) / 64; +++ rpi->chromastride64 = (((sps->height+64) * 128 ) / 2) / 64; +++ +++ x64 += 17 * rpi->framebytes64; +++#endif +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ // 128 bits = 16 bytes per MV, one for every 16*16 +++ int collocatedStride64 = (rpi->PicWidthInCtbsY * (CtbSizeY/16) * 16 + 63)>>6; +++ rpi->mvframebytes64 = rpi->PicHeightInCtbsY * (CtbSizeY/16) * collocatedStride64; +++ rpi->mvstorage64 = x64; +++ x64 += rpi->mvframebytes64 * 17; // Leave space for 17 reference pictures +++ rpi->colstride64 = collocatedStride64; +++ rpi->mvstride64 = collocatedStride64; +++ } +++ +++ rpi->pubase64[0] = x64; +++} +++ +++static int alloc_stream_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ int stride64, x64 = rpi->pubase64[0]; +++ +++ stride64 = 1 + (rpi->max_pu_msgs*2*rpi->PicWidthInCtbsY)/64; +++ rpi->pubase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; +++ rpi->pustep64 = stride64; +++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; +++ +++ stride64 = rpi->max_coeff64; +++ rpi->coeffbase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; +++ rpi->coeffstep64 = stride64; +++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; +++ return x64; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Start or restart phase 1 +++ +++static void phase1_begin(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ rpi->apb_write_addr(rpi->id, RPI_PUWBASE, rpi->pubase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_PUWSTRIDE, rpi->pustep64); +++ rpi->apb_write_addr(rpi->id, RPI_COEFFWBASE, rpi->coeffbase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_COEFFWSTRIDE, rpi->coeffstep64); +++} +++ +++/////////////////////////////////////////////////////////////////////////////// +++// Wait until phase 2 idle +++ +++static void wait_idle(RPI_T *rpi, int last) { +++ for (;;) { +++ int order; +++ pthread_mutex_lock (&rpi->mutex_phase2); +++ order = rpi->phase2_order; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ if (order==last) return; +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Handle PU and COEFF stream overflow +++ +++static int check_status(RPI_T *rpi) { +++ int status, c, p; +++ status = rpi->apb_read(rpi->id, RPI_STATUS); +++ p = (status>>4)&1; +++ c = (status>>3)&1; +++ if (p|c) { // overflow? +++ wait_idle(rpi, rpi->phase1_order-1); // drain phase2 before changing memory layout +++ if (p) rpi->max_pu_msgs += rpi->max_pu_msgs/2; +++ if (c) rpi->max_coeff64 += rpi->max_coeff64/2; +++ return 1; +++ } +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Write STATUS register with expected end CTU address of previous slice +++ +++static void end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; +++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++} +++ +++static void wpp_pause(RPI_T *rpi, int ctb_row) { +++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + 0x25); +++ p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); +++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1?0x70000:0x30000); +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_row<<16) + 2); +++} +++ +++static void wpp_end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int new_x = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int new_y = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; +++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; +++ if (rpi->wpp_entry_x<2 && (rpi->wpp_entry_y2) && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++ if (new_x==2 || rpi->PicWidthInCtbsY==2 && rpi->wpp_entry_yps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ p1_apb_write(rpi, RPI_SPS0, +++ (sps->log2_min_cb_size << 0) + +++ (sps->log2_ctb_size << 4) + +++ (sps->log2_min_tb_size << 8) + +++ (sps->log2_max_trafo_size << 12) + +++ (sps->bit_depth << 16) + +++ (sps->bit_depth << 20) + +++ (sps->max_transform_hierarchy_depth_intra << 24) + +++ (sps->max_transform_hierarchy_depth_inter << 28)); +++ +++ p1_apb_write(rpi, RPI_SPS1, +++ (sps->pcm.bit_depth << 0) + +++ (sps->pcm.bit_depth_chroma << 4) + +++ (sps->pcm.log2_min_pcm_cb_size << 8) + +++ (sps->pcm.log2_max_pcm_cb_size << 12) + +++ (sps->separate_colour_plane_flag? 0:sps->chroma_format_idc << 16) + +++ (sps->amp_enabled_flag << 18) + +++ (sps->pcm_enabled_flag << 19) + +++ (sps->scaling_list_enable_flag << 20) + +++ (sps->sps_strong_intra_smoothing_enable_flag << 21)); +++ +++ p1_apb_write(rpi, RPI_PPS, +++ (sps->log2_ctb_size - pps->diff_cu_qp_delta_depth << 0) + +++ (pps->cu_qp_delta_enabled_flag << 4) + +++ (pps->transquant_bypass_enable_flag << 5) + +++ (pps->transform_skip_enabled_flag << 6) + +++ (pps->sign_data_hiding_flag << 7) + +++ (((pps->cb_qp_offset + s->sh.slice_cb_qp_offset)&255) << 8) + +++ (((pps->cr_qp_offset + s->sh.slice_cr_qp_offset)&255) << 16) + +++ (pps->constrained_intra_pred_flag << 24)); +++ +++ if (s->ps.sps->scaling_list_enable_flag) WriteScalingFactors(rpi); +++ +++ if (!s->sh.dependent_slice_segment_flag) { +++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; +++ rpi->reg_slicestart = (ctb_col<<0) + (ctb_row<<16); +++ } +++ +++ p1_apb_write(rpi, RPI_SLICESTART, rpi->reg_slicestart); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void write_slice(RPI_T *rpi, HEVCContext *s, uint8_t slice_w, uint8_t slice_h) { +++ uint32_t u32 = +++ (s->sh.slice_type << 12) +++ + (s->sh.slice_sample_adaptive_offset_flag[0] << 14) +++ + (s->sh.slice_sample_adaptive_offset_flag[1] << 15) +++ + (slice_w << 17) +++ + (slice_h << 24); +++ +++ if (s->sh.slice_type==HEVC_SLICE_B || s->sh.slice_type==HEVC_SLICE_P) u32 |= +++ (s->sh.max_num_merge_cand << 0) +++ + (s->sh.nb_refs[L0] << 4) +++ + (s->sh.nb_refs[L1] << 8); +++ +++ if (s->sh.slice_type==HEVC_SLICE_B) u32 |= s->sh.mvd_l1_zero_flag<<16; +++ p1_apb_write(rpi, RPI_SLICE, u32); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Wavefront mode +++ +++static void wpp_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int ctb_size = 1<log2_ctb_size; +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ +++ int ctb_col = rpi->wpp_entry_x = ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = rpi->wpp_entry_y = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ +++ int endx = rpi->PicWidthInCtbsY-1; +++ int endy = ctb_row; +++ +++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); +++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); +++ +++ p1_apb_write(rpi, RPI_TILESTART, 0); +++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); +++ +++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); +++ +++ write_slice(rpi, s, slice_w, ctb_row==rpi->PicHeightInCtbsY-1? slice_h : ctb_size); +++ +++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); +++ +++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1? 0x60001 : 0x20001); +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Tiles mode +++ +++static void new_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int ctb_col = pps->ctb_addr_ts_to_rs[ctb_addr_ts] % rpi->PicWidthInCtbsY; +++ int ctb_row = pps->ctb_addr_ts_to_rs[ctb_addr_ts] / rpi->PicWidthInCtbsY; +++ +++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); +++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); +++ +++ int endx = pps->col_bd[tile_x+1] - 1; +++ int endy = pps->row_bd[tile_y+1] - 1; +++ +++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, 1<log2_ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); +++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, 1<log2_ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); +++ +++ p1_apb_write(rpi, RPI_TILESTART, pps->col_bd[tile_x] + (pps->row_bd[tile_y]<<16)); +++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); +++ +++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); +++ +++ write_slice(rpi, s, slice_w, slice_h); +++ +++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); +++ +++ p1_apb_write(rpi, RPI_MODE, (0xFFFF << 0) +++ + (0x0 << 16) +++ + ((tile_x==pps->num_tile_columns-1) << 17) +++ + ((tile_y==pps->num_tile_rows-1) << 18)); +++ +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Workaround for 3 December 2016 commit 8dfba25ce89b62c80ba83e2116d549176c376144 +++// https://github.com/libav/libav/commit/8dfba25ce89b62c80ba83e2116d549176c376144 +++// This commit prevents multi-threaded hardware acceleration by locking hwaccel_mutex +++// around codec->decode() calls. Workaround is to unlock and relock before returning. +++ +++static void hwaccel_mutex(AVCodecContext *avctx, int (*action) (pthread_mutex_t *)) { +++ struct FrameThreadContext { +++ void *foo1, *foo2; // must match struct layout in pthread_frame.c +++ pthread_mutex_t foo3, hwaccel_mutex; +++ }; +++ struct PerThreadContext { +++ struct FrameThreadContext *parent; +++ }; +++ struct PerThreadContext *p = avctx->internal->thread_ctx; +++ if (avctx->thread_count>1) action(&p->parent->hwaccel_mutex); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int get_thread_idx(RPI_T *rpi, AVCodecContext *avctx) { +++ int idx; +++ for (idx=0; idxthread_avctx[idx]==avctx) break; +++ av_assert0(idxinternal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ +++ int thread_idx = get_thread_idx(rpi, 0); // Find first free slot +++ +++ rpi->thread_avctx[thread_idx] = avctx; +++ rpi->thread_order[thread_idx] = rpi->decode_order++; +++ +++ ff_thread_finish_setup(avctx); // Allow next thread to enter rpi_hevc_start_frame +++ hwaccel_mutex(avctx, pthread_mutex_unlock); +++ +++ // Enforcing phase 1 order precludes busy waiting for phase 2 +++ for (;;) { +++ pthread_mutex_lock (&rpi->mutex_phase1); +++ if (rpi->thread_order[thread_idx]==rpi->phase1_order) break; +++ pthread_mutex_unlock(&rpi->mutex_phase1); +++ } +++ rpi->phase1_order++; +++ +++ alloc_picture_space(rpi, s, thread_idx); +++ rpi->bit_len = rpi->cmd_len = 0; +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Slice messages +++ +++static void msg_slice(RPI_T *rpi, uint16_t msg) { +++ rpi->slice_msgs[rpi->num_slice_msgs++] = msg; +++} +++ +++static void program_slicecmds(RPI_T *rpi, int sliceid) { +++ int i; +++ p1_apb_write(rpi, RPI_SLICECMDS, rpi->num_slice_msgs+(sliceid<<8)); +++ for(i=0; inum_slice_msgs; i++) { +++ p1_apb_write(rpi, 0x4000+4*i, rpi->slice_msgs[i] & 0xffff); +++ } +++} +++ +++static void pre_slice_decode(RPI_T *rpi, HEVCContext *s) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ SliceHeader *sh = &s->sh; +++ +++ int weightedPredFlag, i, rIdx; +++ uint16_t cmd_slice; +++ +++ rpi->num_slice_msgs=0; +++ cmd_slice = 0; +++ if (sh->slice_type==HEVC_SLICE_I) cmd_slice = 1; +++ if (sh->slice_type==HEVC_SLICE_P) cmd_slice = 2; +++ if (sh->slice_type==HEVC_SLICE_B) cmd_slice = 3; +++ +++ if (sh->slice_type!=HEVC_SLICE_I) { +++ cmd_slice += sh->nb_refs[L0]<<2; +++ cmd_slice += sh->nb_refs[L1]<<6; +++ } +++ if (sh->slice_type==HEVC_SLICE_P +++ || sh->slice_type==HEVC_SLICE_B) rpi->max_num_merge_cand = sh->max_num_merge_cand; +++ +++ cmd_slice += rpi->max_num_merge_cand<<11; +++ +++ if (sh->slice_temporal_mvp_enabled_flag) { +++ if (sh->slice_type==HEVC_SLICE_B) rpi->collocated_from_l0_flag = sh->collocated_list==L0; +++ else if (sh->slice_type==HEVC_SLICE_P) rpi->collocated_from_l0_flag = 1; +++ } +++ cmd_slice += rpi->collocated_from_l0_flag<<14; +++ +++ if (sh->slice_type==HEVC_SLICE_P || sh->slice_type==HEVC_SLICE_B) { +++ +++ int NoBackwardPredFlag = 1; // Flag to say all reference pictures are from the past +++ for(i=L0; i<=L1; i++) { +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ if (c->poc < f->poc) NoBackwardPredFlag = 0; +++ } +++ } +++ +++ rpi->collocated_ref_idx = sh->collocated_ref_idx; +++ if (s->ref->refPicList && s->ref->collocated_ref) +++ for (i=0; inb_refs[L1]) rpi->RefPicList[1][i] = s->ref->refPicList[1].ref[i] - s->DPB; +++ if (inb_refs[L0]) rpi->RefPicList[0][i] = s->ref->refPicList[0].ref[i] - s->DPB; +++ } +++ +++ cmd_slice += NoBackwardPredFlag<<10; +++ msg_slice(rpi, cmd_slice); +++ +++ // Write reference picture descriptions +++ weightedPredFlag = sh->slice_type==HEVC_SLICE_P? pps->weighted_pred_flag : pps->weighted_bipred_flag; +++ +++ for(i=L0; i<=L1; i++) +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ int pic = f - s->DPB; +++ // Make sure pictures are in range 0 to 15 +++ int adjusted_pic = fref->refPicList[i].isLongTerm[rIdx]; +++ msg_slice(rpi, adjusted_pic+(lt<<4)+(weightedPredFlag<<5)+(weightedPredFlag<<6)); +++ msg_slice(rpi, f->poc); +++ if (weightedPredFlag) { +++ msg_slice(rpi, s->sh.luma_log2_weight_denom+(((i?s-> sh.luma_weight_l1: s->sh.luma_weight_l0)[rIdx] &0x1ff)<<3)); +++ msg_slice(rpi, (i?s-> sh.luma_offset_l1: s->sh.luma_offset_l0)[rIdx] & 0xff); +++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][0]&0x1ff)<<3)); +++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][0]& 0xff); +++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][1]&0x1ff)<<3)); +++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][1]& 0xff); +++ } +++ } +++ } +++ else +++ msg_slice(rpi, cmd_slice); +++ +++ msg_slice(rpi, ((sh->beta_offset/2)&15) +++ + (((sh->tc_offset/2)&15) << 4) +++ + (sh->disable_deblocking_filter_flag << 8) +++ + (sh->slice_loop_filter_across_slices_enabled_flag << 9) +++ + (pps->loop_filter_across_tiles_enabled_flag << 10)); // CMD_DEBLOCK +++ +++ msg_slice(rpi, ((sh->slice_cr_qp_offset&31)<<5) + (sh->slice_cb_qp_offset&31)); // CMD_QPOFF +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ int thread_idx = get_thread_idx(rpi, s->avctx); +++ int CurrentPicture = s->ref - s->DPB; +++ int colPic = rpi->RefPicList[sh->slice_type==HEVC_SLICE_B && rpi->collocated_from_l0_flag==0][rpi->collocated_ref_idx]; +++ rpi->mvbase64 [thread_idx] = rpi->mvstorage64 + CurrentPicture * rpi->mvframebytes64; +++ if (sh->slice_type==HEVC_SLICE_I) { +++ // Collocated picture not well defined here. Use mvbase or previous value +++ if (sh->first_slice_in_pic_flag) +++ rpi->colbase64[thread_idx] = rpi->mvbase64[thread_idx]; // Ensure we don't read garbage +++ } +++ else +++ rpi->colbase64[thread_idx] = rpi->mvstorage64 + colPic * rpi->mvframebytes64; +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// End frame +++ +++static int rpi_hevc_end_frame(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ const HEVCPPS *pps = s->ps.pps; +++ const HEVCSPS *sps = s->ps.sps; +++ int thread_idx = get_thread_idx(rpi, avctx); +++ int jump = sps->bit_depth>8?96:128; +++ int CurrentPicture = s->ref - s->DPB; +++ AVFrame *f = s->ref->frame; +++ int last_x = pps->col_bd[pps->num_tile_columns]-1; +++ int last_y = pps->row_bd[pps->num_tile_rows]-1; +++ +++ int i, a64, x; +++ char *buf; +++ +++ // End of phase 1 command compilation +++ if (pps->entropy_coding_sync_enabled_flag) { +++ if (rpi->wpp_entry_x<2 && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); +++ } +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++ +++ // Phase 1 ... +++ for (;;) { +++ // (Re-)allocate PU/COEFF stream space +++ a64 = alloc_stream_space(rpi, s, thread_idx); +++ // Send bitstream data +++ for (i=0; ibit_len; i++) { +++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->bit_fifo[i].len, rpi->bit_fifo[i].ptr); +++ rpi->cmd_fifo[rpi->bit_fifo[i].cmd].data = a64 + (rpi->axi_get_addr(rpi->id)>>6); // Set BFBASE +++ a64 += (rpi->bit_fifo[i].len+63)/64; +++ } +++ // Send phase 1 commands (cache flush on real hardware) +++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD), rpi->cmd_fifo); +++ rpi->axi_flush(rpi->id, 3); +++ phase1_begin(rpi, s, thread_idx); +++ // Trigger command FIFO +++ rpi->apb_write(rpi->id, RPI_CFNUM, rpi->cmd_len); +++ rpi->apb_dump_regs(rpi->id, 0x0, 32); +++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); +++ rpi->axi_dump(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD)); +++ rpi->apb_write_addr(rpi->id, RPI_CFBASE, a64); +++ rpi->wait_interrupt(rpi->id, 1); +++ if (check_status(rpi)==0) break; // No PU/COEFF overflow? +++ } +++ pthread_mutex_unlock(&rpi->mutex_phase1); +++ +++ // Phase 2 ... +++ for (;;) { +++ pthread_mutex_lock (&rpi->mutex_phase2); +++ if (rpi->thread_order[thread_idx]==rpi->phase2_order) break; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ } +++ rpi->phase2_order++; +++ +++ rpi->apb_write_addr(rpi->id, RPI_PURBASE, rpi->pubase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_PURSTRIDE, rpi->pustep64); +++ rpi->apb_write_addr(rpi->id, RPI_COEFFRBASE, rpi->coeffbase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_COEFFRSTRIDE, rpi->coeffstep64); +++ +++#if !defined(AXI_BUFFERS) +++#define MANGLE(x) (((x) &~0xc0000000)>>6) +++{ +++ const AVRpiZcRefPtr fr_buf = f ? av_rpi_zc_ref(avctx, f, f->format, 0) : NULL; +++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; +++// printf("%s cur:%d fr:%p handle:%d YUV:%x:%x ystride:%d ustride:%d ah:%d\n", __FUNCTION__, CurrentPicture, f, handle, get_vc_address_y(f), get_vc_address_u(f), f->linesize[0], f->linesize[1], f->linesize[3]); +++ rpi->apb_write(rpi->id, RPI_OUTYBASE, MANGLE(get_vc_address_y(f))); +++ rpi->apb_write(rpi->id, RPI_OUTCBASE, MANGLE(get_vc_address_u(f))); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, f->linesize[3] * 128 / 64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, f->linesize[3] * 128 / 64); +++ av_rpi_zc_unref(fr_buf); +++} +++#else +++ // Output frame and reference picture locations +++ rpi->apb_write_addr(rpi->id, RPI_OUTYBASE, CurrentPicture * rpi->framebytes64); +++ rpi->apb_write_addr(rpi->id, RPI_OUTCBASE, CurrentPicture * rpi->framebytes64 + rpi->lumabytes64); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, rpi->lumastride64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, rpi->chromastride64); +++#endif +++ +++#if !defined(AXI_BUFFERS) +++{ +++ SliceHeader *sh = &s->sh; +++ int rIdx; +++ for(i=0; i<16; i++) { +++ rpi->apb_write(rpi->id, 0x9000+16*i, 0); +++ rpi->apb_write(rpi->id, 0x9004+16*i, 0); +++ rpi->apb_write(rpi->id, 0x9008+16*i, 0); +++ rpi->apb_write(rpi->id, 0x900C+16*i, 0); +++ } +++ +++ for(i=L0; i<=L1; i++) +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f1 = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ int pic = f1 - s->DPB; +++ // Make sure pictures are in range 0 to 15 +++ int adjusted_pic = f1DPB[pic]; +++ AVFrame *fr = hevc ? hevc->frame : NULL; +++ const AVRpiZcRefPtr fr_buf = fr ? av_rpi_zc_ref(avctx, fr, fr->format, 0) : NULL; +++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; +++// printf("%s pic:%d (%d,%d,%d) fr:%p handle:%d YUV:%x:%x\n", __FUNCTION__, adjusted_pic, i, rIdx, pic, fr, handle, get_vc_address_y(fr), get_vc_address_u(fr)); +++ rpi->apb_write(rpi->id, 0x9000+16*adjusted_pic, MANGLE(get_vc_address_y(fr))); +++ rpi->apb_write(rpi->id, 0x9008+16*adjusted_pic, MANGLE(get_vc_address_u(fr))); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, fr->linesize[3] * 128 / 64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, fr->linesize[3] * 128 / 64); +++ av_rpi_zc_unref(fr_buf); +++ } +++} +++#else +++ for(i=0; i<16; i++) { +++ int pic = i < CurrentPicture ? i : i+1; +++ rpi->apb_write_addr(rpi->id, 0x9000+16*i, pic * rpi->framebytes64); +++ rpi->apb_write(rpi->id, 0x9004+16*i, rpi->lumastride64); +++ rpi->apb_write_addr(rpi->id, 0x9008+16*i, pic * rpi->framebytes64 + rpi->lumabytes64); +++ rpi->apb_write(rpi->id, 0x900C+16*i, rpi->chromastride64); +++ } +++#endif +++ +++ rpi->apb_write(rpi->id, RPI_CONFIG2, +++ (sps->bit_depth << 0) // BitDepthY +++ + (sps->bit_depth << 4) // BitDepthC +++ + ((sps->bit_depth>8) << 8) // BitDepthY +++ + ((sps->bit_depth>8) << 9) // BitDepthC +++ + (sps->log2_ctb_size <<10) +++ + (pps->constrained_intra_pred_flag <<13) +++ + (sps->sps_strong_intra_smoothing_enable_flag<<14) +++ + (sps->sps_temporal_mvp_enabled_flag <<15) +++ + (pps->log2_parallel_merge_level <<16) +++ + (s->sh.slice_temporal_mvp_enabled_flag <<19) +++ + (sps->pcm.loop_filter_disable_flag <<20) +++ + ((pps->cb_qp_offset&31) <<21) +++ + ((pps->cr_qp_offset&31) <<26)); +++ +++ rpi->apb_write(rpi->id, RPI_FRAMESIZE, (sps->height<<16) + sps->width); +++ rpi->apb_write(rpi->id, RPI_CURRPOC, s->poc); +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ rpi->apb_write(rpi->id, RPI_COLSTRIDE, rpi->colstride64); +++ rpi->apb_write(rpi->id, RPI_MVSTRIDE, rpi->mvstride64); +++ rpi->apb_write_addr(rpi->id, RPI_MVBASE, rpi->mvbase64 [thread_idx]); +++ rpi->apb_write_addr(rpi->id, RPI_COLBASE, rpi->colbase64[thread_idx]); +++ } +++ +++ rpi->apb_dump_regs(rpi->id, 0x0, 32); +++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); +++ rpi->apb_write(rpi->id, RPI_NUMROWS, rpi->PicHeightInCtbsY); +++ rpi->apb_read_drop(rpi->id, RPI_NUMROWS); // Read back to confirm write has reached block +++ rpi->wait_interrupt(rpi->id, 2); +++ +++//printf("%s: %dx%d %d\n", __FUNCTION__, f->width, f->height, f->linesize[0]); +++#if defined(AXI_BUFFERS) +++ // Copy YUV output frame +++ av_assert0(buf = malloc(128*sps->height)); +++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64; +++ for(x=0; xwidth; x+=jump) { +++ int bpl = bytes_per_line(sps, jump, x); +++ read_rect(rpi, buf, a64, sps->height, bpl); +++ (sps->bit_depth>8?copy_luma10:copy_luma)(buf, bpl, sps->height, x, f->data[0], f->linesize[0]); +++ a64 += rpi->lumastride64; +++ } +++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64 + rpi->lumabytes64; +++ for(x=0; xwidth; x+=jump) { +++ int bpl = bytes_per_line(sps, jump, x); +++ read_rect(rpi, buf, a64, sps->height/2, bpl); +++ (sps->bit_depth>8?copy_chroma10:copy_chroma)(buf, bpl, sps->height/2, x/2, f->data[1], f->data[2], f->linesize[1]); +++ a64 += rpi->chromastride64; +++ } +++ free(buf); +++#endif +++ rpi->thread_avctx[thread_idx] = 0; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ hwaccel_mutex(avctx, pthread_mutex_lock); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void WriteBitstream(RPI_T *rpi, HEVCContext *s) { +++ const int rpi_use_emu = 0; // FFmpeg removes emulation prevention bytes +++ const int offset = 0; // Always 64-byte aligned in sim, need not be on real hardware +++ GetBitContext *gb = &s->HEVClc->gb; +++ int len = 1 + gb->size_in_bits/8 - gb->index/8; +++ const void *ptr = &gb->buffer[gb->index/8]; +++ +++ p1_axi_write(rpi, len, ptr, p1_apb_write(rpi, RPI_BFBASE, 0)); // BFBASE set later +++ p1_apb_write(rpi, RPI_BFNUM, len); +++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (1<<7)); // Stop +++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (rpi_use_emu<<6)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Wavefront mode +++ +++static void wpp_decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int i, resetQPY=1; +++ int indep = !s->sh.dependent_slice_segment_flag; +++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ +++ if (ctb_addr_ts) wpp_end_previous_slice(rpi, s, ctb_addr_ts); +++ pre_slice_decode(rpi, s); +++ WriteBitstream(rpi, s); +++ if (ctb_addr_ts==0 || indep || rpi->PicWidthInCtbsY==1) WriteProb(rpi); +++ else if (ctb_col==0) p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); +++ else resetQPY=0; +++ program_slicecmds(rpi, s->slice_idx); +++ new_slice_segment(rpi, s); +++ wpp_entry_point(rpi, s, indep, resetQPY, ctb_addr_ts); +++ for (i=0; ish.num_entry_point_offsets; i++) { +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int last_x = rpi->PicWidthInCtbsY-1; +++ if (rpi->PicWidthInCtbsY>2) wpp_pause(rpi, ctb_row); +++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + (last_x<<5) + 2); +++ if (rpi->PicWidthInCtbsY==2) p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); +++ if (rpi->PicWidthInCtbsY==1) WriteProb(rpi); +++ else p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); +++ ctb_addr_ts += pps->column_width[0]; +++ wpp_entry_point(rpi, s, 0, 1, ctb_addr_ts); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Tiles mode +++ +++static void decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int i, resetQPY; +++ +++ if (ctb_addr_ts) end_previous_slice(rpi, s, ctb_addr_ts); +++ pre_slice_decode(rpi, s); +++ WriteBitstream(rpi, s); +++ resetQPY = ctb_addr_ts==0 +++ || pps->tile_id[ctb_addr_ts]!=pps->tile_id[ctb_addr_ts-1] +++ || !s->sh.dependent_slice_segment_flag; +++ if (resetQPY) WriteProb(rpi); +++ program_slicecmds(rpi, s->slice_idx); +++ new_slice_segment(rpi, s); +++ new_entry_point(rpi, s, !s->sh.dependent_slice_segment_flag, resetQPY, ctb_addr_ts); +++ for (i=0; ish.num_entry_point_offsets; i++) { +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ int ctb_col = ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); +++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); +++ int last_x = pps->col_bd[tile_x+1]-1; +++ int last_y = pps->row_bd[tile_y+1]-1; +++ p1_apb_write(rpi, RPI_STATUS, 2 + (last_x<<5) + (last_y<<18)); +++ WriteProb(rpi); +++ ctb_addr_ts += pps->column_width[tile_x] * pps->row_height[tile_y]; +++ new_entry_point(rpi, s, 0, 1, ctb_addr_ts); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_decode_slice( +++ AVCodecContext *avctx, +++ const uint8_t *buffer, +++ uint32_t size) { +++ +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ const HEVCPPS *pps = s->ps.pps; +++ int ctb_addr_ts = pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]; +++ ff_hevc_cabac_init(s, ctb_addr_ts); +++ if (s->ps.sps->scaling_list_enable_flag) populate_scaling_factors(rpi, s); +++ populate_prob_tables(rpi, s); +++ pps->entropy_coding_sync_enabled_flag? wpp_decode_slice(rpi, s, ctb_addr_ts) +++ : decode_slice(rpi, s, ctb_addr_ts); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Bind to socket client +++ +++static int open_socket_client(RPI_T *rpi, const char *so) { +++ *(void **) &rpi->ctrl_ffmpeg_init = rpi_ctrl_ffmpeg_init; +++ *(void **) &rpi->apb_write = rpi_apb_write; +++ *(void **) &rpi->apb_write_addr = rpi_apb_write_addr; +++ *(void **) &rpi->apb_read = rpi_apb_read; +++ *(void **) &rpi->apb_read_drop = rpi_apb_read_drop; +++ *(void **) &rpi->axi_write = rpi_axi_write; +++ *(void **) &rpi->axi_read_alloc = rpi_axi_read_alloc; +++ *(void **) &rpi->axi_read_tx = rpi_axi_read_tx; +++ *(void **) &rpi->axi_read_rx = rpi_axi_read_rx; +++ *(void **) &rpi->axi_get_addr = rpi_axi_get_addr; +++ *(void **) &rpi->apb_dump_regs = rpi_apb_dump_regs; +++ *(void **) &rpi->axi_dump = rpi_axi_dump; +++ *(void **) &rpi->axi_flush = rpi_axi_flush; +++ *(void **) &rpi->wait_interrupt = rpi_wait_interrupt; +++ *(void **) &rpi->ctrl_ffmpeg_free = rpi_ctrl_ffmpeg_free; +++ return 1; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_alloc_frame(AVCodecContext *avctx, AVFrame *f) { +++ HEVCContext *s = avctx->priv_data; +++ const HEVCSPS *sps = s->ps.sps; +++ const int ALIGN = 16; +++ +++ f->width = sps->width; +++ f->height = sps->height; +++ f->format = sps->pix_fmt; +++ f->buf[0] = av_buffer_alloc(1); +++ f->buf[1] = av_buffer_alloc(1); +++ f->buf[2] = av_buffer_alloc(1); +++ return av_image_alloc(f->data, f->linesize, f->width, f->height, f->format, ALIGN); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_init(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ const char *err, *so; +++ +++ so = "./rpi_ffmpeg.so"; +++ +++ if (avctx->width>4096 || avctx->height>4096) { +++ av_log(NULL, AV_LOG_FATAL, "Picture size %dx%d exceeds 4096x4096 maximum for HWAccel\n", avctx->width, avctx->height); +++ return AVERROR(ENOTSUP); +++ } +++ if (!open_socket_client(rpi, so)) { +++ av_log(NULL, AV_LOG_FATAL, "%s\n", dlerror()); +++ return AVERROR_EXTERNAL; +++ } +++ err = rpi->ctrl_ffmpeg_init(NULL, &rpi->id); +++ if (err) { +++ av_log(NULL, AV_LOG_FATAL, "Could not connect to RPI server: %s\n", err); +++ return AVERROR_EXTERNAL; +++ } +++ +++#ifdef RPI_DISPLAY +++ #include "rpi_zc.h" +++ // Whilst FFmpegs init fn is only called once the close fn is called as +++ // many times as we have threads (init_thread_copy is called for the +++ // threads). So to match init & term put the init here where it will be +++ // called by both init & copy +++ av_rpi_zc_init(avctx); +++#endif +++ +++ pthread_mutex_init(&rpi->mutex_phase1, NULL); +++ pthread_mutex_init(&rpi->mutex_phase2, NULL); +++ +++ // Initial PU/COEFF stream buffer sizes chosen so jellyfish40.265 requires 1 overflow/restart +++ rpi->max_pu_msgs = 2+340; // 7.2 says at most 1611 messages per CTU +++ rpi->max_coeff64 = 2+1404; +++ +++ av_assert0(rpi->cmd_fifo = malloc((rpi->cmd_max=1024)*sizeof(struct RPI_CMD))); +++ av_assert0(rpi->bit_fifo = malloc((rpi->bit_max=1024)*sizeof(struct RPI_BIT))); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_free(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ if (rpi->decode_order) wait_idle(rpi, rpi->decode_order); +++ if (rpi->cmd_fifo) free(rpi->cmd_fifo); +++ if (rpi->bit_fifo) free(rpi->bit_fifo); +++ pthread_mutex_destroy(&rpi->mutex_phase1); +++ pthread_mutex_destroy(&rpi->mutex_phase2); +++ if (rpi->id && rpi->ctrl_ffmpeg_free) rpi->ctrl_ffmpeg_free(rpi->id); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++const AVHWAccel ff_hevc_rpi4_8_hwaccel = { +++ .name = "hevc_rpi4_8", +++ .type = AVMEDIA_TYPE_VIDEO, +++ .id = AV_CODEC_ID_HEVC, +++ .pix_fmt = AV_PIX_FMT_RPI4_8, +++ //.alloc_frame = rpi_hevc_alloc_frame, +++ .start_frame = rpi_hevc_start_frame, +++ .end_frame = rpi_hevc_end_frame, +++ .decode_slice = rpi_hevc_decode_slice, +++ .init = rpi_hevc_init, +++ .uninit = rpi_hevc_free, +++ .priv_data_size = sizeof(RPI_T), +++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +++}; +++ +++const AVHWAccel ff_hevc_rpi4_10_hwaccel = { +++ .name = "hevc_rpi4_10", +++ .type = AVMEDIA_TYPE_VIDEO, +++ .id = AV_CODEC_ID_HEVC, +++ .pix_fmt = AV_PIX_FMT_RPI4_10, +++ //.alloc_frame = rpi_hevc_alloc_frame, +++ .start_frame = rpi_hevc_start_frame, +++ .end_frame = rpi_hevc_end_frame, +++ .decode_slice = rpi_hevc_decode_slice, +++ .init = rpi_hevc_init, +++ .uninit = rpi_hevc_free, +++ .priv_data_size = sizeof(RPI_T), +++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +++}; +++ +++ +++int rpi_init(AVCodecContext *avctx) { +++ return 0; +++} ++diff --git a/libavcodec/rpi_hevc.h b/libavcodec/rpi_hevc.h ++new file mode 100644 ++index 0000000000..f54657a957 ++--- /dev/null +++++ b/libavcodec/rpi_hevc.h ++@@ -0,0 +1,219 @@ +++// FFMPEG HEVC decoder hardware accelerator +++// Andrew Holme, Argon Design Ltd +++// Copyright (c) June 2017 Raspberry Pi Ltd +++ +++#include +++#include +++ +++#include "hevc.h" +++#include "hevcdec.h" +++ +++#define MAX_THREADS 50 +++#define NUM_SCALING_FACTORS 4064 +++ +++#define AXI_BASE64 0 +++ +++#define PROB_BACKUP ((20<<12) + (20<<6) + (0<<0)) +++#define PROB_RELOAD ((20<<12) + (20<<0) + (0<<6)) +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++#define RPI_SPS0 0 +++#define RPI_SPS1 4 +++#define RPI_PPS 8 +++#define RPI_SLICE 12 +++#define RPI_TILESTART 16 +++#define RPI_TILEEND 20 +++#define RPI_SLICESTART 24 +++#define RPI_MODE 28 +++#define RPI_LEFT0 32 +++#define RPI_LEFT1 36 +++#define RPI_LEFT2 40 +++#define RPI_LEFT3 44 +++#define RPI_QP 48 +++#define RPI_CONTROL 52 +++#define RPI_STATUS 56 +++#define RPI_VERSION 60 +++#define RPI_BFBASE 64 +++#define RPI_BFNUM 68 +++#define RPI_BFCONTROL 72 +++#define RPI_BFSTATUS 76 +++#define RPI_PUWBASE 80 +++#define RPI_PUWSTRIDE 84 +++#define RPI_COEFFWBASE 88 +++#define RPI_COEFFWSTRIDE 92 +++#define RPI_SLICECMDS 96 +++#define RPI_BEGINTILEEND 100 +++#define RPI_TRANSFER 104 +++#define RPI_CFBASE 108 +++#define RPI_CFNUM 112 +++#define RPI_CFSTATUS 116 +++ +++#define RPI_PURBASE 0x8000 +++#define RPI_PURSTRIDE 0x8004 +++#define RPI_COEFFRBASE 0x8008 +++#define RPI_COEFFRSTRIDE 0x800C +++#define RPI_NUMROWS 0x8010 +++#define RPI_CONFIG2 0x8014 +++#define RPI_OUTYBASE 0x8018 +++#define RPI_OUTYSTRIDE 0x801C +++#define RPI_OUTCBASE 0x8020 +++#define RPI_OUTCSTRIDE 0x8024 +++#define RPI_STATUS2 0x8028 +++#define RPI_FRAMESIZE 0x802C +++#define RPI_MVBASE 0x8030 +++#define RPI_MVSTRIDE 0x8034 +++#define RPI_COLBASE 0x8038 +++#define RPI_COLSTRIDE 0x803C +++#define RPI_CURRPOC 0x8040 +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct FFM_PROB { +++ uint8_t sao_merge_flag [ 1]; +++ uint8_t sao_type_idx [ 1]; +++ uint8_t split_coding_unit_flag [ 3]; +++ uint8_t cu_transquant_bypass_flag [ 1]; +++ uint8_t skip_flag [ 3]; +++ uint8_t cu_qp_delta [ 3]; +++ uint8_t pred_mode_flag [ 1]; +++ uint8_t part_mode [ 4]; +++ uint8_t prev_intra_luma_pred_flag [ 1]; +++ uint8_t intra_chroma_pred_mode [ 2]; +++ uint8_t merge_flag [ 1]; +++ uint8_t merge_idx [ 1]; +++ uint8_t inter_pred_idc [ 5]; +++ uint8_t ref_idx_l0 [ 2]; +++ uint8_t ref_idx_l1 [ 2]; +++ uint8_t abs_mvd_greater0_flag [ 2]; +++ uint8_t abs_mvd_greater1_flag [ 2]; +++ uint8_t mvp_lx_flag [ 1]; +++ uint8_t no_residual_data_flag [ 1]; +++ uint8_t split_transform_flag [ 3]; +++ uint8_t cbf_luma [ 2]; +++ uint8_t cbf_cb_cr [ 4]; +++ uint8_t transform_skip_flag/*[][]*/ [ 2]; +++ uint8_t explicit_rdpcm_flag/*[][]*/ [ 2]; +++ uint8_t explicit_rdpcm_dir_flag/*[][]*/ [ 2]; +++ uint8_t last_significant_coeff_x_prefix [18]; +++ uint8_t last_significant_coeff_y_prefix [18]; +++ uint8_t significant_coeff_group_flag [ 4]; +++ uint8_t significant_coeff_flag [44]; +++ uint8_t coeff_abs_level_greater1_flag [24]; +++ uint8_t coeff_abs_level_greater2_flag [ 6]; +++ uint8_t log2_res_scale_abs [ 8]; +++ uint8_t res_scale_sign_flag [ 2]; +++ uint8_t cu_chroma_qp_offset_flag [ 1]; +++ uint8_t cu_chroma_qp_offset_idx [ 1]; +++} __attribute__((packed)); +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct RPI_PROB { +++ uint8_t SAO_MERGE_FLAG [ 1]; +++ uint8_t SAO_TYPE_IDX [ 1]; +++ uint8_t SPLIT_FLAG [ 3]; +++ uint8_t CU_SKIP_FLAG [ 3]; +++ uint8_t CU_TRANSQUANT_BYPASS_FLAG [ 1]; +++ uint8_t PRED_MODE [ 1]; +++ uint8_t PART_SIZE [ 4]; +++ uint8_t INTRA_PRED_MODE [ 1]; +++ uint8_t CHROMA_PRED_MODE [ 1]; +++ uint8_t MERGE_FLAG_EXT [ 1]; +++ uint8_t MERGE_IDX_EXT [ 1]; +++ uint8_t INTER_DIR [ 5]; +++ uint8_t REF_PIC [ 2]; +++ uint8_t MVP_IDX [ 1]; +++ uint8_t MVD [ 2]; +++ uint8_t QT_ROOT_CBF [ 1]; +++ uint8_t TRANS_SUBDIV_FLAG [ 3]; +++ uint8_t QT_CBF [ 6]; +++ uint8_t DQP [ 2]; +++ uint8_t ONE_FLAG [24]; +++ uint8_t LASTX [18]; +++ uint8_t LASTY [18]; +++ uint8_t SIG_CG_FLAG [ 4]; +++ uint8_t ABS_FLAG [ 6]; +++ uint8_t TRANSFORMSKIP_FLAG [ 2]; +++ uint8_t SIG_FLAG [42]; +++ uint8_t SIG_FLAG_unused [ 2]; +++} __attribute__((packed)); +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct RPI_CMD { +++ uint32_t addr; +++ uint32_t data; +++} __attribute__((packed)); +++ +++struct RPI_BIT { +++ int cmd; +++ const void *ptr; +++ int len; +++}; +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++typedef struct RPI_T { +++struct RPI_BIT *bit_fifo; +++struct RPI_CMD *cmd_fifo; +++ int bit_len, bit_max; +++ int cmd_len, cmd_max; +++ int max_pu_msgs; +++ int max_coeff64; +++AVCodecContext *thread_avctx[MAX_THREADS]; +++ int thread_order[MAX_THREADS]; +++ int decode_order; +++ int phase1_order; +++ int phase2_order; +++pthread_mutex_t mutex_phase1; +++pthread_mutex_t mutex_phase2; +++ uint8_t scaling_factors[NUM_SCALING_FACTORS]; +++struct RPI_PROB probabilities; +++ int num_slice_msgs; +++ uint16_t slice_msgs[2*HEVC_MAX_REFS*8+3]; +++ int pubase64[MAX_THREADS]; +++ int pustep64; +++ int coeffbase64[MAX_THREADS]; +++ int coeffstep64; +++ int PicWidthInCtbsY; +++ int PicHeightInCtbsY; +++#ifdef AXI_BUFFERS +++ int lumabytes64; +++ int framebytes64; +++ int lumastride64; +++ int chromastride64; +++#endif +++ int mvframebytes64; +++ int mvstorage64; +++ int colstride64; +++ int mvstride64; +++ int colbase64[MAX_THREADS]; +++ int mvbase64[MAX_THREADS]; +++ uint32_t reg_slicestart; +++ int collocated_from_l0_flag; +++ int max_num_merge_cand; +++ int RefPicList[2][HEVC_MAX_REFS]; +++ int collocated_ref_idx; +++ int wpp_entry_x; +++ int wpp_entry_y; +++ +++ void * dl_handle; +++ void * id; +++ char * (* ctrl_ffmpeg_init) (const char *hwaccel_device, void **id); +++ void (* apb_write) (void *id, uint16_t addr, uint32_t data); +++ void (* apb_write_addr) (void *id, uint16_t addr, uint32_t data); +++ uint32_t (* apb_read) (void *id, uint16_t addr); +++ void (* apb_read_drop) (void *id, uint16_t addr); +++ void (* axi_write) (void *id, uint64_t addr, uint32_t size, const void *buf); +++ void (* axi_read_alloc) (void *id, uint32_t size); +++ void (* axi_read_tx) (void *id, uint64_t addr, uint32_t size); +++ void (* axi_read_rx) (void *id, uint32_t size, void *buf); +++ uint64_t (* axi_get_addr) (void *id); +++ void (* apb_dump_regs) (void *id, uint16_t addr, int num); +++ void (* axi_dump) (void *id, uint64_t addr, uint32_t size); +++ void (* axi_flush) (void *id, int mode); +++ void (* wait_interrupt) (void *id, int phase); +++ void (* ctrl_ffmpeg_free) (void *id); +++ +++} RPI_T; ++diff --git a/libavcodec/rpi_mailbox.c b/libavcodec/rpi_mailbox.c ++new file mode 100644 ++index 0000000000..5f23e9b36c ++--- /dev/null +++++ b/libavcodec/rpi_mailbox.c ++@@ -0,0 +1,149 @@ +++/* +++Copyright (c) 2012, Broadcom Europe Ltd. +++All rights reserved. +++ +++Redistribution and use in source and binary forms, with or without +++modification, are permitted provided that the following conditions are met: +++ * Redistributions of source code must retain the above copyright +++ notice, this list of conditions and the following disclaimer. +++ * 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. +++ * Neither the name of the copyright holder 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +++*/ +++ +++#if 1//defined(RPI) || defined (RPI_DISPLAY) +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#include +++ +++#define MAJOR_NUM 100 +++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) +++#define DEVICE_FILE_NAME "/dev/vcio" +++ +++#include "rpi_mailbox.h" +++//#include +++ +++/* +++ * use ioctl to send mbox property message +++ */ +++ +++static int mbox_property(int file_desc, void *buf) +++{ +++ int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); +++ +++ if (ret_val < 0) { +++ printf("ioctl_set_msg failed:%d\n", ret_val); +++ } +++ +++#ifdef DEBUG +++ unsigned *p = buf; int i; unsigned size = *(unsigned *)buf; +++ for (i=0; i +++#include +++#include +++#include +++#include +++#include "libavutil/avassert.h" +++ +++#include "config.h" +++ +++#include +++#include +++ +++#include +++ +++#include "rpi_mailbox.h" +++#include "rpi_qpu.h" +++ +++#pragma GCC diagnostic push +++// Many many redundant decls in the header files +++#pragma GCC diagnostic ignored "-Wredundant-decls" +++#include "interface/vmcs_host/vc_vchi_gpuserv.h" +++#pragma GCC diagnostic pop +++ +++// QPU "noflush" flags +++// a mixture of flushing & profiling +++ +++#define QPU_FLAGS_NO_FLUSH_VPU 1 // If unset VPU cache will be flushed +++#define QPU_FLAGS_PROF_CLEAR_AND_ENABLE 2 // Clear & Enable detailed QPU profiling registers +++#define QPU_FLAGS_PROF_OUTPUT_COUNTS 4 // Print the results +++#define QPU_FLAGS_OUTPUT_QPU_TIMES 8 // Print QPU times - independant of the profiling +++#define QPU_FLAGS_NO_FLUSH_QPU 16 // If unset flush QPU caches & TMUs (uniforms always flushed) +++ +++#define vcos_verify_ge0(x) ((x)>=0) +++ +++struct rpi_cache_flush_env_s { +++// unsigned int n; +++// struct vcsm_user_clean_invalid_s a[CFE_A_COUNT]; +++ struct vcsm_user_clean_invalid2_s v; +++}; +++ +++typedef struct gpu_env_s +++{ +++ int open_count; +++ int init_count; +++ int mb; +++ int vpu_i_cache_flushed; +++} gpu_env_t; +++ +++// Stop more than one thread trying to allocate memory or use the processing resources at once +++static pthread_mutex_t gpu_mutex = PTHREAD_MUTEX_INITIALIZER; +++static gpu_env_t * gpu = NULL; +++ +++ +++// GPU memory alloc fns (internal) +++ +++// GPU_MEM_PTR_T alloc fns +++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = (numbytes + 255) & ~255; // Round up +++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_VC, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_HOST_AND_VC, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++// printf("***** %s, %d\n", __func__, numbytes); +++ +++ return 0; +++} +++ +++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = numbytes; +++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++// printf("***** %s, %d\n", __func__, numbytes); +++ return 0; +++} +++ +++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { +++ mbox_mem_unlock(mb, p->vc_handle); +++ vcsm_unlock_ptr(p->arm); +++ vcsm_free(p->vcsm_handle); +++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again +++// printf("***** %s\n", __func__); +++} +++ +++ +++// GPU init, free, lock, unlock +++ +++static void gpu_term(void) +++{ +++ gpu_env_t * const ge = gpu; +++ +++ // We have to hope that eveything has terminated... +++ gpu = NULL; +++ +++ vc_gpuserv_deinit(); +++ +++ vcsm_exit(); +++ +++ mbox_close(ge->mb); +++ +++ free(ge); +++} +++ +++ +++// Connect to QPU, returns 0 on success. +++static int gpu_init(gpu_env_t ** const gpu) { +++ gpu_env_t * const ge = calloc(1, sizeof(gpu_env_t)); +++ *gpu = NULL; +++ +++ if (ge == NULL) +++ return -1; +++ +++ if ((ge->mb = mbox_open()) < 0) +++ return -1; +++ +++ vcsm_init(); +++ +++ *gpu = ge; +++ return 0; +++} +++ +++ +++ +++static void gpu_unlock(void) { +++ pthread_mutex_unlock(&gpu_mutex); +++} +++ +++// Make sure we have exclusive access to the mailbox, and enable qpu if necessary. +++static gpu_env_t * gpu_lock(void) { +++ pthread_mutex_lock(&gpu_mutex); +++ +++ av_assert0(gpu != NULL); +++ return gpu; +++} +++ +++static gpu_env_t * gpu_lock_ref(void) +++{ +++ pthread_mutex_lock(&gpu_mutex); +++ +++ if (gpu == NULL) { +++ int rv = gpu_init(&gpu); +++ if (rv != 0) { +++ gpu_unlock(); +++ return NULL; +++ } +++ } +++ +++ ++gpu->open_count; +++ return gpu; +++} +++ +++static void gpu_unlock_unref(gpu_env_t * const ge) +++{ +++ if (--ge->open_count == 0) +++ gpu_term(); +++ +++ gpu_unlock(); +++} +++ +++static inline gpu_env_t * gpu_ptr(void) +++{ +++ av_assert0(gpu != NULL); +++ return gpu; +++} +++ +++// Public gpu fns +++ +++// Allocate memory on GPU +++// Fills in structure

containing ARM pointer, videocore handle, videocore memory address, numbytes +++// Returns 0 on success. +++// This allocates memory that will not be cached in ARM's data cache. +++// Therefore safe to use without data cache flushing. +++int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p) +++{ +++ int r; +++ gpu_env_t * const ge = gpu_lock_ref(); +++ if (ge == NULL) +++ return -1; +++ r = gpu_malloc_uncached_internal(ge->mb, numbytes, p); +++ gpu_unlock(); +++ return r; +++} +++ +++// This allocates data that will be +++// Cached in ARM L2 +++// Uncached in VPU L2 +++int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p) +++{ +++ int r; +++ gpu_env_t * const ge = gpu_lock_ref(); +++ if (ge == NULL) +++ return -1; +++ r = gpu_malloc_cached_internal(ge->mb, numbytes, p); +++ gpu_unlock(); +++ return r; +++} +++ +++void gpu_free(GPU_MEM_PTR_T * const p) { +++ gpu_env_t * const ge = gpu_lock(); +++ gpu_free_internal(ge->mb, p); +++ gpu_unlock_unref(ge); +++} +++ +++int gpu_get_mailbox(void) +++{ +++ av_assert0(gpu); +++ return gpu->mb; +++} +++ +++void gpu_ref(void) +++{ +++ gpu_lock_ref(); +++ gpu_unlock(); +++} +++ +++void gpu_unref(void) +++{ +++ gpu_env_t * const ge = gpu_lock(); +++ gpu_unlock_unref(ge); +++} +++ +++// ---------------------------------------------------------------------------- +++// +++// Cache flush functions +++ +++#define CACHE_EL_MAX 16 +++ +++rpi_cache_flush_env_t * rpi_cache_flush_init() +++{ +++ rpi_cache_flush_env_t * const rfe = malloc(sizeof(rpi_cache_flush_env_t) + +++ sizeof(struct vcsm_user_clean_invalid2_block_s) * CACHE_EL_MAX); +++ if (rfe == NULL) +++ return NULL; +++ +++ rfe->v.op_count = 0; +++ return rfe; +++} +++ +++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe) +++{ +++ if (rfe != NULL) +++ free(rfe); +++} +++ +++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe) +++{ +++ int rc = 0; +++ +++ if (vcsm_clean_invalid2(&rfe->v) != 0) +++ rc = -1; +++ +++ free(rfe); +++ +++ if (rc == 0) +++ return 0; +++ +++ av_log(NULL, AV_LOG_ERROR, "vcsm_clean_invalid failed: errno=%d\n", errno); +++ return rc; +++} +++ +++inline void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride) +++{ +++ struct vcsm_user_clean_invalid2_block_s * const b = rfe->v.s + rfe->v.op_count++; +++ +++ av_assert0(rfe->v.op_count <= CACHE_EL_MAX); +++ +++ b->invalidate_mode = mode; +++ b->block_count = blocks; +++ b->start_address = gm->arm + offset0; +++ b->block_size = block_size; +++ b->inter_block_stride = block_stride; +++} +++ +++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset, const unsigned int size) +++{ +++ // Deal with empty pointer trivially +++ if (gm == NULL || size == 0) +++ return; +++ +++ av_assert0(offset <= gm->numbytes); +++ av_assert0(size <= gm->numbytes); +++ av_assert0(offset + size <= gm->numbytes); +++ +++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, offset, size, 1, 0); +++} +++ +++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode) +++{ +++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, 0, gm->numbytes, 1, 0); +++} +++ +++ +++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const unsigned int mode) +++{ +++#if !RPI_ONE_BUF +++#error Fixme! (NIF) +++#endif +++ if (gpu_is_buf1(frame)) { +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf1_gmem(frame), mode); +++ } +++ else +++ { +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 0), mode); +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 1), mode); +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 2), mode); +++ } +++} +++ +++// Call this to clean and invalidate a region of memory +++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T *const p, const rpi_cache_flush_mode_t mode) +++{ +++ rpi_cache_flush_env_t * rfe = rpi_cache_flush_init(); +++ rpi_cache_flush_add_gm_ptr(rfe, p, mode); +++ rpi_cache_flush_finish(rfe); +++} +++ +++ +++// ---------------------------------------------------------------------------- +++ +++#endif // RPI ++diff --git a/libavcodec/rpi_qpu.h b/libavcodec/rpi_qpu.h ++new file mode 100644 ++index 0000000000..485a08f8ba ++--- /dev/null +++++ b/libavcodec/rpi_qpu.h ++@@ -0,0 +1,206 @@ +++#ifndef RPI_QPU_H +++#define RPI_QPU_H +++ +++#define RPI_ONE_BUF 1 +++ +++typedef struct gpu_mem_ptr_s { +++ unsigned char *arm; // Pointer to memory mapped on ARM side +++ int vc_handle; // Videocore handle of relocatable memory +++ int vcsm_handle; // Handle for use by VCSM +++ int vc; // Address for use in GPU code +++ int numbytes; // Size of memory block +++} GPU_MEM_PTR_T; +++ +++// General GPU functions +++extern int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p); +++extern int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p); +++extern void gpu_free(GPU_MEM_PTR_T * const p); +++ +++#include "libavutil/frame.h" +++#if !RPI_ONE_BUF +++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[0]); +++ return p->vc; +++} +++ +++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[1]); +++ return p->vc; +++} +++ +++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[2]); +++ return p->vc; +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[0]); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[1]); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[2]); +++} +++ +++#else +++ +++static inline int gpu_is_buf1(const AVFrame * const frame) +++{ +++ return frame->buf[1] == NULL; +++} +++ +++static inline GPU_MEM_PTR_T * gpu_buf1_gmem(const AVFrame * const frame) +++{ +++ return av_buffer_get_opaque(frame->buf[0]); +++} +++ +++static inline GPU_MEM_PTR_T * gpu_buf3_gmem(const AVFrame * const frame, const unsigned int n) +++{ +++ return av_buffer_pool_opaque(frame->buf[n]); +++} +++ +++static inline uint32_t get_vc_address3(const AVFrame * const frame, const unsigned int n) +++{ +++ const GPU_MEM_PTR_T * const gm = gpu_is_buf1(frame) ? gpu_buf1_gmem(frame) : gpu_buf3_gmem(frame, n); +++ return gm->vc + (frame->data[n] - gm->arm); +++} +++ +++ +++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { +++ return get_vc_address3(frame, 0); +++} +++ +++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { +++ return get_vc_address3(frame, 1); +++} +++ +++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { +++ return get_vc_address3(frame, 2); +++} +++ +++#if 0 +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.numbytes = frame->data[1] - frame->data[0]; +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 0); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.arm += frame->data[1] - frame->data[0]; +++ g.vc += frame->data[1] - frame->data[0]; +++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 1); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.arm += frame->data[2] - frame->data[0]; +++ g.vc += frame->data[2] - frame->data[0]; +++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 2); +++} +++#endif +++#endif +++ +++// Cache flush stuff +++ +++struct rpi_cache_flush_env_s; +++typedef struct rpi_cache_flush_env_s rpi_cache_flush_env_t; +++ +++rpi_cache_flush_env_t * rpi_cache_flush_init(void); +++// Free env without flushing +++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe); +++// Do the accumulated flush & free the env +++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe); +++ +++typedef enum +++{ +++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, +++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, +++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 +++} rpi_cache_flush_mode_t; +++ +++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode); +++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode, +++ const unsigned int offset, const unsigned int size); +++void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride); +++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode); +++void rpi_cache_flush_add_frame_block(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode, +++ const unsigned int x0, const unsigned int y0, const unsigned int width, const unsigned int height, +++ const unsigned int uv_shift, const int do_luma, const int do_chroma); +++ +++// init, add, finish for one gm ptr +++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T * const p, const rpi_cache_flush_mode_t mode); +++ +++ +++// QPU specific functions +++ +++typedef struct HEVCRpiQpu { +++ uint32_t c_pxx; +++ uint32_t c_pxx_l1; +++ uint32_t c_bxx; +++ uint32_t y_pxx; +++ uint32_t y_bxx; +++ uint32_t y_p00; +++ uint32_t y_b00; +++} HEVCRpiQpu; +++ +++int rpi_hevc_qpu_init_fn(HEVCRpiQpu * const qf, const unsigned int bit_depth); +++ +++uint32_t qpu_fn(const int * const mc_fn); +++ +++#define QPU_N_GRP 4 +++#define QPU_N_MAX 12 +++ +++#define QPU_MAIL_EL_VALS 2 +++ +++struct vpu_qpu_wait_s; +++typedef struct vq_wait_s * vpu_qpu_wait_h; +++ +++// VPU specific functions +++ +++struct vpu_qpu_job_env_s; +++typedef struct vpu_qpu_job_env_s * vpu_qpu_job_h; +++ +++vpu_qpu_job_h vpu_qpu_job_new(void); +++void vpu_qpu_job_delete(const vpu_qpu_job_h vqj); +++void vpu_qpu_job_add_vpu(const vpu_qpu_job_h vqj, const uint32_t vpu_code, +++ const unsigned r0, const unsigned r1, const unsigned r2, const unsigned r3, const unsigned r4, const unsigned r5); +++void vpu_qpu_job_add_qpu(const vpu_qpu_job_h vqj, const unsigned int n, const uint32_t * const mail); +++void vpu_qpu_job_add_sync_this(const vpu_qpu_job_h vqj, vpu_qpu_wait_h * const wait_h); +++int vpu_qpu_job_start(const vpu_qpu_job_h vqj); +++int vpu_qpu_job_finish(const vpu_qpu_job_h vqj); +++ +++extern unsigned int vpu_get_fn(const unsigned int bit_depth); +++extern unsigned int vpu_get_constants(void); +++ +++// Waits for previous post_codee to complete and Will null out *wait_h after use +++void vpu_qpu_wait(vpu_qpu_wait_h * const wait_h); +++int vpu_qpu_init(void); +++void vpu_qpu_term(void); +++ +++extern int gpu_get_mailbox(void); +++void gpu_ref(void); +++void gpu_unref(void); +++ +++#endif ++diff --git a/libavcodec/rpi_zc.c b/libavcodec/rpi_zc.c ++new file mode 100644 ++index 0000000000..3bf1da4083 ++--- /dev/null +++++ b/libavcodec/rpi_zc.c ++@@ -0,0 +1,743 @@ +++#include "config.h" +++#if 1 //defined(RPI) //|| defined (RPI_DISPLAY) +++#include "libavcodec/avcodec.h" +++#include "rpi_qpu.h" +++#include "rpi_mailbox.h" +++#include "rpi_zc.h" +++#include "libavutil/avassert.h" +++#include +++ +++#include "libavutil/buffer_internal.h" +++#include +++ +++#define TRACE_ALLOC 0 +++ +++struct ZcPoolEnt; +++ +++typedef struct ZcPool +++{ +++ int numbytes; +++ unsigned int n; +++ struct ZcPoolEnt * head; +++ pthread_mutex_t lock; +++} ZcPool; +++ +++typedef struct ZcPoolEnt +++{ +++ // It is important that we start with gmem as other bits of code will expect to see that +++ GPU_MEM_PTR_T gmem; +++ unsigned int n; +++ struct ZcPoolEnt * next; +++ struct ZcPool * pool; +++} ZcPoolEnt; +++ +++#define ALLOC_PAD 0 +++#define ALLOC_ROUND 0x1000 +++#define ALLOC_N_OFFSET 0 +++#define STRIDE_ROUND 64 +++#define STRIDE_OR 0 +++ +++#define DEBUG_ZAP0_BUFFERS 0 +++ +++static inline int av_rpi_is_sand_format(const int format) +++{ +++ return (format >= AV_PIX_FMT_SAND128 && format <= AV_PIX_FMT_SAND64_16) || +++ (format == AV_PIX_FMT_RPI4_8 || format == AV_PIX_FMT_RPI4_10); +++} +++ +++static inline int av_rpi_is_sand_frame(const AVFrame * const frame) +++{ +++ return av_rpi_is_sand_format(frame->format); +++} +++ +++static ZcPoolEnt * zc_pool_ent_alloc(ZcPool * const pool, const unsigned int req_size) +++{ +++ ZcPoolEnt * const zp = av_malloc(sizeof(ZcPoolEnt)); +++ +++ // Round up to 4k & add 4k +++ const unsigned int alloc_size = (req_size + ALLOC_PAD + ALLOC_ROUND - 1) & ~(ALLOC_ROUND - 1); +++ +++ if (zp == NULL) { +++ av_log(NULL, AV_LOG_ERROR, "av_malloc(ZcPoolEnt) failed\n"); +++ goto fail0; +++ } +++ +++ if (gpu_malloc_cached(alloc_size, &zp->gmem) != 0) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_gpu_malloc_cached(%d) failed\n", alloc_size); +++ goto fail1; +++ } +++ +++#if TRACE_ALLOC +++ printf("%s: Alloc %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); +++#endif +++ +++ pool->numbytes = zp->gmem.numbytes; +++ zp->next = NULL; +++ zp->pool = pool; +++ zp->n = pool->n++; +++ return zp; +++ +++fail1: +++ av_free(zp); +++fail0: +++ return NULL; +++} +++ +++static void zc_pool_ent_free(ZcPoolEnt * const zp) +++{ +++#if TRACE_ALLOC +++ printf("%s: Free %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); +++#endif +++ +++ gpu_free(&zp->gmem); +++ av_free(zp); +++} +++ +++static void zc_pool_flush(ZcPool * const pool) +++{ +++ ZcPoolEnt * p = pool->head; +++ pool->head = NULL; +++ pool->numbytes = -1; +++ +++ while (p != NULL) +++ { +++ ZcPoolEnt * const zp = p; +++ p = p->next; +++ zc_pool_ent_free(zp); +++ } +++} +++ +++static ZcPoolEnt * zc_pool_alloc(ZcPool * const pool, const int req_bytes) +++{ +++ ZcPoolEnt * zp; +++ int numbytes; +++ +++ pthread_mutex_lock(&pool->lock); +++ +++ numbytes = pool->numbytes; +++ +++ // If size isn't close then dump the pool +++ // Close in this context means within 128k +++ if (req_bytes > numbytes || req_bytes + 0x20000 < numbytes) +++ { +++ zc_pool_flush(pool); +++ numbytes = req_bytes; +++ } +++ +++ if (pool->head != NULL) +++ { +++ zp = pool->head; +++ pool->head = zp->next; +++ } +++ else +++ { +++ zp = zc_pool_ent_alloc(pool, numbytes); +++ } +++ +++ pthread_mutex_unlock(&pool->lock); +++ +++ // Start with our buffer empty of preconceptions +++// rpi_cache_flush_one_gm_ptr(&zp->gmem, RPI_CACHE_FLUSH_MODE_INVALIDATE); +++ +++ return zp; +++} +++ +++static void zc_pool_free(ZcPoolEnt * const zp) +++{ +++ ZcPool * const pool = zp == NULL ? NULL : zp->pool; +++ if (zp != NULL) +++ { +++ pthread_mutex_lock(&pool->lock); +++#if TRACE_ALLOC +++ printf("%s: Recycle %#x, %#x\n", __func__, pool->numbytes, zp->gmem.numbytes); +++#endif +++ +++ if (pool->numbytes == zp->gmem.numbytes) +++ { +++ zp->next = pool->head; +++ pool->head = zp; +++ pthread_mutex_unlock(&pool->lock); +++ } +++ else +++ { +++ pthread_mutex_unlock(&pool->lock); +++ zc_pool_ent_free(zp); +++ } +++ } +++} +++ +++static void +++zc_pool_init(ZcPool * const pool) +++{ +++ pool->numbytes = -1; +++ pool->head = NULL; +++ pthread_mutex_init(&pool->lock, NULL); +++} +++ +++static void +++zc_pool_destroy(ZcPool * const pool) +++{ +++ pool->numbytes = -1; +++ zc_pool_flush(pool); +++ pthread_mutex_destroy(&pool->lock); +++} +++ +++typedef struct ZcOldCtxVals +++{ +++ int thread_safe_callbacks; +++ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); +++ void * get_buffer_context; +++} ZcOldCtxVals; +++ +++typedef struct AVZcEnv +++{ +++ unsigned int refcount; +++ ZcPool pool; +++ ZcOldCtxVals old; +++} ZcEnv; +++ +++// Callback when buffer unrefed to zero +++static void rpi_free_display_buffer(void *opaque, uint8_t *data) +++{ +++ ZcPoolEnt *const zp = opaque; +++// printf("%s: data=%p\n", __func__, data); +++ zc_pool_free(zp); +++} +++ +++static inline GPU_MEM_PTR_T * pic_gm_ptr(AVBufferRef * const buf) +++{ +++ // Kludge where we check the free fn to check this is really +++ // one of our buffers - can't think of a better way +++ return buf == NULL || buf->buffer->free != rpi_free_display_buffer ? NULL : +++ av_buffer_get_opaque(buf); +++} +++ +++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( +++ const int format, const unsigned int video_width, const unsigned int video_height) +++{ +++ AVRpiZcFrameGeometry geo; +++ +++ switch (format) +++ { +++ case AV_PIX_FMT_YUV420P: +++ geo.stride_y = ((video_width + 32 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; +++ geo.stride_c = geo.stride_y / 2; +++ geo.height_y = (video_height + 32 + 31) & ~31; +++ geo.height_c = geo.height_y / 2; +++ geo.planes_c = 2; +++ geo.stripes = 1; +++ geo.bytes_per_pel = 1; +++ geo.stripe_is_yc = 1; +++ break; +++ +++ case AV_PIX_FMT_YUV420P10: +++ geo.stride_y = ((video_width * 2 + 64 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; +++ geo.stride_c = geo.stride_y / 2; +++ geo.height_y = (video_height + 32 + 31) & ~31; +++ geo.height_c = geo.height_y / 2; +++ geo.planes_c = 2; +++ geo.stripes = 1; +++ geo.bytes_per_pel = 2; +++ geo.stripe_is_yc = 1; +++ break; +++ +++ case AV_PIX_FMT_SAND128: +++ case AV_PIX_FMT_RPI4_8: +++ { +++ const unsigned int stripe_w = 128; +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV_UV, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.stripe_is_yc = 1; +++ if (geo.height_y * stripe_w > img.pitch) +++ { +++ // "tall" sand - all C blocks now follow Y +++ geo.height_y = img.pitch / stripe_w; +++ geo.height_c = geo.height_y; +++ geo.stripe_is_yc = 0; +++ } +++ geo.planes_c = 1; +++ geo.stripes = (video_width + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++#if 0 +++ printf("Req: %dx%d: stride=%d/%d, height=%d/%d, stripes=%d, img.pitch=%d\n", +++ video_width, video_height, +++ geo.stride_y, geo.stride_c, +++ geo.height_y, geo.height_c, +++ geo.stripes, img.pitch); +++#endif +++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); +++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); +++ break; +++ } +++ +++ case AV_PIX_FMT_RPI4_10: +++ { +++ const unsigned int stripe_w = 128; // bytes +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV10COL, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.planes_c = 1; +++ geo.stripes = ((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 1; +++ geo.stripe_is_yc = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++ +++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); +++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); +++ break; +++ } +++ +++ case AV_PIX_FMT_SAND64_16: +++ case AV_PIX_FMT_SAND64_10: +++ { +++ const unsigned int stripe_w = 128; // bytes +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV_UV_16, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.planes_c = 1; +++ geo.stripes = (video_width * 2 + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 2; +++ geo.stripe_is_yc = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++ break; +++ } +++ +++ default: +++ memset(&geo, 0, sizeof(geo)); +++ break; +++ } +++ return geo; +++} +++ +++ +++static AVBufferRef * rpi_buf_pool_alloc(ZcPool * const pool, int size) +++{ +++ ZcPoolEnt *const zp = zc_pool_alloc(pool, size); +++ AVBufferRef * buf; +++ intptr_t idata = (intptr_t)zp->gmem.arm; +++#if ALLOC_N_OFFSET != 0 +++ intptr_t noff = (zp->n * ALLOC_N_OFFSET) & (ALLOC_PAD - 1); +++#endif +++ +++ if (zp == NULL) { +++ av_log(NULL, AV_LOG_ERROR, "zc_pool_alloc(%d) failed\n", size); +++ goto fail0; +++ } +++ +++#if ALLOC_N_OFFSET != 0 +++ idata = ((idata & ~(ALLOC_PAD - 1)) | noff) + (((idata & (ALLOC_PAD - 1)) > noff) ? ALLOC_PAD : 0); +++#endif +++ +++#if DEBUG_ZAP0_BUFFERS +++ memset((void*)idata, 0, size); +++#endif +++ +++ if ((buf = av_buffer_create((void *)idata, size, rpi_free_display_buffer, zp, AV_BUFFER_FLAG_READONLY)) == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_buffer_create() failed\n"); +++ goto fail2; +++ } +++ +++ return buf; +++ +++fail2: +++ zc_pool_free(zp); +++fail0: +++ return NULL; +++} +++ +++static int rpi_get_display_buffer(ZcEnv *const zc, AVFrame * const frame) +++{ +++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(frame->format, frame->width, frame->height); +++ const unsigned int size_y = geo.stride_y * geo.height_y; +++ const unsigned int size_c = geo.stride_c * geo.height_c; +++ const unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes; +++ AVBufferRef * buf; +++ unsigned int i; +++ +++// printf("Do local alloc: format=%#x, %dx%d: %u\n", frame->format, frame->width, frame->height, size_pic); +++ +++ if ((buf = rpi_buf_pool_alloc(&zc->pool, size_pic)) == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "rpi_get_display_buffer: Failed to get buffer from pool\n"); +++ return AVERROR(ENOMEM); +++ } +++ +++ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { +++ frame->buf[i] = NULL; +++ frame->data[i] = NULL; +++ frame->linesize[i] = 0; +++ } +++ +++ frame->buf[0] = buf; +++ +++ frame->linesize[0] = geo.stride_y; +++ frame->linesize[1] = geo.stride_c; +++ frame->linesize[2] = geo.stride_c; +++ // abuse: linesize[3] = "stripe stride" +++ // stripe_stride is NOT the stride between slices it is (that / geo.stride_y). +++ // In a general case this makes the calculation an xor and multiply rather +++ // than a divide and multiply +++ if (geo.stripes > 1) +++ frame->linesize[3] = geo.stripe_is_yc ? geo.height_y + geo.height_c : geo.height_y; +++ +++ frame->data[0] = buf->data; +++ frame->data[1] = frame->data[0] + (geo.stripe_is_yc ? size_y : size_y * geo.stripes); +++ if (geo.planes_c > 1) +++ frame->data[2] = frame->data[1] + size_c; +++ +++ frame->extended_data = frame->data; +++ // Leave extended buf alone +++ +++#if RPI_ZC_SAND_8_IN_10_BUF != 0 +++ // *** If we intend to use this for real we will want a 2nd buffer pool +++ frame->buf[RPI_ZC_SAND_8_IN_10_BUF] = rpi_buf_pool_alloc(&zc->pool, size_pic); // *** 2 * wanted size - kludge +++#endif +++ +++ return 0; +++} +++ +++#define RPI_GET_BUFFER2 1 +++ +++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags) +++{ +++#if !RPI_GET_BUFFER2 +++ return avcodec_default_get_buffer2(s, frame, flags); +++#else +++ int rv; +++ +++ if ((s->codec->capabilities & AV_CODEC_CAP_DR1) == 0) +++ { +++// printf("Do default alloc: format=%#x\n", frame->format); +++ rv = avcodec_default_get_buffer2(s, frame, flags); +++ } +++ else if (frame->format == AV_PIX_FMT_YUV420P || +++ av_rpi_is_sand_frame(frame)) +++ { +++ rv = rpi_get_display_buffer(s->get_buffer_context, frame); +++ } +++ else +++ { +++ rv = avcodec_default_get_buffer2(s, frame, flags); +++ } +++ +++#if 0 +++ printf("%s: fmt:%d, %dx%d lsize=%d/%d/%d/%d data=%p/%p/%p bref=%p/%p/%p opaque[0]=%p\n", __func__, +++ frame->format, frame->width, frame->height, +++ frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3], +++ frame->data[0], frame->data[1], frame->data[2], +++ frame->buf[0], frame->buf[1], frame->buf[2], +++ av_buffer_get_opaque(frame->buf[0])); +++#endif +++ return rv; +++#endif +++} +++ +++ +++static AVBufferRef * zc_copy(struct AVCodecContext * const s, +++ const AVFrame * const src) +++{ +++ AVFrame dest_frame; +++ AVFrame * const dest = &dest_frame; +++ unsigned int i; +++ uint8_t * psrc, * pdest; +++ +++ dest->format = src->format; +++ dest->width = src->width; +++ dest->height = src->height; +++ +++ if (rpi_get_display_buffer(s->get_buffer_context, dest) != 0) +++ { +++ return NULL; +++ } +++ +++ for (i = 0, psrc = src->data[0], pdest = dest->data[0]; +++ i != dest->height; +++ ++i, psrc += src->linesize[0], pdest += dest->linesize[0]) +++ { +++ memcpy(pdest, psrc, dest->width); +++ } +++ for (i = 0, psrc = src->data[1], pdest = dest->data[1]; +++ i != dest->height / 2; +++ ++i, psrc += src->linesize[1], pdest += dest->linesize[1]) +++ { +++ memcpy(pdest, psrc, dest->width / 2); +++ } +++ for (i = 0, psrc = src->data[2], pdest = dest->data[2]; +++ i != dest->height / 2; +++ ++i, psrc += src->linesize[2], pdest += dest->linesize[2]) +++ { +++ memcpy(pdest, psrc, dest->width / 2); +++ } +++ +++ return dest->buf[0]; +++} +++ +++ +++static AVBufferRef * zc_420p10_to_sand128(struct AVCodecContext * const s, +++ const AVFrame * const src) +++{ +++ assert(0); +++ return NULL; +++} +++ +++ +++static AVBufferRef * zc_sand64_16_to_sand128(struct AVCodecContext * const s, +++ const AVFrame * const src, const unsigned int src_bits) +++{ +++ assert(0); +++ return NULL; +++} +++ +++ +++ +++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, +++ const AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy) +++{ +++ assert(s != NULL); +++ +++ if (frame->format != AV_PIX_FMT_YUV420P && +++ frame->format != AV_PIX_FMT_YUV420P10 && +++ !av_rpi_is_sand_frame(frame)) +++ { +++ av_log(s, AV_LOG_WARNING, "%s: *** Format not SAND/YUV420P: %d\n", __func__, frame->format); +++ return NULL; +++ } +++ +++ if (frame->buf[1] != NULL || frame->format != expected_format) +++ { +++#if RPI_ZC_SAND_8_IN_10_BUF +++ if (frame->format == AV_PIX_FMT_SAND64_10 && expected_format == AV_PIX_FMT_SAND128 && frame->buf[RPI_ZC_SAND_8_IN_10_BUF] != NULL) +++ { +++// av_log(s, AV_LOG_INFO, "%s: --- found buf[4]\n", __func__); +++ return av_buffer_ref(frame->buf[RPI_ZC_SAND_8_IN_10_BUF]); +++ } +++#endif +++ +++ if (maycopy) +++ { +++ if (frame->buf[1] != NULL) +++ av_log(s, AV_LOG_INFO, "%s: *** Not a single buf frame: copying\n", __func__); +++ else +++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format %d: copying to %d\n", __func__, frame->format, expected_format); +++ +++ switch (frame->format) +++ { +++ case AV_PIX_FMT_YUV420P10: +++ return zc_420p10_to_sand128(s, frame); +++ +++ case AV_PIX_FMT_SAND64_10: +++ return zc_sand64_16_to_sand128(s, frame, 10); +++ +++ default: +++ return zc_copy(s, frame); +++ } +++ } +++ else +++ { +++ if (frame->buf[1] != NULL) +++ av_log(s, AV_LOG_WARNING, "%s: *** Not a single buf frame: buf[1] != NULL\n", __func__); +++ else +++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format: %d != %d\n", __func__, frame->format, expected_format); +++ return NULL; +++ } +++ } +++ +++ if (pic_gm_ptr(frame->buf[0]) == NULL) +++ { +++ if (maycopy) +++ { +++ av_log(s, AV_LOG_INFO, "%s: *** Not one of our buffers: copying\n", __func__); +++ return zc_copy(s, frame); +++ } +++ else +++ { +++ av_log(s, AV_LOG_WARNING, "%s: *** Not one of our buffers: NULL\n", __func__); +++ return NULL; +++ } +++ } +++ +++ return av_buffer_ref(frame->buf[0]); +++} +++ +++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? -1 : p->vc_handle; +++} +++ +++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? 0 : fr_ref->data - p->arm; +++} +++ +++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref) +++{ +++ return fr_ref == NULL ? 0 : fr_ref->size; +++} +++ +++ +++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? 0 : p->numbytes; +++} +++ +++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref) +++{ +++ if (fr_ref != NULL) +++ { +++ av_buffer_unref(&fr_ref); +++ } +++} +++ +++AVZcEnvPtr av_rpi_zc_env_alloc(void) +++{ +++ ZcEnv * const zc = av_mallocz(sizeof(ZcEnv)); +++ if (zc == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_rpi_zc_env_alloc: Context allocation failed\n"); +++ return NULL; +++ } +++ +++ zc_pool_init(&zc->pool); +++ return zc; +++} +++ +++void av_rpi_zc_env_free(AVZcEnvPtr zc) +++{ +++ if (zc != NULL) +++ { +++ zc_pool_destroy(&zc->pool); ; +++ av_free(zc); +++ } +++} +++ +++int av_rpi_zc_in_use(const struct AVCodecContext * const s) +++{ +++ return s->get_buffer2 == av_rpi_zc_get_buffer2; +++} +++ +++int av_rpi_zc_init(struct AVCodecContext * const s) +++{ +++ if (av_rpi_zc_in_use(s)) +++ { +++ ZcEnv * const zc = s->get_buffer_context; +++ ++zc->refcount; +++ } +++ else +++ { +++ ZcEnv *const zc = av_rpi_zc_env_alloc(); +++ if (zc == NULL) +++ { +++ return AVERROR(ENOMEM); +++ } +++ +++ zc->refcount = 1; +++ zc->old.get_buffer_context = s->get_buffer_context; +++ zc->old.get_buffer2 = s->get_buffer2; +++ zc->old.thread_safe_callbacks = s->thread_safe_callbacks; +++ +++ s->get_buffer_context = zc; +++ s->get_buffer2 = av_rpi_zc_get_buffer2; +++ s->thread_safe_callbacks = 1; +++ } +++ return 0; +++} +++ +++void av_rpi_zc_uninit(struct AVCodecContext * const s) +++{ +++ if (av_rpi_zc_in_use(s)) +++ { +++ ZcEnv * const zc = s->get_buffer_context; +++ if (--zc->refcount == 0) +++ { +++ s->get_buffer2 = zc->old.get_buffer2; +++ s->get_buffer_context = zc->old.get_buffer_context; +++ s->thread_safe_callbacks = zc->old.thread_safe_callbacks; +++ av_rpi_zc_env_free(zc); +++ } +++ } +++} +++ +++#endif // RPI +++ ++diff --git a/libavcodec/rpi_zc.h b/libavcodec/rpi_zc.h ++new file mode 100644 ++index 0000000000..0e39b8e3b3 ++--- /dev/null +++++ b/libavcodec/rpi_zc.h ++@@ -0,0 +1,106 @@ +++#ifndef LIBAVCODEC_RPI_ZC_H +++#define LIBAVCODEC_RPI_ZC_H +++ +++// Zero-Copy frame code for RPi +++// RPi needs Y/U/V planes to be contiguous for display. By default +++// ffmpeg will allocate separated planes so a memcpy is needed before +++// display. This code provides a method a making ffmpeg allocate a single +++// bit of memory for the frame when can then be reference counted until +++// display has finished with it. +++ +++// Frame buffer number in which to stuff an 8-bit copy of a 16-bit frame +++// 0 disables +++// *** This option still in development +++// Only works if SAO active +++// Allocates buffers that are twice the required size +++#define RPI_ZC_SAND_8_IN_10_BUF 0 +++ +++struct AVBufferRef; +++struct AVFrame; +++struct AVCodecContext; +++enum AVPixelFormat; +++ +++// "Opaque" pointer to whatever we are using as a buffer reference +++typedef struct AVBufferRef * AVRpiZcRefPtr; +++ +++struct AVZcEnv; +++typedef struct AVZcEnv * AVZcEnvPtr; +++ +++typedef struct AVRpiZcFrameGeometry +++{ +++ unsigned int stride_y; // Luma stride (bytes) +++ unsigned int height_y; // Luma height (lines) +++ unsigned int stride_c; // Chroma stride (bytes) +++ unsigned int height_c; // Chroma stride (lines) +++ unsigned int planes_c; // Chroma plane count (U, V = 2, interleaved = 1) +++ unsigned int stripes; // Number of stripes (sand) +++ unsigned int bytes_per_pel; +++ int stripe_is_yc; // A single stripe is Y then C (false for tall sand) +++} AVRpiZcFrameGeometry; +++ +++ +++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( +++ const int format, +++ const unsigned int video_width, const unsigned int video_height); +++ +++// Replacement fn for avctx->get_buffer2 +++// Should be set before calling avcodec_decode_open2 +++// +++// N.B. in addition to to setting avctx->get_buffer2, avctx->refcounted_frames +++// must be set to 1 as otherwise the buffer info is killed before being returned +++// by avcodec_decode_video2. Note also that this means that the AVFrame that is +++// returned must be manually derefed with av_frame_unref. This should be done +++// after av_rpi_zc_ref has been called. +++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags); +++ +++// Generate a ZC reference to the buffer(s) in this frame +++// If the buffer doesn't appear to be one allocated by _get_buffer_2 +++// then the behaviour depends on maycopy: +++// If maycopy=0 then return NULL +++// If maycopy=1 && the src frame is in a form where we can easily copy +++// the data, then allocate a new buffer and copy the data into it +++// Otherwise return NULL +++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, +++ const struct AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy); +++ +++// Get the vc_handle from the frame ref +++// Returns -1 if ref doesn't look valid +++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref); +++// Get offset from the start of the memory referenced +++// by the vc_handle to valid data +++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref); +++// Length of buffer data +++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref); +++// Get the number of bytes allocated from the frame ref +++// Returns 0 if ref doesn't look valid +++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref); +++ +++// Unreference the buffer refed/allocated by _zc_ref +++// If fr_ref is NULL then this will NOP +++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref); +++ +++// Allocate an environment for the buffer pool used by the ZC code +++// This should be put in avctx->get_buffer_context so it can be found by +++// av_rpi_zc_get_buffer2 when it is called from ffmpeg +++AVZcEnvPtr av_rpi_zc_env_alloc(void); +++ +++// Allocate the environment used by the ZC code +++void av_rpi_zc_env_free(AVZcEnvPtr); +++ +++// Test to see if the context is using zc (checks get_buffer2) +++int av_rpi_zc_in_use(const struct AVCodecContext * const s); +++ +++// Init ZC into a context +++// There is nothing magic in this fn - it just packages setting +++// get_buffer2 & get_buffer_context +++int av_rpi_zc_init(struct AVCodecContext * const s); +++ +++// Free ZC from a context +++// There is nothing magic in this fn - it just packages unsetting +++// get_buffer2 & get_buffer_context +++void av_rpi_zc_uninit(struct AVCodecContext * const s); +++ +++ +++ +++#endif +++ ++diff --git a/libavutil/buffer.c b/libavutil/buffer.c ++index 8d1aa5fa84..649876db77 100644 ++--- a/libavutil/buffer.c +++++ b/libavutil/buffer.c ++@@ -355,3 +355,9 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) ++ ++ return ret; ++ } +++ +++// Return the opaque for the underlying frame (gives us a GPU_MEM_PTR_T) +++void *av_buffer_pool_opaque(AVBufferRef *ref) { +++ BufferPoolEntry *buf = av_buffer_get_opaque(ref); +++ return buf->opaque; +++} ++diff --git a/libavutil/buffer.h b/libavutil/buffer.h ++index 73b6bd0b14..d907de3f1c 100644 ++--- a/libavutil/buffer.h +++++ b/libavutil/buffer.h ++@@ -284,6 +284,9 @@ void av_buffer_pool_uninit(AVBufferPool **pool); ++ */ ++ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); ++ +++// Return the opaque for the underlying frame +++void *av_buffer_pool_opaque(AVBufferRef *ref); +++ ++ /** ++ * @} ++ */ ++diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c ++index 8ed52751c1..5e2b5ec3bc 100644 ++--- a/libavutil/pixdesc.c +++++ b/libavutil/pixdesc.c ++@@ -1989,6 +1989,18 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { ++ .name = "cuda", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, +++ [AV_PIX_FMT_RPI] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, +++ [AV_PIX_FMT_RPI4_10] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, +++ [AV_PIX_FMT_RPI4_8] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, ++ [AV_PIX_FMT_AYUV64LE] = { ++ .name = "ayuv64le", ++ .nb_components = 4, ++diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h ++index 34a1531489..0a6ff1f482 100644 ++--- a/libavutil/pixfmt.h +++++ b/libavutil/pixfmt.h ++@@ -234,6 +234,11 @@ enum AVPixelFormat { ++ */ ++ AV_PIX_FMT_CUDA, ++ +++ /** +++ * HW acceleration through RPI. +++ */ +++ AV_PIX_FMT_RPI, +++ ++ 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 ++@@ -334,6 +339,14 @@ enum AVPixelFormat { ++ */ ++ AV_PIX_FMT_OPENCL, ++ +++// RPI - not on ifdef so can be got at by calling progs +++ AV_PIX_FMT_SAND128, ///< 4:2:0 8-bit 128x*Y stripe, 64x*UV stripe, then next x stripe, mysterious padding +++ AV_PIX_FMT_SAND64_10, ///< 4:2:0 10-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding +++ AV_PIX_FMT_SAND64_16, ///< 4:2:0 16-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding +++ +++ AV_PIX_FMT_RPI4_8, +++ AV_PIX_FMT_RPI4_10, +++ ++ 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 ++ }; ++ ++diff --git a/pi-util/conf_pi1.sh b/pi-util/conf_pi1.sh ++new file mode 100755 ++index 0000000000..ec25b81c31 ++--- /dev/null +++++ b/pi-util/conf_pi1.sh ++@@ -0,0 +1,31 @@ +++echo "Configure for Pi1" +++ +++RPI_TOOLROOT=`pwd`/../tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf +++RPI_OPT_VC=`pwd`/../firmware/opt/vc +++ +++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" +++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI=1" +++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" +++#RPI_KEEPS="-save-temps=obj" +++RPI_KEEPS="" +++ +++./configure --enable-cross-compile\ +++ --cpu=arm1176jzf-s\ +++ --arch=arm\ +++ --disable-neon\ +++ --target-os=linux\ +++ --disable-stripping\ +++ --enable-mmal\ +++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ +++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ +++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ +++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ +++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- +++ +++ +++# --enable-extra-warnings\ +++# --arch=armv71\ +++# --enable-shared\ +++ +++# gcc option for getting asm listing +++# -Wa,-ahls ++diff --git a/pi-util/conf_pi2.sh b/pi-util/conf_pi2.sh ++new file mode 100755 ++index 0000000000..7ec0402ce8 ++--- /dev/null +++++ b/pi-util/conf_pi2.sh ++@@ -0,0 +1,34 @@ +++echo "Configure for Pi2/3" +++ +++RPI_TOOLROOT=/home/dom/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf +++RPI_OPT_VC=/opt/bcm-rootfs/opt/vc +++ +++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" +++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI_DISPLAY=1" +++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" +++#RPI_KEEPS="-save-temps=obj" +++RPI_KEEPS="" +++ +++./configure --enable-cross-compile\ +++ --arch=armv6t2\ +++ --cpu=cortex-a7\ +++ --target-os=linux\ +++ --disable-stripping\ +++ --disable-thumb\ +++ --enable-mmal\ +++ --enable-rpi\ +++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ +++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ +++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ +++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ +++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- \ +++ --prefix=$HOME/buster/home/pi/projects/fpga \ +++ --extra-libs="-ldl" +++ +++# --disable-decoders --enable-decoder=hevc --disable-hwaccels --enable-hwaccel=hevc_rpi --disable-encoders --enable-encoder=rawvideo --enable-muxer=rawvideo \ +++# --enable-extra-warnings\ +++# --arch=armv71\ +++# --enable-shared\ +++ +++# gcc option for getting asm listing +++# -Wa,-ahls +-- +2.20.1 + + +From b6633c36d3855a81d32dbf0dd68358267d0e7c2c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 26 Jun 2017 20:17:09 +0100 +Subject: [PATCH 03/14] MMAL: Add hevc support by allowing 4 planes + +--- + xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp | 3 +++ + xbmc/cores/VideoPlayer/Process/VideoBuffer.h | 2 +- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 3 +++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 2cf3575ca9..854f34fa62 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -77,6 +77,8 @@ void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES]) + strides[0] = geo.getStrideY(); + strides[1] = geo.getStrideC(); + strides[2] = geo.getStrideC(); ++ if (geo.getStripes() > 1) ++ strides[3] = geo.getHeightY() + geo.getHeightC(); // abuse: strides[3] = stripe stride + } + + void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) +@@ -284,6 +286,7 @@ CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) + if (frame) + { + if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 && ++ frame->format != AV_PIX_FMT_SAND128 && frame->format != AV_PIX_FMT_SAND64_10 && frame->format != AV_PIX_FMT_SAND64_16 && + frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || + frame->buf[1] != nullptr || frame->buf[0] == nullptr) + { +diff --git a/xbmc/cores/VideoPlayer/Process/VideoBuffer.h b/xbmc/cores/VideoPlayer/Process/VideoBuffer.h +index 1c1ba21c48..86a71bb558 100644 +--- a/xbmc/cores/VideoPlayer/Process/VideoBuffer.h ++++ b/xbmc/cores/VideoPlayer/Process/VideoBuffer.h +@@ -23,7 +23,7 @@ extern "C" { + + struct YuvImage + { +- static const int MAX_PLANES = 3; ++ static const int MAX_PLANES = 4; + + uint8_t* plane[MAX_PLANES]; + int planesize[MAX_PLANES]; +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index aa5b0e06c0..fae5df73e2 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -193,6 +193,9 @@ std::vector CMMALPool::mmal_encoding_table = + { AV_PIX_FMT_YUV420P12,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, }, ++ { AV_PIX_FMT_SAND128, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_SAND64_10,MMAL_ENCODING_YUVUV64_16 }, ++ { AV_PIX_FMT_SAND64_16,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, }, + { AV_PIX_FMT_BGRA, MMAL_ENCODING_BGRA }, + { AV_PIX_FMT_RGB0, MMAL_ENCODING_RGBA }, +-- +2.20.1 + + +From 0f8645a751d04e657a82a66d42a0c56205097466 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:52:34 +0100 +Subject: [PATCH 04/14] RPI: Apply ffmpeg patches through cmake + +--- + cmake/modules/FindFFMPEG.cmake | 5 ++++- + tools/depends/target/ffmpeg/CMakeLists.txt | 5 +++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake +index ef74671d40..a6e5de5917 100644 +--- a/cmake/modules/FindFFMPEG.cmake ++++ b/cmake/modules/FindFFMPEG.cmake +@@ -270,7 +270,10 @@ if(NOT FFMPEG_FOUND) + && + ${CMAKE_COMMAND} -E copy + ${CMAKE_SOURCE_DIR}/tools/depends/target/ffmpeg/FindGnuTls.cmake +- ) ++ && ++ patch -p1 < ${CMAKE_SOURCE_DIR}/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch ++ ) ++ + + find_program(BASH_COMMAND bash) + if(NOT BASH_COMMAND) +diff --git a/tools/depends/target/ffmpeg/CMakeLists.txt b/tools/depends/target/ffmpeg/CMakeLists.txt +index 4a2622216c..3afb989dcf 100644 +--- a/tools/depends/target/ffmpeg/CMakeLists.txt ++++ b/tools/depends/target/ffmpeg/CMakeLists.txt +@@ -18,6 +18,11 @@ if(CROSSCOMPILING) + message(STATUS "CROSS: ${ffmpeg_conf}") + endif() + ++#if(CORE_PLATFORM_NAME STREQUAL rbpi) ++ string(CONCAT CMAKE_C_FLAGS ${CMAKE_C_FLAGS} " -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux") ++ list(APPEND ffmpeg_conf --enable-rpi --disable-ffmpeg --disable-ffprobe) ++#endif() ++ + if(CMAKE_C_FLAGS) + list(APPEND ffmpeg_conf --extra-cflags=${CMAKE_C_FLAGS}) + endif() +-- +2.20.1 + + +From a9a7f16a39db1fcab3c47df6024fb6c98c314063 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 29 Apr 2019 20:52:03 +0100 +Subject: [PATCH 05/14] HACK: add videoplayer.usemmal setting to gbm.xml + +This reverts commit 2c94f63f62a124ed4024f01c3dafcf8f6dfebda0. +--- + system/settings/gbm.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index c5e4d98e0b..2335b5843e 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -9,6 +9,11 @@ + + + ++ ++ 2 ++ true ++ ++ + + false + 2 +-- +2.20.1 + + +From cc4e38058d7d1afacfb8febd59ea68ae01c18d3f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 25 Apr 2019 17:14:32 +0100 +Subject: [PATCH 06/14] gbm: Expose videoplayer.usedisplayasclock + +--- + system/settings/gbm.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index 2335b5843e..dffea009fe 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -4,7 +4,7 @@ + + + +- false ++ true + false + + +-- +2.20.1 + + +From 18e97485734156146bc796bde8f0b82c0550d554 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 24 Mar 2019 11:07:25 +0100 +Subject: [PATCH 07/14] HACK: try to use MMAL with gbm + +Signed-off-by: Matthias Reichl +--- + cmake/platform/linux/gbm.cmake | 2 +- + xbmc/SystemGlobals.cpp | 4 -- + .../VideoRenderers/HwDecRender/MMALRenderer.h | 1 + + xbmc/platform/linux/CMakeLists.txt | 3 + + xbmc/platform/linux/RBP.cpp | 18 ++++++ + xbmc/platform/linux/RBP.h | 10 +++ + xbmc/windowing/gbm/CMakeLists.txt | 2 + + xbmc/windowing/gbm/VideoSyncPi.cpp | 62 +++++++++++++++++++ + xbmc/windowing/gbm/VideoSyncPi.h | 27 ++++++++ + .../windowing/gbm/WinSystemGbmGLESContext.cpp | 42 +++++++------ + xbmc/windowing/gbm/WinSystemGbmGLESContext.h | 3 +- + 11 files changed, 148 insertions(+), 26 deletions(-) + create mode 100644 xbmc/windowing/gbm/VideoSyncPi.cpp + create mode 100644 xbmc/windowing/gbm/VideoSyncPi.h + +diff --git a/cmake/platform/linux/gbm.cmake b/cmake/platform/linux/gbm.cmake +index e5b44ada46..b25ea7b0eb 100644 +--- a/cmake/platform/linux/gbm.cmake ++++ b/cmake/platform/linux/gbm.cmake +@@ -1,4 +1,4 @@ +-set(PLATFORM_REQUIRED_DEPS EGL GBM LibDRM LibInput Xkbcommon) ++set(PLATFORM_REQUIRED_DEPS EGL GBM LibDRM LibInput Xkbcommon MMAL) + set(PLATFORM_OPTIONAL_DEPS VAAPI) + + set(GBM_RENDER_SYSTEM "" CACHE STRING "Render system to use with GBM: \"gl\" or \"gles\"") +diff --git a/xbmc/SystemGlobals.cpp b/xbmc/SystemGlobals.cpp +index 435b1f5090..df1ae2cced 100644 +--- a/xbmc/SystemGlobals.cpp ++++ b/xbmc/SystemGlobals.cpp +@@ -24,9 +24,7 @@ std::map CSpecialProtocol::m_pathMap; + + #include "filesystem/ZipManager.h" + +-#ifdef TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" +-#endif + + CLangCodeExpander g_LangCodeExpander; + CLocalizeStrings g_localizeStrings; +@@ -42,8 +40,6 @@ std::map CSpecialProtocol::m_pathMap; + CAlarmClock g_alarmClock; + CSectionLoader g_sectionLoader; + +-#ifdef TARGET_RASPBERRY_PI + CRBP g_RBP; +-#endif + + CZipManager g_ZipManager; +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +index 9718fb056d..03042edfb1 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +@@ -21,6 +21,7 @@ + #include "threads/Thread.h" + #include "threads/IRunnable.h" + #include "utils/Geometry.h" ++#include "platform/linux/RBP.h" + + // worst case number of buffers. 12 for decoder. 8 for multi-threading in ffmpeg. NUM_BUFFERS for renderer. + // Note, generally these won't necessarily result in allocated pictures +diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt +index f3d9b535bc..88076c3d5a 100644 +--- a/xbmc/platform/linux/CMakeLists.txt ++++ b/xbmc/platform/linux/CMakeLists.txt +@@ -48,6 +48,9 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + DllOMX.h + OMXClock.h + OMXCore.h) ++else() ++ list(APPEND SOURCES RBP.cpp) ++ list(APPEND HEADERS RBP.h) + endif() + + if(HAVE_SSE4_1) +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 9558e80afa..e7b11a5f73 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -14,7 +14,9 @@ + #include "settings/SettingsComponent.h" + #include "utils/log.h" + ++#ifdef TARGET_RASPBERRY_PI + #include "cores/omxplayer/OMXImage.h" ++#endif + #include + + #include +@@ -66,9 +68,13 @@ typedef int vc_image_t_size_check[(sizeof(VC_IMAGE_T) == 64) * 2 - 1]; + CRBP::CRBP() + { + m_initialized = false; ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; ++#endif + m_DllBcmHost = new DllBcmHost(); ++#ifdef TARGET_RASPBERRY_PI + m_OMX = new COMXCore(); ++#endif + m_display = DISPMANX_NO_HANDLE; + m_mb = mbox_open(); + vcsm_init(); +@@ -79,7 +85,9 @@ CRBP::CRBP() + CRBP::~CRBP() + { + Deinitialize(); ++#ifdef TARGET_RASPBERRY_PI + delete m_OMX; ++#endif + delete m_DllBcmHost; + } + +@@ -95,9 +103,11 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) + return false; ++#endif + + char response[80] = ""; + m_arm_mem = 0; +@@ -122,8 +132,10 @@ bool CRBP::Initialize() + if (!m_gui_resolution_limit) + m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080; + ++#ifdef TARGET_RASPBERRY_PI + g_OMXImage.Initialize(); + m_omx_image_init = true; ++#endif + return true; + } + +@@ -264,20 +276,26 @@ uint32_t CRBP::LastVsync() + + void CRBP::Deinitialize() + { ++#ifdef TARGET_RASPBERRY_PI + if (m_omx_image_init) + g_OMXImage.Deinitialize(); + + if(m_omx_initialized) + m_OMX->Deinitialize(); ++#endif + + m_DllBcmHost->bcm_host_deinit(); + + if(m_initialized) + m_DllBcmHost->Unload(); + ++#ifdef TARGET_RASPBERRY_PI + m_omx_image_init = false; ++#endif + m_initialized = false; ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; ++#endif + if (m_mb) + mbox_close(m_mb); + m_mb = 0; +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index aaddd14591..c4741fd60f 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -19,7 +19,9 @@ + #endif + + #include "DllBCM.h" ++#ifdef TARGET_RASPBERRY_PI + #include "OMXCore.h" ++#endif + #include "xbmc/utils/CPUInfo.h" + #include "threads/CriticalSection.h" + #include "threads/Event.h" +@@ -91,7 +93,9 @@ public: + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); ++#ifdef TARGET_RASPBERRY_PI + DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } ++#endif + uint32_t LastVsync(int64_t &time); + uint32_t LastVsync(); + uint32_t WaitVsync(uint32_t target = ~0U); +@@ -102,20 +106,26 @@ public: + private: + DllBcmHost *m_DllBcmHost; + bool m_initialized; ++#ifdef TARGET_RASPBERRY_PI + bool m_omx_initialized; + bool m_omx_image_init; ++#endif + int m_arm_mem; + int m_gpu_mem; + int m_gui_resolution_limit; + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; ++#ifdef TARGET_RASPBERRY_PI + COMXCore *m_OMX; ++#endif + DISPMANX_DISPLAY_HANDLE_T m_display; + CCriticalSection m_vsync_lock; + XbmcThreads::ConditionVariable m_vsync_cond; + uint32_t m_vsync_count; + int64_t m_vsync_time; ++#ifdef TARGET_RASPBERRY_PI + class DllLibOMXCore; ++#endif + CCriticalSection m_critSection; + + int m_mb; +diff --git a/xbmc/windowing/gbm/CMakeLists.txt b/xbmc/windowing/gbm/CMakeLists.txt +index 78c788c158..c3377e9a52 100644 +--- a/xbmc/windowing/gbm/CMakeLists.txt ++++ b/xbmc/windowing/gbm/CMakeLists.txt +@@ -1,5 +1,6 @@ + set(SOURCES OptionalsReg.cpp + WinSystemGbm.cpp ++ VideoSyncPi.cpp + GBMUtils.cpp + DRMUtils.cpp + DRMLegacy.cpp +@@ -9,6 +10,7 @@ set(SOURCES OptionalsReg.cpp + + set(HEADERS OptionalsReg.h + WinSystemGbm.h ++ VideoSyncPi.h + GBMUtils.h + DRMUtils.h + DRMLegacy.h +diff --git a/xbmc/windowing/gbm/VideoSyncPi.cpp b/xbmc/windowing/gbm/VideoSyncPi.cpp +new file mode 100644 +index 0000000000..fd12528011 +--- /dev/null ++++ b/xbmc/windowing/gbm/VideoSyncPi.cpp +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2005-2018 Team Kodi ++ * This file is part of Kodi - https://kodi.tv ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * See LICENSES/README.md for more information. ++ */ ++ ++#include "VideoSyncPi.h" ++#include "ServiceBroker.h" ++#include "windowing/GraphicContext.h" ++#include "windowing/WinSystem.h" ++#include "utils/TimeUtils.h" ++#include "utils/log.h" ++#include "platform/linux/RBP.h" ++#include "threads/Thread.h" ++ ++bool CVideoSyncPi::Setup(PUPDATECLOCK func) ++{ ++ UpdateClock = func; ++ m_abort = false; ++ CServiceBroker::GetWinSystem()->Register(this); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up RPi"); ++ return true; ++} ++ ++void CVideoSyncPi::Run(CEvent& stopEvent) ++{ ++ /* This shouldn't be very busy and timing is important so increase priority */ ++ CThread::GetCurrentThread()->SetPriority(CThread::GetCurrentThread()->GetPriority()+1); ++ ++ while (!stopEvent.Signaled() && !m_abort) ++ { ++ g_RBP.WaitVsync(); ++ uint64_t now = CurrentHostCounter(); ++ UpdateClock(1, now, m_refClock); ++ } ++} ++ ++void CVideoSyncPi::Cleanup() ++{ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up RPi"); ++ CServiceBroker::GetWinSystem()->Unregister(this); ++} ++ ++float CVideoSyncPi::GetFps() ++{ ++ m_fps = CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS(); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.2f", m_fps); ++ return m_fps; ++} ++ ++void CVideoSyncPi::OnResetDisplay() ++{ ++ m_abort = true; ++} ++ ++void CVideoSyncPi::RefreshChanged() ++{ ++ if (m_fps != CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS()) ++ m_abort = true; ++} +diff --git a/xbmc/windowing/gbm/VideoSyncPi.h b/xbmc/windowing/gbm/VideoSyncPi.h +new file mode 100644 +index 0000000000..e0c759fa7f +--- /dev/null ++++ b/xbmc/windowing/gbm/VideoSyncPi.h +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2005-2018 Team Kodi ++ * This file is part of Kodi - https://kodi.tv ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * See LICENSES/README.md for more information. ++ */ ++ ++#pragma once ++ ++#include "windowing/VideoSync.h" ++#include "guilib/DispResource.h" ++ ++class CVideoSyncPi : public CVideoSync, IDispResource ++{ ++public: ++ CVideoSyncPi(void *clock) : CVideoSync(clock) {}; ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(CEvent& stopEvent); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++ virtual void OnResetDisplay(); ++ virtual void RefreshChanged(); ++ ++private: ++ volatile bool m_abort; ++}; +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +index f763577117..e73381f350 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +@@ -6,15 +6,12 @@ + * See LICENSES/README.md for more information. + */ + +-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.h" +-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h" +- + #include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h" + #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererGBM.h" + #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h" + #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h" +-#include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h" ++#include "cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h" ++#include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h" + #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" + #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" + +@@ -22,6 +19,7 @@ + #include "platform/linux/XTimeUtils.h" + #include "utils/log.h" + #include "WinSystemGbmGLESContext.h" ++#include "VideoSyncPi.h" + + #include + #include +@@ -43,9 +41,10 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + { + VIDEOPLAYER::CRendererFactory::ClearRenderer(); + CDVDFactoryCodec::ClearHWAccels(); ++ CDVDFactoryCodec::ClearHWVideoCodecs(); ++ + CLinuxRendererGLES::Register(); + RETRO::CRPProcessInfoGbm::Register(); +- RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryGBM); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES); + + if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API)) +@@ -53,20 +52,9 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + return false; + } + +- bool general, deepColor; +- m_vaapiProxy.reset(GBM::VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor())); +- GBM::VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay()); +- GBM::VAAPIRegisterRender(m_vaapiProxy.get(), general, deepColor); +- +- if (general) +- { +- GBM::VAAPIRegister(m_vaapiProxy.get(), deepColor); +- } +- +- CRendererDRMPRIMEGLES::Register(); +- CRendererDRMPRIME::Register(); +- CDVDVideoCodecDRMPRIME::Register(); +- VIDEOPLAYER::CProcessInfoGBM::Register(); ++ MMAL::CDecoder::Register(); ++ MMAL::CMMALRenderer::Register(); ++ MMAL::CMMALVideo::Register(); + + return true; + } +@@ -144,3 +132,17 @@ bool CWinSystemGbmGLESContext::CreateContext() + } + return true; + } ++ ++std::unique_ptr CWinSystemGbmGLESContext::GetVideoSync(void *clock) ++{ ++ std::unique_ptr pVSync(new CVideoSyncPi(clock)); ++ return pVSync; ++} ++ ++void CWinSystemGbmGLESContext::SetVSyncImpl(bool enable) ++{ ++ if (!m_eglContext.SetVSync(enable)) ++ { ++ CLog::Log(LOGERROR, "%s,Could not set egl vsync", __FUNCTION__); ++ } ++} +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.h b/xbmc/windowing/gbm/WinSystemGbmGLESContext.h +index d80d9770d5..95954a606c 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.h ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.h +@@ -34,7 +34,8 @@ public: + bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override; + void PresentRender(bool rendered, bool videoLayer) override; + protected: +- void SetVSyncImpl(bool enable) override { return; }; ++ void SetVSyncImpl(bool enable) override; ++ virtual std::unique_ptr GetVideoSync(void *clock) override; + void PresentRenderImpl(bool rendered) override {}; + bool CreateContext() override; + }; +-- +2.20.1 + + +From 21a4e178608b931f35128eb378d99657b5ecdf43 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 3 Apr 2019 19:19:45 +0100 +Subject: [PATCH 08/14] MMALRenderer: Avoid advanced deinterlace in gbm mode + +--- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index fae5df73e2..e4a9a2c9ea 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -745,7 +745,9 @@ void CMMALRenderer::Run() + bool interlace = (omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED) ? true:false; + + // advanced deinterlace requires 3 frames of context so disable when showing stills ++#if !defined(HAVE_GBM) + if (omvb->m_stills) ++#endif + { + if (interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED) + interlace_method = VS_INTERLACEMETHOD_MMAL_BOB; +-- +2.20.1 + + +From 9a03bf88878532faa76532105bb6298f28a78cd1 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 24 Apr 2019 16:22:27 +0100 +Subject: [PATCH 09/14] MMALRender: Move video plane behind GUI + +--- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index e4a9a2c9ea..2114712c29 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -1280,6 +1280,9 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect + region.noaspect = MMAL_TRUE; + region.mode = MMAL_DISPLAY_MODE_LETTERBOX; + ++ region.set |= MMAL_DISPLAY_SET_LAYER; ++ region.layer = -128; ++ + if (m_renderOrientation == 90) + region.transform = MMAL_DISPLAY_ROT90; + else if (m_renderOrientation == 180) +-- +2.20.1 + + +From 736818a17b48faf18e3bcdaa9f3069cded8ea6f9 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 26 Apr 2019 17:33:36 +0200 +Subject: [PATCH 10/14] WinSystemGbmGLESContext: register CProcessInfoPi + +Signed-off-by: Matthias Reichl +--- + xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt | 4 ++-- + xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt b/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt +index 1a41576405..2b0c66ebc7 100644 +--- a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt ++++ b/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt +@@ -1,7 +1,7 @@ +-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) ++# if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + set(SOURCES ProcessInfoPi.cpp) + + set(HEADERS ProcessInfoPi.h) + + core_add_library(processPi) +-endif() ++# endif() +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +index e73381f350..c4997cc2f4 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +@@ -14,6 +14,7 @@ + #include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h" + #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" + #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" ++#include "cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h" + + #include "OptionalsReg.h" + #include "platform/linux/XTimeUtils.h" +@@ -44,6 +45,7 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + CDVDFactoryCodec::ClearHWVideoCodecs(); + + CLinuxRendererGLES::Register(); ++ CProcessInfoPi::Register(); + RETRO::CRPProcessInfoGbm::Register(); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES); + +-- +2.20.1 + + +From 2958fa06af85e097f811a984cbaf718884e6a17e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 28 Apr 2019 10:57:11 +0200 +Subject: [PATCH 11/14] Screenshot: use RPi/dispmanx code to capture screenshot + +Signed-off-by: Matthias Reichl +--- + xbmc/utils/Screenshot.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp +index 0616e24a18..ad82156384 100644 +--- a/xbmc/utils/Screenshot.cpp ++++ b/xbmc/utils/Screenshot.cpp +@@ -17,7 +17,7 @@ + + #include "pictures/Picture.h" + +-#ifdef TARGET_RASPBERRY_PI ++#if 1 //#ifdef TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" + #endif + +@@ -62,7 +62,7 @@ CScreenshotSurface::~CScreenshotSurface() + + bool CScreenshotSurface::capture() + { +-#if defined(TARGET_RASPBERRY_PI) ++#if 1 //#if defined(TARGET_RASPBERRY_PI) + g_RBP.GetDisplaySize(m_width, m_height); + m_buffer = g_RBP.CaptureDisplay(m_width, m_height, &m_stride, true, false); + if (!m_buffer) +-- +2.20.1 + + +From 0412bf4ffbd7bc1695a2e9e975ce7ca6ef7fd51c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 25 Apr 2019 17:11:53 +0100 +Subject: [PATCH 12/14] RBP: Hack: open display after changing hdmi mode + +--- + xbmc/platform/linux/RBP.cpp | 6 ++++-- + xbmc/platform/xbmc.cpp | 4 ++-- + xbmc/windowing/gbm/DRMAtomic.cpp | 12 +++++++++++- + xbmc/windowing/gbm/DRMAtomic.h | 2 ++ + 4 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index e7b11a5f73..255f4640c0 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -162,6 +162,7 @@ static void vsync_callback_static(DISPMANX_UPDATE_HANDLE_T u, void *arg) + + DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) + { ++ DISPMANX_DISPLAY_HANDLE_T last_display = m_display; + CSingleLock lock(m_critSection); + if (m_display == DISPMANX_NO_HANDLE) + { +@@ -169,12 +170,14 @@ DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) + int s = vc_dispmanx_vsync_callback(m_display, vsync_callback_static, (void *)this); + assert(s == 0); + } ++ CLog::Log(LOGDEBUG, "CRBP::%s device:%d m_display:%x (%x)", __FUNCTION__, device, m_display, last_display); + return m_display; + } + + void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) + { + CSingleLock lock(m_critSection); ++ CLog::Log(LOGDEBUG, "CRBP::%s display:%x m_display:%x", __FUNCTION__, display, m_display); + assert(display == m_display); + int s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); + assert(s == 0); +@@ -244,7 +247,6 @@ void CRBP::VSyncCallback() + uint32_t CRBP::WaitVsync(uint32_t target) + { + CSingleLock vlock(m_vsync_lock); +- DISPMANX_DISPLAY_HANDLE_T display = m_display; + XbmcThreads::EndTime delay(50); + if (target == ~0U) + target = m_vsync_count+1; +@@ -256,7 +258,7 @@ uint32_t CRBP::WaitVsync(uint32_t target) + break; + } + if ((signed)(m_vsync_count - target) < 0) +- CLog::Log(LOGDEBUG, "CRBP::%s no vsync %d/%d display:%x(%x) delay:%d", __FUNCTION__, m_vsync_count, target, m_display, display, delay.MillisLeft()); ++ CLog::Log(LOGDEBUG, "CRBP::%s no vsync %d/%d display:%x delay:%d", __FUNCTION__, m_vsync_count, target, m_display, delay.MillisLeft()); + + return m_vsync_count; + } +diff --git a/xbmc/platform/xbmc.cpp b/xbmc/platform/xbmc.cpp +index e9f39178ca..4617c196d8 100644 +--- a/xbmc/platform/xbmc.cpp ++++ b/xbmc/platform/xbmc.cpp +@@ -8,7 +8,7 @@ + + #include "Application.h" + +-#ifdef TARGET_RASPBERRY_PI ++#if 1//def TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" + #endif + +@@ -36,7 +36,7 @@ extern "C" int XBMC_Run(bool renderGUI, const CAppParamParser ¶ms) + return status; + } + +-#ifdef TARGET_RASPBERRY_PI ++#if 1//def TARGET_RASPBERRY_PI + if(!g_RBP.Initialize()) + return false; + g_RBP.LogFirmwareVersion(); +diff --git a/xbmc/windowing/gbm/DRMAtomic.cpp b/xbmc/windowing/gbm/DRMAtomic.cpp +index 0299fc9caa..de2c905e61 100644 +--- a/xbmc/windowing/gbm/DRMAtomic.cpp ++++ b/xbmc/windowing/gbm/DRMAtomic.cpp +@@ -118,10 +118,20 @@ void CDRMAtomic::FlipPage(struct gbm_bo *bo, bool rendered, bool videoLayer) + if (m_need_modeset) + { + flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; +- m_need_modeset = false; ++ if (m_dispman_display != DISPMANX_NO_HANDLE) ++ { ++ g_RBP.CloseDisplay(m_dispman_display); ++ m_dispman_display = DISPMANX_NO_HANDLE; ++ } + } + + DrmAtomicCommit(!drm_fb ? 0 : drm_fb->fb_id, flags, rendered, videoLayer); ++ ++ if (m_need_modeset) ++ { ++ m_need_modeset = false; ++ m_dispman_display = g_RBP.OpenDisplay(0); ++ } + } + + bool CDRMAtomic::InitDrm() +diff --git a/xbmc/windowing/gbm/DRMAtomic.h b/xbmc/windowing/gbm/DRMAtomic.h +index 1aa96127f4..3dcb449103 100644 +--- a/xbmc/windowing/gbm/DRMAtomic.h ++++ b/xbmc/windowing/gbm/DRMAtomic.h +@@ -9,6 +9,7 @@ + #pragma once + + #include "DRMUtils.h" ++#include "platform/linux/RBP.h" + + namespace KODI + { +@@ -36,6 +37,7 @@ private: + bool m_need_modeset; + bool m_active = true; + drmModeAtomicReq *m_req = nullptr; ++ DISPMANX_ELEMENT_HANDLE_T m_dispman_display = 0; + }; + + } +-- +2.20.1 + + +From bd3966f39af236f5d332781e1446a7eb3aa56c49 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:54:03 +0100 +Subject: [PATCH 13/14] RPI: Some fixes for 10-bit geometry + +--- + .../DVDCodecs/Video/MMALFFmpeg.cpp | 12 +++++--- + .../HwDecRender/MMALRenderer.cpp | 5 +++- + .../VideoRenderers/HwDecRender/MMALRenderer.h | 4 +-- + xbmc/platform/linux/RBP.cpp | 29 +++++++++++++++++++ + xbmc/platform/linux/RBP.h | 4 +++ + 5 files changed, 47 insertions(+), 7 deletions(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 854f34fa62..030ca1b7bf 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -58,11 +58,13 @@ void CMMALYUVBuffer::GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]) + AVRpiZcFrameGeometry geo = pool->GetGeometry(); + + if (VERBOSE) +- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d)", CLASSNAME, __FUNCTION__, geo.getStrideY(), geo.getHeightY(), geo.getStrideC(), geo.getHeightC(), Width(), Height(), AlignedWidth(), AlignedHeight()); ++ CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d) ofu:%d szy:%d szu:%d yc:%d", CLASSNAME, __FUNCTION__, ++ geo.getHeightY(), geo.getHeightC(), geo.getStrideY(), geo.getStrideC(), Width(), Height(), AlignedWidth(), AlignedHeight(), ++ geo.getOffsetU(), geo.getSizeY(), geo.getSizeC(), geo.getStripeIsYc() ); + + planes[0] = GetMemPtr(); + if (planes[0] && geo.getPlanesC() >= 1) +- planes[1] = planes[0] + geo.getSizeY(); ++ planes[1] = planes[0] + geo.getOffsetU(); + if (planes[1] && geo.getPlanesC() >= 2) + planes[2] = planes[1] + geo.getSizeC(); + } +@@ -78,7 +80,7 @@ void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES]) + strides[1] = geo.getStrideC(); + strides[2] = geo.getStrideC(); + if (geo.getStripes() > 1) +- strides[3] = geo.getHeightY() + geo.getHeightC(); // abuse: strides[3] = stripe stride ++ strides[3] = geo.getStripeIsYc() ? geo.getHeightY() + geo.getHeightC() : geo.getHeightY(); // abuse: strides[3] = stripe stride + } + + void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) +@@ -190,7 +192,8 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *frame, int flags) + { + int aligned_width = frame->width; + int aligned_height = frame->height; +- if (pool->Encoding() != MMAL_ENCODING_YUVUV128 && pool->Encoding() != MMAL_ENCODING_YUVUV64_16) ++ if (dec->m_fmt != AV_PIX_FMT_SAND128 && dec->m_fmt != AV_PIX_FMT_SAND64_10 && dec->m_fmt != AV_PIX_FMT_SAND64_16 && ++ dec->m_fmt != AV_PIX_FMT_RPI && dec->m_fmt != AV_PIX_FMT_RPI4_8 && dec->m_fmt != AV_PIX_FMT_RPI4_10) + { + // ffmpeg requirements + AlignedSize(dec->m_avctx, aligned_width, aligned_height); +@@ -287,6 +290,7 @@ CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) + { + if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 && + frame->format != AV_PIX_FMT_SAND128 && frame->format != AV_PIX_FMT_SAND64_10 && frame->format != AV_PIX_FMT_SAND64_16 && ++ frame->format != AV_PIX_FMT_RPI && frame->format != AV_PIX_FMT_RPI4_8 && frame->format != AV_PIX_FMT_RPI4_10 && + frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || + frame->buf[1] != nullptr || frame->buf[0] == nullptr) + { +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index 2114712c29..d2f3d21781 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -194,6 +194,9 @@ std::vector CMMALPool::mmal_encoding_table = + { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_SAND128, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI4_8, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI4_10, MMAL_ENCODING_YUV10_COL }, + { AV_PIX_FMT_SAND64_10,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_SAND64_16,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, }, +@@ -234,7 +237,7 @@ void CMMALPool::Configure(AVPixelFormat format, int width, int height, int align + if (m_mmal_format != MMAL_ENCODING_UNKNOWN) + { + m_geo = g_RBP.GetFrameGeometry(m_mmal_format, alignedWidth, alignedHeight); +- if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 ) ++ if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 && m_mmal_format != MMAL_ENCODING_YUV10_COL ) + { + if (alignedWidth) + { +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +index 03042edfb1..644174dfeb 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +@@ -59,8 +59,8 @@ public: + static uint32_t TranslateFormat(AVPixelFormat pixfmt); + virtual int Width() { return m_width; } + virtual int Height() { return m_height; } +- virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_geo.getBytesPerPixel() == 0 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); } +- virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 ? 0 : m_geo.getHeightY(); } ++ virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_mmal_format == MMAL_ENCODING_YUV10_COL || m_geo.getBytesPerPixel() == 0 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); } ++ virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_mmal_format == MMAL_ENCODING_YUV10_COL ? 0 : m_geo.getHeightY(); } + virtual int BitsPerPixel() { return m_geo.getBitsPerPixel(); } + virtual uint32_t &Encoding() { return m_mmal_format; } + virtual int Size() { return m_size; } +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 255f4640c0..6c045e9674 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -459,6 +459,7 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); ++ geo.setStripeIsYc(1); + break; + case MMAL_ENCODING_I420_16: + geo.setBitsPerPixel(10); +@@ -467,6 +468,7 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); ++ geo.setStripeIsYc(1); + break; + case MMAL_ENCODING_OPAQUE: + geo.setStrideY(video_width); +@@ -487,6 +489,14 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); ++ if (geo.getHeightY() * stripe_w > img.pitch) ++ { ++ // "tall" sand - all C blocks now follow Y ++ geo.setHeightY(img.pitch / stripe_w); ++ geo.setHeightC(geo.getHeightY()); ++ geo.setStripeIsYc(0); ++ } + break; + } + case MMAL_ENCODING_YUVUV64_16: +@@ -505,6 +515,25 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width * 2 + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); ++ break; ++ } ++ case MMAL_ENCODING_YUV10_COL: ++ { ++ VC_IMAGE_T img = {}; ++ img.type = VC_IMAGE_YUV10COL; ++ img.width = video_width; ++ img.height = video_height; ++ int rc = get_image_params(GetMBox(), &img); ++ assert(rc == 0); ++ const unsigned int stripe_w = 128; ++ geo.setStrideY(stripe_w); ++ geo.setStrideC(stripe_w); ++ geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w); ++ geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); ++ geo.setPlanesC(1); ++ geo.setStripes(((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); + break; + } + default: assert(0); +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index c4741fd60f..63e02a1826 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -38,9 +38,11 @@ public: + unsigned int getStripes() { return stripes; } + unsigned int getBitsPerPixel() { return bits_per_pixel; } + unsigned int getBytesPerPixel() { return (bits_per_pixel + 7) >> 3; } ++ unsigned int getStripeIsYc() { return stripe_is_yc; } + unsigned int getSizeY() { return stride_y * height_y; } + unsigned int getSizeC() { return stride_c * height_c; } + unsigned int getSize() { return (getSizeY() + getSizeC() * getPlanesC()) * getStripes(); } ++ unsigned int getOffsetU() { return stripe_is_yc ? getSizeY() : getSizeY() * stripes; } + void setStrideY(unsigned int v) { stride_y = v; } + void setHeightY(unsigned int v) { height_y = v; } + void setStrideC(unsigned int v) { stride_c = v; } +@@ -49,6 +51,7 @@ public: + void setStripes(unsigned int v) { stripes = v; } + void setBitsPerPixel(unsigned int v) { bits_per_pixel = v; } + void setBytesPerPixel(unsigned int v) { bits_per_pixel = v * 8; } ++ void setStripeIsYc(unsigned int v) { stripe_is_yc = v; } + private: + unsigned int stride_y = 0; + unsigned int height_y = 0; +@@ -57,6 +60,7 @@ private: + unsigned int planes_c = 0; + unsigned int stripes = 0; + unsigned int bits_per_pixel = 0; ++ unsigned int stripe_is_yc = 0; + }; + + class CGPUMEM +-- +2.20.1 + + +From 3a51e92daaeb528d001f071d00f01d9b513e5e56 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:59:25 +0100 +Subject: [PATCH 14/14] RPI: Increase number of referenced frames + +--- + xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 030ca1b7bf..1dfcf1cef2 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -364,7 +364,7 @@ CDVDVideoCodec::VCReturn CDecoder::Check(AVCodecContext* avctx) + + unsigned CDecoder::GetAllowedReferences() + { +- return 6; ++ return 7; + } + + IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt) +-- +2.20.1 + From 818afbc01352caf5d1566f72e250faef69e7630a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 15 Jun 2019 09:29:00 +0200 Subject: [PATCH 20/23] bcm2835-driver: only filter out libEGL/libGL on RPi4 libopenmaxil links against libbrcmEGL.so and libbrcmGLESv2.so so these libs should not be filtered out. Signed-off-by: Matthias Reichl --- packages/graphics/bcm2835-driver/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/graphics/bcm2835-driver/package.mk b/packages/graphics/bcm2835-driver/package.mk index 7f71085fe4..e27ed5302b 100644 --- a/packages/graphics/bcm2835-driver/package.mk +++ b/packages/graphics/bcm2835-driver/package.mk @@ -39,7 +39,7 @@ make_target() { cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.a ${SYSROOT_PREFIX}/usr/lib cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig ${SYSROOT_PREFIX}/usr/lib else - for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so *.a | grep -v "GL"); do + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so *.a | grep -Ev "^lib(EGL|GL)"); do cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${SYSROOT_PREFIX}/usr/lib done mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig @@ -69,7 +69,7 @@ makeinstall_target() { ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so.2 else - for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so | grep -v "GL"); do + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so | grep -Ev "^lib(EGL|GL)"); do cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${INSTALL}/usr/lib done fi From 3365ab2af7afd17781865fa578151e93f128110e Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 15 Jun 2019 09:31:23 +0200 Subject: [PATCH 21/23] kodi (RPi4): add patch to enable PiSink Signed-off-by: Matthias Reichl --- .../patches/kodi/kodi-002-add-pisink.patch | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch new file mode 100644 index 0000000000..145542295b --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch @@ -0,0 +1,206 @@ +From 8f0d283542fa8c55f2a9cdd520271b0b471e3393 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 10 Jun 2019 22:07:55 +0100 +Subject: [PATCH] RBP: add PiSink + +--- + xbmc/cores/AudioEngine/CMakeLists.txt | 3 +++ + xbmc/platform/linux/CMakeLists.txt | 10 +++++----- + xbmc/platform/linux/RBP.cpp | 24 ++++++++++++------------ + xbmc/platform/linux/RBP.h | 22 +++++++++++----------- + xbmc/windowing/gbm/WinSystemGbm.cpp | 2 ++ + 5 files changed, 33 insertions(+), 28 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/CMakeLists.txt b/xbmc/cores/AudioEngine/CMakeLists.txt +index 060c6a960d..e5b80cf54a 100644 +--- a/xbmc/cores/AudioEngine/CMakeLists.txt ++++ b/xbmc/cores/AudioEngine/CMakeLists.txt +@@ -101,6 +101,9 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + Sinks/AESinkPi.h) + endif() + ++ list(APPEND SOURCES Sinks/AESinkPi.cpp) ++ list(APPEND HEADERS Sinks/AESinkPi.h) ++ + if(CORE_SYSTEM_NAME STREQUAL osx) + list(APPEND SOURCES Sinks/AESinkDARWINOSX.cpp + Sinks/osx/AEDeviceEnumerationOSX.cpp +diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt +index 88076c3d5a..16cdd478be 100644 +--- a/xbmc/platform/linux/CMakeLists.txt ++++ b/xbmc/platform/linux/CMakeLists.txt +@@ -39,7 +39,7 @@ if(DBUS_FOUND) + DBusUtil.h) + endif() + +-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) ++#if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + list(APPEND SOURCES RBP.cpp + OMXClock.cpp + OMXCore.cpp) +@@ -48,10 +48,10 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + DllOMX.h + OMXClock.h + OMXCore.h) +-else() +- list(APPEND SOURCES RBP.cpp) +- list(APPEND HEADERS RBP.h) +-endif() ++#else() ++# list(APPEND SOURCES RBP.cpp) ++# list(APPEND HEADERS RBP.h) ++#endif() + + if(HAVE_SSE4_1) + add_subdirectory(sse4) +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 6c045e9674..9ff4ed4e6f 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -68,13 +68,13 @@ typedef int vc_image_t_size_check[(sizeof(VC_IMAGE_T) == 64) * 2 - 1]; + CRBP::CRBP() + { + m_initialized = false; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; +-#endif ++//#endif + m_DllBcmHost = new DllBcmHost(); +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_OMX = new COMXCore(); +-#endif ++//#endif + m_display = DISPMANX_NO_HANDLE; + m_mb = mbox_open(); + vcsm_init(); +@@ -103,11 +103,11 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) + return false; +-#endif ++//#endif + + char response[80] = ""; + m_arm_mem = 0; +@@ -278,13 +278,13 @@ uint32_t CRBP::LastVsync() + + void CRBP::Deinitialize() + { +-#ifdef TARGET_RASPBERRY_PI +- if (m_omx_image_init) +- g_OMXImage.Deinitialize(); ++//#ifdef TARGET_RASPBERRY_PI ++// if (m_omx_image_init) ++// g_OMXImage.Deinitialize(); + + if(m_omx_initialized) + m_OMX->Deinitialize(); +-#endif ++//#endif + + m_DllBcmHost->bcm_host_deinit(); + +@@ -295,9 +295,9 @@ void CRBP::Deinitialize() + m_omx_image_init = false; + #endif + m_initialized = false; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; +-#endif ++//#endif + if (m_mb) + mbox_close(m_mb); + m_mb = 0; +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index 63e02a1826..d3f46d34a1 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -19,9 +19,9 @@ + #endif + + #include "DllBCM.h" +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + #include "OMXCore.h" +-#endif ++//#endif + #include "xbmc/utils/CPUInfo.h" + #include "threads/CriticalSection.h" + #include "threads/Event.h" +@@ -97,9 +97,9 @@ public: + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } +-#endif ++//#endif + uint32_t LastVsync(int64_t &time); + uint32_t LastVsync(); + uint32_t WaitVsync(uint32_t target = ~0U); +@@ -110,26 +110,26 @@ public: + private: + DllBcmHost *m_DllBcmHost; + bool m_initialized; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + bool m_omx_initialized; +- bool m_omx_image_init; +-#endif ++ //bool m_omx_image_init; ++//#endif + int m_arm_mem; + int m_gpu_mem; + int m_gui_resolution_limit; + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + COMXCore *m_OMX; +-#endif ++//#endif + DISPMANX_DISPLAY_HANDLE_T m_display; + CCriticalSection m_vsync_lock; + XbmcThreads::ConditionVariable m_vsync_cond; + uint32_t m_vsync_count; + int64_t m_vsync_time; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + class DllLibOMXCore; +-#endif ++//#endif + CCriticalSection m_critSection; + + int m_mb; +diff --git a/xbmc/windowing/gbm/WinSystemGbm.cpp b/xbmc/windowing/gbm/WinSystemGbm.cpp +index 9ad1f2daf1..418e0cf8b1 100644 +--- a/xbmc/windowing/gbm/WinSystemGbm.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbm.cpp +@@ -25,6 +25,7 @@ + #include "DRMLegacy.h" + #include "OffScreenModeSetting.h" + #include "messaging/ApplicationMessenger.h" ++#include "cores/AudioEngine/Sinks/AESinkPi.h" + + using namespace KODI::WINDOWING::GBM; + +@@ -33,6 +34,7 @@ CWinSystemGbm::CWinSystemGbm() : + m_GBM(new CGBMUtils), + m_libinput(new CLibInputHandler) + { ++ CAESinkPi::Register(); + OPTIONALS::ALSARegister(); + OPTIONALS::PulseAudioRegister(); + +-- +2.20.1 + From 06a4a5883589f7e6512bd0921cfbe078ea07ac38 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 17 Jun 2019 19:41:28 +0200 Subject: [PATCH 22/23] kodi (RPi4): add patch to limit GUI size, default to 1080p Leia backport of https://github.com/xbmc/xbmc/pull/16063/ picked from https://github.com/Kwiboo/xbmc/commit/b2ad605c9ae4b3e8bf5447562aea095fa094e66a Signed-off-by: Matthias Reichl --- projects/RPi/devices/RPi4/kodi/appliance.xml | 14 ++ .../kodi-010-PR16063-Leia-limit-guisize.patch | 150 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 projects/RPi/devices/RPi4/kodi/appliance.xml create mode 100644 projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch diff --git a/projects/RPi/devices/RPi4/kodi/appliance.xml b/projects/RPi/devices/RPi4/kodi/appliance.xml new file mode 100644 index 0000000000..472aaf7971 --- /dev/null +++ b/projects/RPi/devices/RPi4/kodi/appliance.xml @@ -0,0 +1,14 @@ + + +

+ + + + true + 3 + + + +
+ + diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch new file mode 100644 index 0000000000..6dbfee91d1 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch @@ -0,0 +1,150 @@ +From b2ad605c9ae4b3e8bf5447562aea095fa094e66a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 30 May 2019 21:36:32 +0000 +Subject: [PATCH] windowing/gbm: add option to limit gui size + +--- + .../resources/strings.po | 44 ++++++++++++++++++- + system/settings/gbm.xml | 15 +++++++ + xbmc/windowing/gbm/DRMUtils.cpp | 33 +++++++++++++- + 3 files changed, 90 insertions(+), 2 deletions(-) + +diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po +index 9c9161a99323..11cdf4aba26c 100644 +--- a/addons/resource.language.en_gb/resources/strings.po ++++ b/addons/resource.language.en_gb/resources/strings.po +@@ -7266,7 +7266,49 @@ msgctxt "#13465" + msgid "EGL" + msgstr "" + +-#empty strings from id 13466 to 13504 ++#. Option for setting Limit GUI Size ++#: system/settings/gbm.xml ++msgctxt "#13466" ++msgid "Limit GUI Size" ++msgstr "" ++ ++#. Description of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13467" ++msgid "This option limits GUI size for screen resolutions above 1080p. Requires restart." ++msgstr "" ++ ++#. String for options 1 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13468" ++msgid "No limit" ++msgstr "" ++ ++#. String for options 2 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13469" ++msgid "720p" ++msgstr "" ++ ++#. String for options 3 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13470" ++msgid "1080p / 720p (>30hz)" ++msgstr "" ++ ++#. String for options 4 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13471" ++msgid "1080p" ++msgstr "" ++ ++#. String for options 5 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13472" ++msgid "No limit / 1080p (>30hz)" ++msgstr "" ++ ++#empty strings from id 13473 to 13504 + + #: system/settings/settings.xml + msgctxt "#13505" +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index c5e4d98e0bef..6492b08ef5f2 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -41,6 +41,21 @@ + + false + ++ ++ false ++ 3 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + 3 + false +diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp +index 48f0bc40bcf9..c6031bf67c41 100644 +--- a/xbmc/windowing/gbm/DRMUtils.cpp ++++ b/xbmc/windowing/gbm/DRMUtils.cpp +@@ -17,14 +17,21 @@ + #include + + #include "platform/linux/XTimeUtils.h" +-#include "utils/log.h" ++#include "settings/Settings.h" ++#include "settings/SettingsComponent.h" + #include "utils/StringUtils.h" ++#include "utils/log.h" + #include "windowing/GraphicContext.h" + + #include "DRMUtils.h" + + using namespace KODI::WINDOWING::GBM; + ++namespace ++{ ++const std::string SETTING_VIDEOSCREEN_LIMITGUISIZE = "videoscreen.limitguisize"; ++} ++ + CDRMUtils::CDRMUtils() + : m_connector(new connector) + , m_encoder(new encoder) +@@ -762,6 +769,30 @@ RESOLUTION_INFO CDRMUtils::GetResolutionInfo(drmModeModeInfoPtr mode) + res.iWidth = res.iScreenWidth; + res.iHeight = res.iScreenHeight; + ++ int limit = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(SETTING_VIDEOSCREEN_LIMITGUISIZE); ++ if (limit > 0 && res.iScreenWidth > 1920 && res.iScreenHeight > 1080) ++ { ++ switch (limit) ++ { ++ case 1: // 720p ++ res.iWidth = 1280; ++ res.iHeight = 720; ++ break; ++ case 2: // 1080p / 720p (>30hz) ++ res.iWidth = mode->vrefresh > 30 ? 1280 : 1920; ++ res.iHeight = mode->vrefresh > 30 ? 720 : 1080; ++ break; ++ case 3: // 1080p ++ res.iWidth = 1920; ++ res.iHeight = 1080; ++ break; ++ case 4: // No limit / 1080p (>30hz) ++ res.iWidth = mode->vrefresh > 30 ? 1920 : res.iScreenWidth; ++ res.iHeight = mode->vrefresh > 30 ? 1080 : res.iScreenHeight; ++ break; ++ } ++ } ++ + if (mode->clock % 5 != 0) + res.fRefreshRate = static_cast(mode->vrefresh) * (1000.0f/1001.0f); + else From c010cd4852c8ec0870873442013ea014b99e9dfe Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Fri, 21 Jun 2019 15:57:51 +0200 Subject: [PATCH 23/23] RPi4: add config.txt with default 320MB gpu mem Several 4k HEVC files were reported to play with artifacts unless gpu mem is bumped to at least 288MB. Use 320MB for now to have a bit more headroom, just in case. Unfortunately this can't be changed via distroconfig.txt so we have to do it in config.txt. Also drop the disable_overscan block as that's enabled by default via distroconfig.txt. Signed-off-by: Matthias Reichl --- projects/RPi/devices/RPi4/config/config.txt | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 projects/RPi/devices/RPi4/config/config.txt diff --git a/projects/RPi/devices/RPi4/config/config.txt b/projects/RPi/devices/RPi4/config/config.txt new file mode 100644 index 0000000000..9e2b74b9ad --- /dev/null +++ b/projects/RPi/devices/RPi4/config/config.txt @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) +################################################################################ +# Bootloader configuration - config.txt +################################################################################ + +################################################################################ +# Memory (System/GPU configuration ) +################################################################################ + +# Default GPU memory split - at least 288M is needed for some 4k HEVC files +gpu_mem=320 + +################################################################################ +# For overclocking and various other settings, see: +# https://www.raspberrypi.org/documentation/configuration/config-txt.md +################################################################################ +# Set 'force_turbo=1' to disable dynamic overclocking and enable overclocking always. +force_turbo=0 + +# Force HDMI even if unplugged or powered off +# hdmi_force_hotplug=1 + +# Doesn't sent initial active source message. +# Avoids bringing CEC (enabled TV) out of standby and channel switch when +# rebooting. +hdmi_ignore_cec_init=1 + +################################################################################ +# End of default configuration +################################################################################ + +################################################################################ +# Include distribution specific config file if it exists. +################################################################################ +[all] +include distroconfig.txt