diff --git a/packages/devel/libcec/package.mk b/packages/devel/libcec/package.mk
index 56bd5f3fe4..d4dd527809 100644
--- a/packages/devel/libcec/package.mk
+++ b/packages/devel/libcec/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="libcec"
-PKG_VERSION="5250931"
-PKG_SHA256="22c746602e85ea575bd247adfb17181849fb54d97428a25ccd29a064e43e6cde"
+PKG_VERSION="8adc786"
+PKG_SHA256="742efcc24e8949d822effdd06cfebfd0d62babab826be33c1686c7bfea52f455"
PKG_ARCH="any"
PKG_LICENSE="GPL"
PKG_SITE="http://libcec.pulse-eight.com/"
diff --git a/packages/devel/libcec/patches/cec-framework/libcec-0001-PR380.patch b/packages/devel/libcec/patches/cec-framework/libcec-0001-PR380.patch
index 392820a2e3..5a871d36f9 100644
--- a/packages/devel/libcec/patches/cec-framework/libcec-0001-PR380.patch
+++ b/packages/devel/libcec/patches/cec-framework/libcec-0001-PR380.patch
@@ -1,4 +1,4 @@
-From f4db70392c9bfe3bb7b551fd9eb79d58d0588a50 Mon Sep 17 00:00:00 2001
+From 93908ac97c496447e47182945dd17dd64fadb73a Mon Sep 17 00:00:00 2001
From: Jonas Karlman
Date: Wed, 6 Sep 2017 17:37:05 +0200
Subject: [PATCH] Add Linux CEC Adapter
@@ -43,10 +43,11 @@ diff --git a/include/cectypes.h b/include/cectypes.h
index 9c918427..2c32e4d9 100644
--- a/include/cectypes.h
+++ b/include/cectypes.h
-@@ -282,6 +282,16 @@ namespace CEC {
+@@ -281,6 +281,16 @@ namespace CEC {
+ */
#define CEC_MAX_DATA_PACKET_SIZE (16 * 4)
- /*!
++/*!
+ * the path to use for the Linux CEC device
+ */
+#define CEC_LINUX_PATH "/dev/cec0"
@@ -56,10 +57,9 @@ index 9c918427..2c32e4d9 100644
+ */
+#define CEC_LINUX_VIRTUAL_COM "Linux"
+
-+/*!
+ /*!
* the path to use for the AOCEC HDMI CEC device
*/
- #define CEC_AOCEC_PATH "/dev/aocec"
@@ -861,6 +871,7 @@ typedef enum cec_adapter_type
ADAPTERTYPE_RPI = 0x100,
ADAPTERTYPE_TDA995x = 0x200,
@@ -69,7 +69,7 @@ index 9c918427..2c32e4d9 100644
} cec_adapter_type;
diff --git a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h
-index 0d0cf178..49be8fbe 100644
+index 25c1c6e3..15f9543f 100644
--- a/src/libcec/CECTypeUtils.h
+++ b/src/libcec/CECTypeUtils.h
@@ -766,6 +766,8 @@ namespace CEC
@@ -82,10 +82,10 @@ index 0d0cf178..49be8fbe 100644
return "unknown";
}
diff --git a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt
-index d3eefa34..8d5bdede 100644
+index 5c888070..eb1c7ee3 100644
--- a/src/libcec/CMakeLists.txt
+++ b/src/libcec/CMakeLists.txt
-@@ -87,6 +87,8 @@ set(CEC_HEADERS devices/CECRecordingDevice.h
+@@ -88,6 +88,8 @@ set(CEC_HEADERS devices/CECRecordingDevice.h
adapter/Exynos/ExynosCEC.h
adapter/Exynos/ExynosCECAdapterDetection.h
adapter/Exynos/ExynosCECAdapterCommunication.h
@@ -161,14 +161,14 @@ index 91195ea0..323c2724 100644
}
diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp
new file mode 100644
-index 00000000..400abde4
+index 00000000..878c572f
--- /dev/null
+++ b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp
@@ -0,0 +1,367 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
-+ * libCEC Linux CEC Adapter is Copyright (C) 2017 Jonas Karlman
++ * libCEC Linux CEC Adapter is Copyright (C) 2017-2018 Jonas Karlman
+ * based heavily on:
+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs
+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea
@@ -209,7 +209,7 @@ index 00000000..400abde4
+#include "LinuxCECAdapterCommunication.h"
+#include "CECTypeUtils.h"
+#include "LibCEC.h"
-+#include
++#include "p8-platform/util/buffer.h"
+#include
+
+using namespace CEC;
@@ -420,12 +420,12 @@ index 00000000..400abde4
+ return false;
+}
+
-+cec_logical_addresses CLinuxCECAdapterCommunication::GetLogicalAddresses(void)
++cec_logical_addresses CLinuxCECAdapterCommunication::GetLogicalAddresses(void) const
+{
+ cec_logical_addresses addresses;
+ addresses.Clear();
+
-+ if (IsOpen())
++ if (m_fd != INVALID_SOCKET_VALUE)
+ {
+ struct cec_log_addrs log_addrs = {};
+ if (ioctl(m_fd, CEC_ADAP_G_LOG_ADDRS, &log_addrs))
@@ -534,7 +534,7 @@ index 00000000..400abde4
+#endif
diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h
new file mode 100644
-index 00000000..66d3e57d
+index 00000000..0453bb26
--- /dev/null
+++ b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h
@@ -0,0 +1,94 @@
@@ -542,7 +542,7 @@ index 00000000..66d3e57d
+/*
+ * This file is part of the libCEC(R) library.
+ *
-+ * libCEC Linux CEC Adapter is Copyright (C) 2017 Jonas Karlman
++ * libCEC Linux CEC Adapter is Copyright (C) 2017-2018 Jonas Karlman
+ * based heavily on:
+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs
+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea
@@ -578,7 +578,7 @@ index 00000000..66d3e57d
+#include "env.h"
+
+#if defined(HAVE_LINUX_API)
-+#include
++#include "p8-platform/threads/threads.h"
+#include "../AdapterCommunication.h"
+
+namespace CEC
@@ -603,7 +603,7 @@ index 00000000..66d3e57d
+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) override { return true; }
+ bool StartBootloader(void) override { return false; }
+ bool SetLogicalAddresses(const cec_logical_addresses &addresses) override;
-+ cec_logical_addresses GetLogicalAddresses(void) override;
++ cec_logical_addresses GetLogicalAddresses(void) const override;
+ bool PingAdapter(void) override { return true; }
+ uint16_t GetFirmwareVersion(void) override { return 0; }
+ uint32_t GetFirmwareBuildDate(void) override { return 0; }
@@ -746,7 +746,7 @@ index 00000000..f5ea2c47
+
+#endif
diff --git a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake
-index 532f2132..a9f1def5 100644
+index 73612dec..c1c182a6 100644
--- a/src/libcec/cmake/CheckPlatformSupport.cmake
+++ b/src/libcec/cmake/CheckPlatformSupport.cmake
@@ -9,6 +9,7 @@
@@ -757,7 +757,7 @@ index 532f2132..a9f1def5 100644
# HAVE_AOCEC_API ON if AOCEC is supported
# HAVE_P8_USB ON if Pulse-Eight devices are supported
# HAVE_P8_USB_DETECT ON if Pulse-Eight devices can be auto-detected
-@@ -29,6 +30,7 @@ SET(HAVE_LIBUDEV OFF CACHE BOOL "udev not supported")
+@@ -30,6 +31,7 @@ SET(HAVE_LIBUDEV OFF CACHE BOOL "udev not supported")
SET(HAVE_RPI_API OFF CACHE BOOL "raspberry pi not supported")
SET(HAVE_TDA995X_API OFF CACHE BOOL "tda995x not supported")
SET(HAVE_EXYNOS_API OFF CACHE BOOL "exynos not supported")
@@ -765,7 +765,7 @@ index 532f2132..a9f1def5 100644
SET(HAVE_AOCEC_API OFF CACHE BOOL "aocec not supported")
# Pulse-Eight devices are always supported
set(HAVE_P8_USB ON CACHE BOOL "p8 usb-cec supported" FORCE)
-@@ -137,6 +139,16 @@ else()
+@@ -139,6 +141,16 @@ else()
list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_EXYNOS})
endif()
@@ -783,7 +783,7 @@ index 532f2132..a9f1def5 100644
if (${HAVE_AOCEC_API})
set(LIB_INFO "${LIB_INFO}, AOCEC")
diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake
-index 7ec10f5d..8ca8119d 100644
+index 83a778af..f47b1f7b 100644
--- a/src/libcec/cmake/DisplayPlatformSupport.cmake
+++ b/src/libcec/cmake/DisplayPlatformSupport.cmake
@@ -44,6 +44,12 @@ else()
@@ -797,10 +797,10 @@ index 7ec10f5d..8ca8119d 100644
+endif()
+
if (HAVE_AOCEC_API)
- message(STATUS "AOCEC support: yes")
+ message(STATUS "AOCEC support: yes")
else()
diff --git a/src/libcec/env.h.in b/src/libcec/env.h.in
-index 0774a1c7..6ee352ae 100644
+index 456a2e75..71895a86 100644
--- a/src/libcec/env.h.in
+++ b/src/libcec/env.h.in
@@ -76,6 +76,9 @@
diff --git a/packages/devel/libcec/patches/libcec-001-drop-tinfo.patch b/packages/devel/libcec/patches/libcec-001-drop-tinfo.patch
new file mode 100644
index 0000000000..281f4c73cf
--- /dev/null
+++ b/packages/devel/libcec/patches/libcec-001-drop-tinfo.patch
@@ -0,0 +1,12 @@
+diff --git a/src/cec-client/CMakeLists.txt b/src/cec-client/CMakeLists.txt
+index 37c733b..2cb42bb 100644
+--- a/src/cec-client/CMakeLists.txt
++++ b/src/cec-client/CMakeLists.txt
+@@ -44,7 +44,6 @@ if (NOT WIN32)
+ # curses
+ if (HAVE_CURSES_API)
+ target_link_libraries(cec-client curses)
+- target_link_libraries(cec-client tinfo)
+ endif()
+
+ # rt
diff --git a/packages/devel/libcec/patches/libcec-002-PR390.patch b/packages/devel/libcec/patches/libcec-002-PR390.patch
index 09b37524c5..88272d4173 100644
--- a/packages/devel/libcec/patches/libcec-002-PR390.patch
+++ b/packages/devel/libcec/patches/libcec-002-PR390.patch
@@ -17,7 +17,7 @@ index dbdd01ce..83e78bd8 100644
else if (command.parameters.size == 1 &&
command.parameters[0] == SL_COMMAND_REQUEST_RECONNECT)
{
-- HandleVendorCommandPowerOn(command);
+- HandleVendorCommandPowerOn(command, false);
+ HandleVendorCommandPowerOnStatus(command);
return COMMAND_HANDLED;
}
diff --git a/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/package.mk b/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/package.mk
index 2f7bb5fa0d..b36eb82881 100644
--- a/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/package.mk
@@ -17,8 +17,8 @@
################################################################################
PKG_NAME="inputstream.adaptive"
-PKG_VERSION="babcca4"
-PKG_SHA256="1351012bbdfe18e683f217ea999d596e0a7f21ea48e9a5c1783ca06e864b144e"
+PKG_VERSION="d89b547"
+PKG_SHA256="7c276aa374fc69cddd8286a348667acee71556623fbb6f1b0ad18e743f818d41"
PKG_LICENSE="GPL"
PKG_SITE="http://www.kodi.tv"
PKG_URL="https://github.com/peak3d/inputstream.adaptive/archive/$PKG_VERSION.tar.gz"
diff --git a/packages/mediacenter/kodi-binary-addons/peripheral.joystick/package.mk b/packages/mediacenter/kodi-binary-addons/peripheral.joystick/package.mk
index 711b19a489..920a5c36db 100644
--- a/packages/mediacenter/kodi-binary-addons/peripheral.joystick/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/peripheral.joystick/package.mk
@@ -1,5 +1,6 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv)
#
# LibreELEC is free software: you can redistribute it and/or modify
@@ -17,8 +18,8 @@
################################################################################
PKG_NAME="peripheral.joystick"
-PKG_VERSION="80224e1"
-PKG_SHA256="6982014982fd3883ae39fd1e6ad6f71c0e940da825390de7494e87d1c18ca0ea"
+PKG_VERSION="6312745"
+PKG_SHA256="0afec1587bed5c1e32e3717529b5e9dec839f28e01a60ec3c49054577532abf9"
PKG_REV="1"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.argustv/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.argustv/package.mk
index 5fc2d2fe44..144f3296f4 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.argustv/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.argustv/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.argustv"
-PKG_VERSION="2bce465"
-PKG_SHA256="2e80867293949e452ca623ac3ed88aa33e5de50fe7e0c6c51f476fca1fa5841a"
+PKG_VERSION="37a3a76"
+PKG_SHA256="18e311b6bbe6acff663019e74c109548a61c325071960feafaa281c2c1e64dff"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.demo/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.demo/package.mk
index 2d29359c4f..710b273858 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.demo/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.demo/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.demo"
-PKG_VERSION="20d81d8"
-PKG_SHA256="67b37fc6d7401dfa7b508241ff2d230fbf0879286b43a70667fd3fb89002470a"
+PKG_VERSION="bcd8289"
+PKG_SHA256="c5a33274c400644970cee167ed2c69ca277e07778272657be46ed75410413c2f"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.dvblink/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.dvblink/package.mk
index 41ca080b14..ac5dcdd4d2 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.dvblink/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.dvblink/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.dvblink"
-PKG_VERSION="a87258b"
-PKG_SHA256="a9ddc8b70d42e174aa9486b84d467296afa870f80fff32dd84223b12abf762e8"
+PKG_VERSION="1732e4b"
+PKG_SHA256="eb3a849102fe5d21d43600bbc97b120ed1b6d5716ac8a2a52079dff1ab4e4364"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.dvbviewer/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.dvbviewer/package.mk
index 3336865d47..6189e62ea1 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.dvbviewer/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.dvbviewer/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.dvbviewer"
-PKG_VERSION="884b732"
-PKG_SHA256="13e2c95aabfc5ee8ded5bcf1259492bd4487574ad2e2ee531061989b2e8f4e41"
+PKG_VERSION="d6f1629"
+PKG_SHA256="9c02b2f075eb5243750786e22ecd56215b51107ce96bedfb8d3ef97d17bf7ddf"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.filmon/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.filmon/package.mk
index 5fdc85ed58..17b7a838ff 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.filmon/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.filmon/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.filmon"
-PKG_VERSION="470ca1c"
-PKG_SHA256="be27454a280664b0bb20c1f18d281ca293d0d74cfa464eaabd771c417c5ff174"
+PKG_VERSION="ba261c9"
+PKG_SHA256="62787a2e5a7bfff874a5138b013f11a00cf1e9c527f531bd3a7e25e0d0eabcb7"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.hdhomerun/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.hdhomerun/package.mk
index f1f749d291..f5affd6329 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.hdhomerun/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.hdhomerun/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.hdhomerun"
-PKG_VERSION="4639740"
-PKG_SHA256="0682689ff55e0585ccd9b57e81af57defab1efde6c56b2e645c03ab4438e2e44"
+PKG_VERSION="379c62c"
+PKG_SHA256="52e6567184ae4ed3c2ca9fd4e5fec67f94ca5eb98e16b4c8996d199f4923ca0a"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.hts/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.hts/package.mk
index 52474200e8..2ab9f544b4 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.hts/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.hts/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.hts"
-PKG_VERSION="4f7196d"
-PKG_SHA256="12f5a51e9923b96f870be59a47336c33d160a8e8903e58027f0dd0cd82cf8347"
+PKG_VERSION="f569808"
+PKG_SHA256="84435fadeb53c0cbfc63d096b40a99b2a74448b4a7dbadc954e29e4943ad07f7"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.iptvsimple/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.iptvsimple/package.mk
index 67e58c5186..b44880e688 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.iptvsimple/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.iptvsimple/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.iptvsimple"
-PKG_VERSION="e220777"
-PKG_SHA256="ed6159cea372129ec49776a778aa9284898abdc2996c1744401273ac1fc21ef5"
+PKG_VERSION="663040c"
+PKG_SHA256="6be5a4dcf368924a04cd458b9b3f264336e8cdb68a2fca77fe26673f224798a7"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.mediaportal.tvserver/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.mediaportal.tvserver/package.mk
index 514b8fa7a9..02572b93a7 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.mediaportal.tvserver/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.mediaportal.tvserver/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.mediaportal.tvserver"
-PKG_VERSION="c4e32b0"
-PKG_SHA256="16531a64827dd0f475c5184c7f89aa47d279736919a06e7cd55d8154f7bac798"
+PKG_VERSION="01af5a0"
+PKG_SHA256="5efd46277ec487e600890785059a20cacd4b7bf0ddada235e09dca40231623e0"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.mythtv/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.mythtv/package.mk
index fb86ccab3f..b3e77b4ff7 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.mythtv/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.mythtv/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.mythtv"
-PKG_VERSION="9d15025"
-PKG_SHA256="ac67f808b165bed28feec2523608e33daa4a74579ed7664945d47714389ebc37"
+PKG_VERSION="c18ca9e"
+PKG_SHA256="4a85244371c4a7105c219b90875893c76b9441b4d0f4da59931ea26483359d2a"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.nextpvr/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.nextpvr/package.mk
index d5070944bc..0366de4916 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.nextpvr/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.nextpvr/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.nextpvr"
-PKG_VERSION="78a80de"
-PKG_SHA256="25cd42764b2b8285f8f7d8855bef24a960d6ae8b18f2f9870c0c429af32116d8"
+PKG_VERSION="fad3ca9"
+PKG_SHA256="4549b3bb4038a9d381f95483a65cababfdf13abdc0f8aa9af44e2cf1b092e2ee"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.njoy/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.njoy/package.mk
index ff9147cd8d..e9f4cab612 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.njoy/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.njoy/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.njoy"
-PKG_VERSION="5a2c2d3"
-PKG_SHA256="14a02f78df7651dd8cb668c1c587e398ec8788125289ed66058e91ba111328f6"
+PKG_VERSION="30743c6"
+PKG_SHA256="93996b7bfcf076051eee7ce3d2108efed5f7af32223afd8fe92808cf478a6355"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.octonet/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.octonet/package.mk
index eac6aa2025..7f696e268d 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.octonet/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.octonet/package.mk
@@ -17,8 +17,8 @@
################################################################################
PKG_NAME="pvr.octonet"
-PKG_VERSION="54680a3"
-PKG_SHA256="27ed72f70412c6cbe7f071bbfaa7c263374ae9268b8015ce1b2307980e2016cc"
+PKG_VERSION="1e44819"
+PKG_SHA256="acea9593c3b6531f7909ce21f95d35553f796fd7327994792839e79f19f1c9ac"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.pctv/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.pctv/package.mk
index 16180a94a7..ffc37c8730 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.pctv/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.pctv/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.pctv"
-PKG_VERSION="17c1897"
-PKG_SHA256="9a1277275833ac0288ac34083daf8521472f2f550d21f8953078d2d4c73559db"
+PKG_VERSION="d0c7241"
+PKG_SHA256="abefc40b02505189dc55dba11b774ddd897922ee057c88b5cea289f30ec1b5da"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.stalker/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.stalker/package.mk
index 6777f540fa..a30aaea82b 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.stalker/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.stalker/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.stalker"
-PKG_VERSION="0700069"
-PKG_SHA256="a3322c8567400b7dbdc9a91bfa5e21375064a9483b4b676414e4164a577d307f"
+PKG_VERSION="00f3fc4"
+PKG_SHA256="1b3a4354991d24ee5b32273133eef48d03749f2d493988f524421a6ab35e0bd6"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.teleboy/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.teleboy/package.mk
index 9a8482db40..7f7593655b 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.teleboy/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.teleboy/package.mk
@@ -17,8 +17,8 @@
################################################################################
PKG_NAME="pvr.teleboy"
-PKG_VERSION="3e9e537"
-PKG_SHA256="5c40d59c4403688d15d9b8a5b96112bd21e2558667a85adc13afeca6aac43fb3"
+PKG_VERSION="dfa68b0"
+PKG_SHA256="dde0747985c9f535642a9be5830cfe59b8651b426883c38653ea4a191f1aa9cf"
PKG_REV="1"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.vbox/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.vbox/package.mk
index c5234f3d98..c90bb6b2e6 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.vbox/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.vbox/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.vbox"
-PKG_VERSION="48ffcba"
-PKG_SHA256="07e46dbc9df1253af0d277c924850ddaf12c02a3e1b8ff1559096b16e528d29a"
+PKG_VERSION="d2e61a9"
+PKG_SHA256="e726378bcd8365d527404ec8831e9d82b716926f30a89734b99db5523fc17d73"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.vdr.vnsi/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.vdr.vnsi/package.mk
index f39c0d5511..b4b3dd0b85 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.vdr.vnsi/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.vdr.vnsi/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.vdr.vnsi"
-PKG_VERSION="a2880c7"
-PKG_SHA256="975ce55c888b46b9b47bf7a8bbe4db56a2169aeebfda11fa9ca51510d1db2148"
+PKG_VERSION="18c7474"
+PKG_SHA256="4cade59a51161dd6094bdc9f592719a1b02bd58d626ab43bd0d1633c82e39bb3"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.vuplus/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.vuplus/package.mk
index 4e3fad543f..6596e10962 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.vuplus/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.vuplus/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.vuplus"
-PKG_VERSION="6c94eec"
-PKG_SHA256="fc645a611a78250299a83edca56dd03686d4ad67900be20fe00f46b2fb6d8e17"
+PKG_VERSION="bcfd34d"
+PKG_SHA256="03e6a7c762d54a97ba57a83d5bb012ee24134991bc42e6101e127b8340d7aa39"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.wmc/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.wmc/package.mk
index 171c13c979..95ad5608d7 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.wmc/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.wmc/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="pvr.wmc"
-PKG_VERSION="a7ec576"
-PKG_SHA256="ecc460e5e50c6e75a857dc7ec0e8de8142fb3bbb036e9253bca72ac20b5a2111"
+PKG_VERSION="ce4b47a"
+PKG_SHA256="a260a35149e60a53a8c8cab9b62b9ddb7eaf04d6a5cf73e8992c83e8a9c3ae74"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/pvr.zattoo/package.mk b/packages/mediacenter/kodi-binary-addons/pvr.zattoo/package.mk
index 4bfca61773..b3ab286e3a 100644
--- a/packages/mediacenter/kodi-binary-addons/pvr.zattoo/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/pvr.zattoo/package.mk
@@ -17,8 +17,8 @@
################################################################################
PKG_NAME="pvr.zattoo"
-PKG_VERSION="f04367b"
-PKG_SHA256="5685ccafe979935123bce6cea2a7499f5bab8ff16f4b1d5b60c9ed3b943ac6b6"
+PKG_VERSION="e72598d"
+PKG_SHA256="0751cd169345c7b69c8eeb1711934d4dbf6c6ef92ae4d520ee30a970d8902658"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi-binary-addons/visualization.spectrum/package.mk b/packages/mediacenter/kodi-binary-addons/visualization.spectrum/package.mk
index 8c06fa113f..9967f5b6f9 100644
--- a/packages/mediacenter/kodi-binary-addons/visualization.spectrum/package.mk
+++ b/packages/mediacenter/kodi-binary-addons/visualization.spectrum/package.mk
@@ -1,24 +1,25 @@
################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
+# This file is part of LibreELEC - https://libreelec.tv
+# Copyright (C) 2018-present Team LibreELEC
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
#
-# OpenELEC is free software: you can redistribute it and/or modify
+# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
-# OpenELEC is distributed in the hope that it will be useful,
+# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with OpenELEC. If not, see .
+# along with LibreELEC. If not, see .
################################################################################
PKG_NAME="visualization.spectrum"
-PKG_VERSION="b533965"
-PKG_SHA256="41173e5ef9058a8356e105fdc41f4facf14722fc9125ec2fc19f6ae1a1273e28"
+PKG_VERSION="063cd80"
+PKG_SHA256="192c684f343a2c51ae23d54a4da9d53f16f3d6183213d0d0f213c77db3da7c0f"
PKG_REV="2"
PKG_ARCH="any"
PKG_LICENSE="GPL"
diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk
index 246860ae71..343b3865ef 100644
--- a/packages/mediacenter/kodi/package.mk
+++ b/packages/mediacenter/kodi/package.mk
@@ -18,8 +18,8 @@
################################################################################
PKG_NAME="kodi"
-PKG_VERSION="593949a"
-PKG_SHA256="7a4ccfacd24461d5dfbba9be362372912ebc26dd6743e52b706907b6cc081be5"
+PKG_VERSION="87c7f9b"
+PKG_SHA256="97f8aec04fcc7a19890ae6f02520f375bbb7bb798d0fb229e486092dc0bc1ff1"
PKG_ARCH="any"
PKG_LICENSE="GPL"
PKG_SITE="http://www.kodi.tv"
diff --git a/packages/mediacenter/kodi/patches/kodi-100.14-use-alsa-and-pulse-together.patch b/packages/mediacenter/kodi/patches/kodi-100.14-use-alsa-and-pulse-together.patch
index 7fbca0cd66..a7bf93ed54 100644
--- a/packages/mediacenter/kodi/patches/kodi-100.14-use-alsa-and-pulse-together.patch
+++ b/packages/mediacenter/kodi/patches/kodi-100.14-use-alsa-and-pulse-together.patch
@@ -19,8 +19,8 @@ index 6e31a80..2e76053 100644
CWinSystemX11GLContext::CWinSystemX11GLContext()
{
- std::string envSink;
-- if (getenv("AE_SINK"))
-- envSink = getenv("AE_SINK");
+- if (getenv("KODI_AE_SINK"))
+- envSink = getenv("KODI_AE_SINK");
- if (StringUtils::EqualsNoCase(envSink, "ALSA"))
- {
- OPTIONALS::ALSARegister();
@@ -85,8 +85,8 @@ index 72ddf6a..79e81d5 100644
m_libinput(new CLibInputHandler)
{
- std::string envSink;
-- if (getenv("AE_SINK"))
-- envSink = getenv("AE_SINK");
+- if (getenv("KODI_AE_SINK"))
+- envSink = getenv("KODI_AE_SINK");
- if (StringUtils::EqualsNoCase(envSink, "ALSA"))
- {
- OPTIONALS::ALSARegister();
diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch
index 5300c1252b..bd5db50f8c 100644
--- a/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch
+++ b/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch
@@ -11222,10 +11222,10 @@ index 0000000000..75a1789c25
+
diff --git a/libavcodec/arm/rpi_hevcpred_intra_filter_neon.S b/libavcodec/arm/rpi_hevcpred_intra_filter_neon.S
new file mode 100644
-index 0000000000..11773f918e
+index 0000000000..6ce3d3ca8d
--- /dev/null
+++ b/libavcodec/arm/rpi_hevcpred_intra_filter_neon.S
-@@ -0,0 +1,878 @@
+@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2018 John Cox (for Raspberry Pi)
+ *
@@ -11259,7 +11259,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+@
@@ -11307,16 +11307,17 @@ index 0000000000..11773f918e
+@
+@ Extend values:
+@ d_l scalar contains value for L & DL
++@ if DL avail then this is is DL[0] so we don't need to load that
+@ d_ul scalar containing value for UL
+@ d_u scalar containing value for U
+@ d_ur scalar containing value for UR
+@ If DL avail then d_l == b_dl elif L avail then d_l == a_l else...
-+@ This means that L-filter works even if nreq DL (we never filter
++@ This means that L-light-filter works even if nreq DL (we never filter
+@ req-DL without req-L, but we do filter req-L without req-DL)
+@ If UR avail then d_ur == a_ur so U-filter good too
+@
+@ Data load pointers (only load if req & avail):
-+@ r4 DL
++@ r4 DL + stride
+@ r10 L
+@ r6 U
+@ r5 UR
@@ -11325,7 +11326,7 @@ index 0000000000..11773f918e
+@ r2 req
+@ r7 req & avail
+@ r3 L + stride
-+@ r8 DL + stride
++@ r8 DL + stride * 2
+@ r9 stride * 2
+@ cs Load U
+@ mi Load UR
@@ -11376,7 +11377,7 @@ index 0000000000..11773f918e
+ itt vc
+ movvc r8, r7
+ movvc r6, r7
-+ vld1.\d_type {\d_l }, [r4]
++ vld1.\d_type {\d_l }, [r4], r9
+ tst r3, #AVAIL_UR
+ vld1.\d_type {\d_u }, [r6]
+ it eq
@@ -11399,7 +11400,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11428,10 +11429,9 @@ index 0000000000..11773f918e
+ vld1.8 {d0[3]}, [r3]
+1:
+ bcc 1f
-+ vld1.8 {d0[4]}, [r4], r9
-+ vld1.8 {d0[5]}, [r8], r9
-+ vld1.8 {d0[6]}, [r4]
-+ vld1.8 {d0[7]}, [r8]
++ vld1.8 {d0[5]}, [r4], r9
++ vld1.8 {d0[6]}, [r8]
++ vld1.8 {d0[7]}, [r4]
+1:
+ vstr d1, [r1] @ Up
+ vst1.8 {d31[7]}, [r12]
@@ -11448,7 +11448,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11474,10 +11474,9 @@ index 0000000000..11773f918e
+ vld1.16 {d0[3]}, [r3]
+1:
+ bcc 1f
-+ vld1.16 {d1[0]}, [r4], r9
-+ vld1.16 {d1[1]}, [r8], r9
-+ vld1.16 {d1[2]}, [r4]
-+ vld1.16 {d1[3]}, [r8]
++ vld1.16 {d1[1]}, [r4], r9
++ vld1.16 {d1[2]}, [r8]
++ vld1.16 {d1[3]}, [r4]
+1:
+ vst1.16 {q1}, [r1] @ Up
+ vst1.16 {d31[3]}, [r12]
@@ -11494,7 +11493,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11524,14 +11523,13 @@ index 0000000000..11773f918e
+ vld1.8 {d0[7]}, [r3]
+1:
+ bcc 1f
-+ vld1.8 {d1[0]}, [r4], r9
-+ vld1.8 {d1[1]}, [r8], r9
-+ vld1.8 {d1[2]}, [r4], r9
-+ vld1.8 {d1[3]}, [r8], r9
-+ vld1.8 {d1[4]}, [r4], r9
-+ vld1.8 {d1[5]}, [r8], r9
-+ vld1.8 {d1[6]}, [r4]
-+ vld1.8 {d1[7]}, [r8]
++ vld1.8 {d1[1]}, [r4], r9
++ vld1.8 {d1[2]}, [r8], r9
++ vld1.8 {d1[3]}, [r4], r9
++ vld1.8 {d1[4]}, [r8], r9
++ vld1.8 {d1[5]}, [r4], r9
++ vld1.8 {d1[6]}, [r8]
++ vld1.8 {d1[7]}, [r4]
+1:
+ tst r2, #FILTER_LIGHT
+ add r12, r0, #-pw
@@ -11582,7 +11580,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11621,16 +11619,15 @@ index 0000000000..11773f918e
+1:
+ bcc 1f
+ ldr r12, [sp, #dl_size]
-+ vld1.16 {d2[0]}, [r4], r9
-+ vld1.16 {d2[1]}, [r8], r9
++ vld1.16 {d2[1]}, [r4], r9
+ cmp r12, #p_size
-+ vld1.16 {d2[2]}, [r4], r9
-+ vld1.16 {d2[3]}, [r8], r9
++ vld1.16 {d2[2]}, [r8], r9
++ vld1.16 {d2[3]}, [r4], r9
+ blt 2f
-+ vld1.16 {d3[0]}, [r4], r9
-+ vld1.16 {d3[1]}, [r8], r9
-+ vld1.16 {d3[2]}, [r4]
-+ vld1.16 {d3[3]}, [r8]
++ vld1.16 {d3[0]}, [r8], r9
++ vld1.16 {d3[1]}, [r4], r9
++ vld1.16 {d3[2]}, [r8]
++ vld1.16 {d3[3]}, [r4]
+ b 1f
+2:
+ vdup.16 d3, d2[3]
@@ -11685,7 +11682,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11745,27 +11742,26 @@ index 0000000000..11773f918e
+ vld1.16 {d3[3]}, [r3]
+1:
+ bcc 1f
-+ vld1.16 {d4[0]}, [r4], r9
-+ vld1.16 {d4[1]}, [r8], r9
++ vld1.16 {d4[1]}, [r4], r9
+ cmp r12, #4
-+ vld1.16 {d4[2]}, [r4], r9
-+ vld1.16 {d4[3]}, [r8], r9
++ vld1.16 {d4[2]}, [r8], r9
++ vld1.16 {d4[3]}, [r4], r9
+ ble 2f
-+ vld1.16 {d5[0]}, [r4], r9
-+ vld1.16 {d5[1]}, [r8], r9
++ vld1.16 {d5[0]}, [r8], r9
++ vld1.16 {d5[1]}, [r4], r9
+ cmp r12, #12
-+ vld1.16 {d5[2]}, [r4], r9
-+ vld1.16 {d5[3]}, [r8], r9
++ vld1.16 {d5[2]}, [r8], r9
++ vld1.16 {d5[3]}, [r4], r9
+ blt 3f
-+ vld1.16 {d6[0]}, [r4], r9
-+ vld1.16 {d6[1]}, [r8], r9
-+ vld1.16 {d6[2]}, [r4], r9
-+ vld1.16 {d6[3]}, [r8], r9
++ vld1.16 {d6[0]}, [r8], r9
++ vld1.16 {d6[1]}, [r4], r9
++ vld1.16 {d6[2]}, [r8], r9
++ vld1.16 {d6[3]}, [r4], r9
+ ble 4f
-+ vld1.16 {d7[0]}, [r4], r9
-+ vld1.16 {d7[1]}, [r8], r9
-+ vld1.16 {d7[2]}, [r4]
-+ vld1.16 {d7[3]}, [r8]
++ vld1.16 {d7[0]}, [r8], r9
++ vld1.16 {d7[1]}, [r4], r9
++ vld1.16 {d7[2]}, [r8]
++ vld1.16 {d7[3]}, [r4]
+ b 1f
+2: vdup.16 d5, d4[3]
+3: vdup.16 d6, d5[3]
@@ -11855,7 +11851,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11882,10 +11878,9 @@ index 0000000000..11773f918e
+ vld1.32 {d1[1]}, [r3]
+1:
+ bcc 1f
-+ vld1.32 {d2[0]}, [r4], r9
-+ vld1.32 {d2[1]}, [r8], r9
-+ vld1.32 {d3[0]}, [r4]
-+ vld1.32 {d3[1]}, [r8]
++ vld1.32 {d2[1]}, [r4], r9
++ vld1.32 {d3[0]}, [r8]
++ vld1.32 {d3[1]}, [r4]
+1:
+ vst1.32 {q2, q3 }, [r1] @ Up
+ vst1.32 {d31[1]}, [r12]
@@ -11902,7 +11897,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -11946,16 +11941,15 @@ index 0000000000..11773f918e
+1:
+ bcc 1f
+ ldr r12, [sp, #dl_size]
-+ vld1.32 {d4[0]}, [r4], r9
-+ vld1.32 {d4[1]}, [r8], r9
++ vld1.32 {d4[1]}, [r4], r9
+ cmp r12, #p_size
-+ vld1.32 {d5[0]}, [r4], r9
-+ vld1.32 {d5[1]}, [r8], r9
++ vld1.32 {d5[0]}, [r8], r9
++ vld1.32 {d5[1]}, [r4], r9
+ blt 2f
-+ vld1.32 {d6[0]}, [r4], r9
-+ vld1.32 {d6[1]}, [r8], r9
-+ vld1.32 {d7[0]}, [r4]
-+ vld1.32 {d7[1]}, [r8]
++ vld1.32 {d6[0]}, [r8], r9
++ vld1.32 {d6[1]}, [r4], r9
++ vld1.32 {d7[0]}, [r8]
++ vld1.32 {d7[1]}, [r4]
+ b 1f
+2:
+ vdup.32 q3, d5[1]
@@ -11976,7 +11970,7 @@ index 0000000000..11773f918e
+@ const pixel * const src_l, [sp, #0]
+@ const pixel * const src_u, [sp, #4]
+@ const pixel * const src_ur, [sp, #8]
-+@ const unsigned int stride, [sp, #12] (bytes)
++@ const unsigned int stride, [sp, #12] (pels)
+@ const unsigned int top_right_size, [sp, #16]
+@ const unsigned int down_left_size) [sp, #20]
+
@@ -12040,28 +12034,28 @@ index 0000000000..11773f918e
+1:
+ bcc 1f
+ ldr r12, [sp, #dl_size]
++ vdup.32 d16, d30[0] @ d16[0] = d30[0]
+ add lr, r0, #(pw << log2_s)
-+ vld1.32 {d16[0]}, [r4], r9
-+ vld1.32 {d16[1]}, [r8], r9
++ vld1.32 {d16[1]}, [r4], r9
+ cmp r12, #4
-+ vld1.32 {d17[0]}, [r4], r9
-+ vld1.32 {d17[1]}, [r8], r9
++ vld1.32 {d17[0]}, [r8], r9
++ vld1.32 {d17[1]}, [r4], r9
+ ble 2f
-+ vld1.32 {d18[0]}, [r4], r9
-+ vld1.32 {d18[1]}, [r8], r9
++ vld1.32 {d18[0]}, [r8], r9
++ vld1.32 {d18[1]}, [r4], r9
+ cmp r12, #12
-+ vld1.32 {d19[0]}, [r4], r9
-+ vld1.32 {d19[1]}, [r8], r9
++ vld1.32 {d19[0]}, [r8], r9
++ vld1.32 {d19[1]}, [r4], r9
+ blt 3f
-+ vld1.32 {d20[0]}, [r4], r9
-+ vld1.32 {d20[1]}, [r8], r9
-+ vld1.32 {d21[0]}, [r4], r9
-+ vld1.32 {d21[1]}, [r8], r9
++ vld1.32 {d20[0]}, [r8], r9
++ vld1.32 {d20[1]}, [r4], r9
++ vld1.32 {d21[0]}, [r8], r9
++ vld1.32 {d21[1]}, [r4], r9
+ ble 4f
-+ vld1.32 {d22[0]}, [r4], r9
-+ vld1.32 {d22[1]}, [r8], r9
-+ vld1.32 {d23[0]}, [r4]
-+ vld1.32 {d23[1]}, [r8]
++ vld1.32 {d22[0]}, [r8], r9
++ vld1.32 {d22[1]}, [r4], r9
++ vld1.32 {d23[0]}, [r8]
++ vld1.32 {d23[1]}, [r4]
+ b 5f
+2: vdup.32 q9, d17[1]
+3: vdup.32 q10, d19[1]
@@ -12106,10 +12100,10 @@ index 0000000000..11773f918e
+
diff --git a/libavcodec/arm/rpi_hevcpred_intra_hv_neon.S b/libavcodec/arm/rpi_hevcpred_intra_hv_neon.S
new file mode 100644
-index 0000000000..ccf13a081f
+index 0000000000..afafb6bc44
--- /dev/null
+++ b/libavcodec/arm/rpi_hevcpred_intra_hv_neon.S
-@@ -0,0 +1,888 @@
+@@ -0,0 +1,922 @@
+/*
+ * Copyright (c) 2018 John Cox (for Raspberry Pi)
+ *
@@ -12153,27 +12147,32 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_4_neon_8, export=1
-+ vld1.32 {d0[0] }, [r1 :32] @ Up
-+ ldrb r12, [r2, #-1] @ Up-left
-+ vld1.32 {d24[0]}, [r2 :32] @ left
-+
-+ vdup.8 d4, r12
-+ vmov.u8 d6, #128
-+ vhsub.u8 d24, d4
-+
-+ veor.8 d2, d0, d6 @ Make -128,127 so we can qadd
-+ mov r1, #4
-+ vdup.8 d2, d2[0]
-+ vqadd.s8 d24, d2
-+ vmov.i64 d4, #0xff
-+ veor.8 d24, d6
-+
-+1:
-+ vbit.8 d0, d24, d4
-+ vext.8 d24, d24, #1
-+ subs r1, #1
-+ vst1.32 {d0[0] }, [r0 :32], r3
-+ bne 1b
++ ldrb ip, [r2, #-1] @ Top-left
++ vld1.32 {d0[0]}, [r2 :32] @ Left
++ add r2, r0, r3
++ vld1.8 {d1[]}, [r1]
++ lsl r3, #1
++ vdup.8 d4, ip
++ vmov.i8 d2, #128
++ vhsub.u8 d4, d0, d4
++ veor d1, d2
++ vld1.32 {d0[0]}, [r1 :32] @ Top
++ vqadd.s8 d1, d4
++ vmov.i64 d3, #0xff
++ vmov d4, d0
++ veor d5, d1, d2
++ veor d1, d1, d2
++ vbit d0, d1, d3
++ vshr.u64 d5, #8
++ vst1.32 {d0[0]}, [r0], r3
++ vshr.u64 d1, #16
++ vbit d4, d5, d3
++ vshr.u64 d5, #16
++ vst1.32 {d4[0]}, [r2], r3
++ vbit d0, d1, d3
++ vst1.32 {d0[0]}, [r0]
++ vbit d4, d5, d3
++ vst1.32 {d4[0]}, [r2]
+
+ bx lr
+endfunc
@@ -12186,26 +12185,26 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_8_neon_8, export=1
-+ vld1.8 {d0 }, [r1 :64] @ Up
-+ ldrb r12, [r2, #-1] @ Up-left
-+ vld1.8 {d24}, [r2 :64] @ left
-+
-+ vdup.8 d4, r12
-+ vmov.u8 d6, #128
-+ vhsub.u8 d24, d4
-+
-+ veor.8 d2, d0, d6 @ Make -128,127 so we can qadd
-+ mov r1, #8
-+ vdup.8 d2, d2[0]
-+ vqadd.s8 d24, d2
-+ vmov.i64 d4, #0xff
-+ veor.8 d24, d6
-+
++ ldrb ip, [r2, #-1] @ Top-left
++ vld1.8 {d0}, [r2 :64] @ Left
++ vmov.i8 d1, #128
++ vld1.8 {d2[]}, [r1]
++ vld1.8 {d3}, [r1 :64] @ Top
++ vdup.8 d4, ip
++ vhsub.u8 d4, d0, d4
++ veor d2, d1
++ vmov.i64 d0, #0xff
++ mov r1, #8
++ vqadd.s8 d2, d4, d2
++ veor d1, d2, d1
+1:
-+ vbit.8 d0, d24, d4
-+ vext.8 d24, d24, #1
-+ subs r1, #1
-+ vst1.8 {d0 }, [r0 :64], r3
++ vbit d3, d1, d0
++ vshr.u64 d1, #8
++ vst1.8 {d3}, [r0 :64], r3
++ subs r1, #2
++ vbit d3, d1, d0
++ vshr.u64 d1, #8
++ vst1.8 {d3}, [r0 :64], r3
+ bne 1b
+
+ bx lr
@@ -12219,26 +12218,28 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_16_neon_8, export=1
-+ vld1.8 {q0 }, [r1 :128] @ Up
-+ ldrb r12, [r2, #-1] @ Up-left
-+ vld1.8 {q12}, [r2 :128] @ left
-+
-+ vdup.8 q2, r12
-+ vmov.u8 q3, #128
-+ vhsub.u8 q12, q2
-+
-+ veor.8 d2, d0, d6 @ Make -128,127 so we can qadd
-+ vdup.8 q1, d2[0]
-+ vqadd.s8 q12, q1
-+ veor.8 q12, q3
-+
-+ vmov.i64 d4, #0xff
-+ mov r1, #16
++ ldrb ip, [r2, #-1] @ Top-left
++ vld1.8 {q0}, [r2 :128] @ Left
++ vdup.8 q1, ip
++ vld1.8 {d4[],d5[]}, [r1]
++ vhsub.u8 q0, q1
++ vmov.i8 q1, #128
++ veor q2, q1
++ vmov.i64 d16, #0xff
++ vqadd.s8 q0, q2
++ vld1.8 {q3}, [r1 :128] @ Top
++ mov r1, #16
++ veor q0, q1
++ vmov q1, q3
++ vext.8 q2, q0, q0, #1
+1:
-+ vbit.8 d0, d24, d4
-+ vext.8 q12, q12, #1
-+ subs r1, #1
-+ vst1.8 {q0 }, [r0 :128], r3
++ vbit d2, d0, d16
++ vbit d6, d4, d16
++ vext.8 q0, q0, q0, #2
++ subs r1, #2
++ vst1.8 {q1}, [r0 :128], r3
++ vext.8 q2, q2, q2, #2
++ vst1.8 {q3}, [r0 :128], r3
+ bne 1b
+
+ bx lr
@@ -12299,7 +12300,9 @@ index 0000000000..ccf13a081f
+ mov r1, #4
+1:
+ vst1.16 {q0 }, [r0 :128], r3
-+ subs r1, #1
++ subs r1, #2
++ vst1.16 {q0 }, [r2 :128], r3
++ vst1.16 {q0 }, [r0 :128], r3
+ vst1.16 {q0 }, [r2 :128], r3
+ bne 1b
+
@@ -12561,31 +12564,36 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_4_neon_10, export=1
-+ vld1.16 {d0 }, [r1 :64] @ Up
-+ ldrh r12, [r2, #-2] @ Up-left
-+ vld1.16 {d24}, [r2 :64] @ left
-+
-+ vdup.16 d4, r12
-+ lsl r3, #1
-+ vhsub.u16 d24, d4
-+
-+ vdup.16 d6, d0[0]
-+ vmov.s16 d4, #0
-+ vadd.i16 d24, d6
-+
-+ vmov.s16 d6, #0x3ff
-+ vmax.s16 d24, d4
-+ vmov.i64 d4, #0xffff
-+ vmin.s16 d24, d6
-+
-+ mov r1, #4
-+1:
-+ vbit.8 d0, d24, d4
-+ vext.16 d24, d24, #1
-+ subs r1, #1
-+ vst1.16 {d0 }, [r0 :64], r3
-+ bne 1b
-+
++ ldrh ip, [r2, #-2] @ Top-left
++ vld1.16 {d0}, [r2 :64] @ Left
++ vmov.i16 d2, #0
++ vld1.16 {d1[]}, [r1]
++T lsl r3, #1
++ vdup.16 d4, ip
++ vmov.i16 d3, #0x3ff
++ vld1.16 {d5}, [r1 :64] @ Top
++ vhsub.u16 d4, d0, d4
++ vmov.i64 d0, #0xffff
++A add r2, r0, r3, lsl #1
++T add r2, r0, r3
++ vadd.i16 d1, d1, d4
++ vmov d6, d5
++ vmax.s16 d1, d1, d2
++ vmin.s16 d2, d1, d3
++ vmin.s16 d1, d1, d3
++ vbit d5, d1, d0
++A lsl r3, #2
++T lsl r3, #1
++ vshr.u64 d2, #16
++ vshr.u64 d1, #32
++ vbit d6, d2, d0
++ vst1.16 {d5}, [r0], r3
++ vshr.u64 d2, #32
++ vst1.16 {d6}, [r2], r3
++ vbit d5, d1, d0
++ vst1.16 {d5}, [r0]
++ vbit d6, d2, d0
++ vst1.16 {d6}, [r2]
+ bx lr
+endfunc
+
@@ -12597,29 +12605,30 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_8_neon_10, export=1
-+ vld1.16 {q0 }, [r1 :128] @ Up
-+ ldrh r12, [r2, #-2] @ Up-left
-+ vld1.16 {q12}, [r2 :128] @ left
-+
-+ vdup.16 q2, r12
-+ lsl r3, #1
-+ vhsub.u16 q12, q2
-+
-+ vdup.16 q3, d0[0]
-+ vmov.s16 q2, #0
-+ vadd.i16 q12, q3
-+
-+ vmov.s16 q3, #0x3ff
-+ vmax.s16 q12, q2
-+ vmin.s16 q12, q3
-+
-+ vmov.i64 d4, #0xffff
-+ mov r1, #8
++ ldrh ip, [r2, #-2] @ Top-left
++ vld1.16 {q0}, [r2 :128] @ Left
++ lsl r3, #1
++ vdup.16 q1, ip
++ vld1.16 {d4[],d5[]}, [r1]
++ vhsub.u16 q0, q0, q1
++ vmov.i16 q1, #0
++ vadd.i16 q0, q2
++ vmov.i16 q2, #0x3ff
++ vld1.16 {q3}, [r1 :128] @ Top
++ mov r1, #8
++ vmax.s16 q0, q1
++ vmov q1, q3
++ vmin.s16 q0, q2
++ vmov.i64 d16, #0xffff
++ vext.16 q2, q0, q0, #1
+1:
-+ vbit.8 d0, d24, d4
-+ vext.16 q12, q12, #1
-+ subs r1, #1
-+ vst1.16 {q0 }, [r0 :128], r3
++ vbit d2, d0, d16
++ vbit d6, d4, d16
++ vext.16 q0, q0, q0, #2
++ subs r1, #2
++ vst1.16 {q1}, [r0 :128], r3
++ vext.16 q2, q2, q2, #2
++ vst1.16 {q3}, [r0 :128], r3
+ bne 1b
+
+ bx lr
@@ -12633,34 +12642,49 @@ index 0000000000..ccf13a081f
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_vertical_16_neon_10, export=1
-+ vld1.16 {q0, q1 }, [r1 :128] @ Up
-+ ldrh r12, [r2, #-2] @ Up-left
-+ vld1.16 {q12, q13}, [r2 :128] @ left
-+
-+ vdup.16 q2, r12
-+ lsl r3, #1
-+ vhsub.u16 q12, q2
-+ vhsub.u16 q13, q2
-+
-+ vdup.16 q3, d0[0]
-+ vmov.s16 q2, #0
-+ vadd.i16 q12, q3
-+ vadd.i16 q13, q3
-+
-+ vmov.s16 q3, #0x3ff
-+ vmax.s16 q12, q2
-+ vmax.s16 q13, q2
-+ vmin.s16 q12, q3
-+ vmin.s16 q13, q3
-+
-+ vmov.i64 d4, #0xffff
-+ mov r1, #16
++ ldrh ip, [r2, #-2] @ Top-left
++ vld1.16 {q0-q1}, [r2 :128] @ Left
++T lsl r3, #1
++ vdup.16 q2, ip
++A add r2, r0, r3, lsl #1
++T add r2, r0, r3
++ vld1.16 {d6[],d7[]}, [r1]
++A lsl r3, #2
++T lsl r3, #1
++ vhsub.u16 q0, q2
++ vhsub.u16 q1, q2
++ vadd.i16 q0, q3
++ vadd.i16 q1, q3
++ vmov.i16 q2, #0
++ vld1.16 {q8-q9}, [r1 :128] @ Top
++ mov r1, #0
++ vmov.i16 q3, #0x3ff
++ vmax.s16 q0, q2
++ vmax.s16 q1, q2
++ vmin.s16 q0, q3
++ vmin.s16 q1, q3
++ vmov q10, q8
++ vmov q11, q9
++ vext.16 q2, q0, q1, #1
++ vext.16 q3, q1, q1, #1
++ vmov.i64 d24, #0xffff
+1:
-+ vbit.8 d0, d24, d4
-+ vext.16 q12, q13, #1
-+ vext.16 q13, q13, #1
-+ subs r1, #1
-+ vst1.16 {q0, q1 }, [r0 :128], r3
++ vbit d16, d0, d24
++ vbit d20, d4, d24
++ vext.16 q0, q0, q0, #2
++ subs r1, #1<<30
++ vst1.16 {q8-q9}, [r0 :128], r3
++ vext.16 q2, q2, q2, #2
++ vst1.16 {q10-q11}, [r2 :128], r3
++ bne 1b
++1:
++ vbit d16, d2, d24
++ vbit d20, d6, d24
++ vext.16 q1, q1, q1, #2
++ subs r1, #1<<30
++ vst1.16 {q8-q9}, [r0 :128], r3
++ vext.16 q3, q3, q3, #2
++ vst1.16 {q10-q11}, [r2 :128], r3
+ bne 1b
+
+ bx lr
@@ -12675,11 +12699,13 @@ index 0000000000..ccf13a081f
+
+function ff_hevc_rpi_pred_vertical_32_neon_10, export=1
+ vldm r1, { q0-q3 } @ Up
-+ mov r1, #32
++ lsl r3, #1
++ mov r1, #32
++ add r2, r0, #32
+1:
-+ subs r1, #1
-+ vstm r0, { q0-q3 }
-+ add r0, r0, r3, lsl #1
++ vst1.16 {q0-q1}, [r0 :128], r3
++ subs r1, #1
++ vst1.16 {q2-q3}, [r2 :128], r3
+ bne 1b
+
+ bx lr
@@ -12735,11 +12761,13 @@ index 0000000000..ccf13a081f
+
+function ff_hevc_rpi_pred_vertical_c_16_neon_10, export=1
+ vldm r1, { q0-q3 } @ Up
-+ mov r1, #16
++ lsl r3, #2
++ mov r1, #16
++ add r2, r0, #32
+1:
-+ subs r1, #1
-+ vstm r0, { q0-q3 }
-+ add r0, r0, r3, lsl #2
++ vst1.16 {q0-q1}, [r0 :128], r3
++ subs r1, #1
++ vst1.16 {q2-q3}, [r2 :128], r3
+ bne 1b
+
+ bx lr
@@ -13000,10 +13028,10 @@ index 0000000000..ccf13a081f
+
diff --git a/libavcodec/arm/rpi_hevcpred_intra_planar_neon.S b/libavcodec/arm/rpi_hevcpred_intra_planar_neon.S
new file mode 100644
-index 0000000000..9fb3633862
+index 0000000000..e35896a102
--- /dev/null
+++ b/libavcodec/arm/rpi_hevcpred_intra_planar_neon.S
-@@ -0,0 +1,930 @@
+@@ -0,0 +1,1034 @@
+/*
+ * Copyright (c) 2017 John Cox (for Raspberry Pi)
+ *
@@ -13035,6 +13063,9 @@ index 0000000000..9fb3633862
+@ ( nTbS - 1 - y ) * p[ x ][ -1 ] +
+@ ( y + 1 ) * p[ -1 ][ nTbS ] + nTbS ) >> ( Log2( nTbS ) + 1 )
+
++@ All 10-bit functions would work with 9
++
++
+@ ff_hevc_rpi_pred_planar_8_neon_8
+@ uint8_t *_src, [r0]
+@ const uint8_t *_top, [r1]
@@ -13042,52 +13073,93 @@ index 0000000000..9fb3633862
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_planar_4_neon_8, export=1
-+ adr r12, nb_3_0_1_4
-+ vld1.8 {d24}, [r2] @ Left
-+ vld1.8 {d0 }, [r1] @ Up
-+ vld1.8 {q8 }, [r12 :128] @ 3..
+
-+ vdup.8 d30, d24[4]
-+ vdup.8 d31, d0[4]
-+
-+ vdup.32 d0, d0[0] @ copy lo -> hi
-+ vsubl.u8 q2, d30, d0 @ Add set up
-+
-+ vshll.u8 q0, d0, #2
-+ add r1, r0, r3
-+ vmlal.u8 q0, d17, d31 @ Acc set up - q8-q9 free
-+
-+ vshl.i16 q3, q2, #1
-+ vadd.i16 d0, d4
-+ vadd.i16 d1, d6
-+ lsl r3, #1
-+ vadd.i16 q1, q0, q3
-+
-+ vdup.u8 d20, d24[0]
-+ vdup.u8 d21, d24[1]
-+ vdup.u8 d22, d24[2]
-+ vdup.u8 d23, d24[3]
-+
-+ vtrn.32 d20, d21
-+ vtrn.32 d22, d23
-+
-+ vmull.u8 q10, d16, d20
-+ vmull.u8 q11, d16, d22
-+ vadd.i16 q10, q0
-+ vadd.i16 q11, q1
-+
-+ vrshrn.u16 d28, q10, #3
-+ vrshrn.u16 d29, q11, #3
-+
-+ vst1.32 {d28[0]}, [r0 :32], r3
-+ vst1.32 {d28[1]}, [r1 :32], r3
-+ vst1.32 {d29[0]}, [r0 :32]
-+ vst1.32 {d29[1]}, [r1 :32]
++ vld1.8 {d0}, [r1] @ Top
++ adr ip, nb_3_0_1_4
++ vld1.8 {d1}, [r2] @ Left
++ vmov.i64 d2, #0xffffffff
++ vldr d3, [ip, #8] @ {1,2,3,4,1,2,3,4}
++ add r1, r0, r3
++ vdup.32 d4, d0[0] @ {t0,t1,t2,t3,t0,t1,t2,t3}
++ vdup.8 d0, d0[4] @ {t4,t4,t4,t4,t4,t4,t4,t4}
++ vdup.8 d5, d1[4] @ {l4,l4,l4,l4,l4,l4,l4,l4}
++ vdup.8 d6, d1[0] @ {l0,l0,l0,l0,l0,l0,l0,l0}
++ vshll.u8 q8, d4, #2
++ lsl r3, #1
++ vsubl.u8 q2, d5, d4
++ vmlal.u8 q8, d0, d3
++ vld1.8 {d0}, [ip] @ {3,2,1,0,3,2,1,0}
++ vdup.8 d7, d1[1] @ {l1,l1,l1,l1,l1,l1,l1,l1}
++ vshl.s16 q9, q2, #1
++ vbif d6, d7, d2 @ {l0,l0,l0,l0,l1,l1,l1,l1}
++ vadd.i16 d16, d4
++ vdup.8 d7, d1[2] @ {l2,l2,l2,l2,l2,l2,l2,l2}
++ vadd.i16 d17, d18
++ vdup.8 d1, d1[3] @ {l3,l3,l3,l3,l3,l3,l3,l3}
++ vadd.i16 q2, q8, q9
++ vmlal.u8 q8, d0, d6
++ vbif d7, d1, d2 @ {l2,l2,l2,l2,l3,l3,l3,l3}
++ vmlal.u8 q2, d0, d7
++ vrshrn.i16 d0, q8, #3
++ vst1.32 d0[0], [r0 :32], r3
++ vst1.32 d0[1], [r1 :32], r3
++ vrshrn.i16 d0, q2, #3
++ vst1.32 d0[0], [r0 :32]
++ vst1.32 d0[1], [r1 :32]
+
+ bx lr
+endfunc
+
+
++@ ff_hevc_rpi_pred_planar_4_neon_10
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_4_neon_10, export=1
++ @ Load from bytes & expand later - at the very least this uses less
++ @ memory than having a short table
++ vld1.16 {q0}, [r1 :64] @ Top
++ adr ip, nbh_3_0_1_4
++ vldr d2, [r2, #8] @ Left (lower)
++ vldr d3, [ip, #8] @ {1,2,3,4}
++T lsl r3, #1
++ vshl.s16 d4, d0, #2
++ vdup.16 d1, d1[0] @ {t4,t4,t4,t4}
++ vldr d5, [r2] @ Left (upper)
++ vdup.16 d2, d2[0] @ {l4,l4,l4,l4}
++ vldr d6, [ip] @ {3,2,1,0}
++ vmla.i16 d4, d3, d1 @ Acc set up
++ vsub.i16 d0, d2, d0 @ Add set up
++ vmov d7, d6
++ vdup.16 d2, d5[0]
++ vdup.16 d3, d5[1]
++ vdup.16 d16, d5[2]
++ vadd.i16 d18, d0, d4
++ vshl.s16 d0, #1 @ x2
++ vadd.i16 d19, d0, d4
++ vdup.16 d17, d5[3]
++ vadd.i16 d4, d0, d18
++A add r1, r0, r3, lsl #1
++T add r1, r0, r3
++ vadd.i16 d5, d0, d19
++A lsl r3, #2
++T lsl r3, #1
++ vmla.i16 q9, q1, q3
++ vmla.i16 q2, q8, q3
++ vrshr.u16 q0, q9, #3
++ vst1.16 {d0}, [r0], r3
++ vrshr.u16 d2, d4, #3
++ vst1.16 {d1}, [r1], r3
++ vrshr.u16 d3, d5, #3
++ vst1.16 {d2}, [r0]
++ vst1.16 {d3}, [r1]
++
++ bx lr
++endfunc
++
++
+@ ff_hevc_rpi_pred_planar_8_neon_8
+@ uint8_t *_src, [r0]
+@ const uint8_t *_top, [r1]
@@ -13095,38 +13167,43 @@ index 0000000000..9fb3633862
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_planar_8_neon_8, export=1
-+ adr r12, nb_7_0_1_8
-+ vld1.8 {q12}, [r2] @ Left
-+ vld1.8 {q0 }, [r1] @ Up
-+ vld1.8 {q8 }, [r12 :128] @ 7..
+
-+ vdup.8 d30, d25[0]
-+ vdup.8 d31, d1[0]
++ vld1.8 {q0}, [r1] @ Top
++ adr ip, nb_7_0_1_8
++ vldr d2, [r2, #8] @ Left (lower)
++ mov r1, #8
++ vldr d3, [ip, #8] @ {1,2,3,4,5,6,7,8}
++ vshll.u8 q2, d0, #3
++ vdup.8 d1, d1[0] @ {t8,t8,t8,t8,t8,t8,t8,t8}
++ vdup.8 d2, d2[0] @ {l8,l8,l8,l8,l8,l8,l8,l8}
++ vldr d6, [r2] @ Left (upper)
++ vmlal.u8 q2, d3, d1
++ vsubl.u8 q0, d2, d0
++ vldr d7, [ip] @ {7,6,5,4,3,2,1,0}
+
-+ mov r1, #8
-+ vsubl.u8 q2, d30, d0 @ Add set up
++@ u8 7..0 [1] d7
++@ u8 left[y] [1] d6
++@ u16 acc [2] q2 (even rows) or q8 (odd rows) = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q0 = p[-1][nTbs] - p[x][-1]
+
-+ vshll.u8 q0, d0, #3
-+ vmlal.u8 q0, d17, d31 @ Acc set up - q8-q9 free
-+
-+@ u8 7..0 [1] d16
-+@ u8 left[y] [1] d24
-+@ u16 acc [2] q0 .. q1 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [2] q2 .. q3 = p[-1][nTbs] - p[x][-1]
++ vdup.8 d2, d6[0]
++ vadd.i16 q2, q0
++ vdup.8 d3, d6[1]
++ vadd.i16 q8, q2, q0
+1:
-+ vadd.i16 q0, q2
-+
-+ vdup.u8 d20, d24[0]
-+ vext.8 d24, d24, #1
-+
-+ vmull.u8 q10, d16, d20
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d28, q10, #4
-+
-+ subs r1, #1
-+ vst1.8 {d28}, [r0 :64], r3
-+
++ vmlal.u8 q2, d7, d2
++ subs r1, #2
++ vadd.i16 q9, q8, q0
++ vmlal.u8 q8, d7, d3
++ vdup.8 d2, d6[2]
++ vdup.8 d3, d6[3]
++ vrshrn.i16 d20, q2, #4
++ vshr.u64 d6, #16
++ vmov q2, q9
++ vst1.8 {d20}, [r0], r3
++ vrshrn.i16 d20, q8, #4
++ vadd.i16 q8, q2, q0
++ vst1.8 {d20}, [r0], r3
+ bne 1b
+
+ bx lr
@@ -13134,338 +13211,71 @@ index 0000000000..9fb3633862
+endfunc
+
+
-+@ ff_hevc_rpi_pred_planar_16_neon_8
++@ ff_hevc_rpi_pred_planar_8_neon_10
+@ uint8_t *_src, [r0]
+@ const uint8_t *_top, [r1]
+@ const uint8_t *_left, [r2]
+@ ptrdiff_t stride) [r3]
+
-+function ff_hevc_rpi_pred_planar_16_neon_8, export=1
-+ vld1.8 {q12}, [r2 :128] @ Left
-+ ldrb r2, [r2, #16] @ Down left - could have this in q13, but avoid that much overrread
-+ adr r12, nb_15_0_1_16
-+ vld1.8 {q0 }, [r1 :128] @ Up
-+ ldrb r1, [r1, #16] @ Up-right
-+ vld1.8 {q8, q9 }, [r12 :128] @ 15...
++function ff_hevc_rpi_pred_planar_8_neon_10, export=1
+
-+ vdup.8 d30, r2
-+ vdup.8 d31, r1
++ adr ip, nb_7_0_1_8
++ vld1.16 {q0}, [r1 :128]! @ Top (left)
++ lsl r3, #1
++ vld1.16 {q1}, [ip :128] @ {7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8}
++ add ip, r2, #16
++ vld1.16 {d4[],d5[]}, [r1] @ Top (right)
++ mov r1, #8-2
++ vshl.s16 q3, q0, #3
++ vmovl.u8 q8, d3 @ {1,2,3,4,5,6,7,8}
++ vld1.16 {d18[],d19[]}, [ip] @ Left (lower)
++ vmla.i16 q3, q8, q2 @ Acc set up
++ vsub.i16 q0, q9, q0 @ Add set up
++ vmovl.u8 q1, d2 @ {7,6,5,4,3,2,1,0}
++ vadd.i16 q2, q3, q0
+
-+ mov r1, #16
-+ vsubl.u8 q3, d30, d1
-+ vsubl.u8 q2, d30, d0 @ Add set up
++@ u16 7..0 [1] q1
++@ u32 left[y] [1] [r2]
++@ u16 acc [1] q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [1] q0 = p[-1][nTbs] - p[x][-1]
+
-+ vshll.u8 q1, d1, #4
-+ vshll.u8 q0, d0, #4
-+ vmlal.u8 q1, d19, d31
-+ vmlal.u8 q0, d18, d31 @ Acc set up - q8-q9 free
-+
-+@ u8 15..0 [1] q8
-+@ u8 left[y] [1] q12
-+@ u16 acc [2] q0 .. q1 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [2] q2 .. q3 = p[-1][nTbs] - p[x][-1]
++ vld1.16 {d6[],d7[]}, [r2]!
++ vadd.i16 q8, q2, q0
++ vld1.16 {d18[],d19[]}, [r2]!
++ vmla.i16 q2, q1, q3
++ vadd.i16 q3, q8, q0
++ vmla.i16 q8, q1, q9
+1:
-+ vadd.i16 q1, q3
-+ vadd.i16 q0, q2
-+
-+ vdup.u8 d20, d24[0]
-+ vext.8 q12, q12, #1
-+
-+ vmull.u8 q11, d17, d20
-+ vmull.u8 q10, d16, d20
-+
-+ vadd.i16 q11, q1
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d29, q11, #5
-+ vrshrn.u16 d28, q10, #5
-+
-+ subs r1, #1
-+ vst1.8 {q14}, [r0 :128], r3
-+
++ vrshr.u16 q9, q2, #4
++ subs r1, #2
++ vmov q2, q3
++ vrshr.u16 q10, q8, #4
++ vld1.16 {d6[],d7[]}, [r2]!
++ vst1.16 {q9}, [r0 :128], r3
++ vadd.i16 q8, q2, q0
++ vld1.16 {d18[],d19[]}, [r2]!
++ vmla.i16 q2, q1, q3
++ vadd.i16 q3, q8, q0
++ vmla.i16 q8, q1, q9
++ vst1.16 {q10}, [r0 :128], r3
+ bne 1b
+
-+ bx lr
++ vrshr.u16 q9, q2, #4
++ add r3, r0
++ vrshr.u16 q10, q8, #4
++ vst1.16 {q9}, [r0 :128]
++ vst1.16 {q10}, [r3 :128]
+
++ bx lr
+endfunc
+
+
-+@ ff_hevc_rpi_pred_planar_32_neon_8
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_32_neon_8, export=1
-+ vpush {q4-q7}
-+ vld1.8 {q12, q13}, [r2 :128]! @ Left
-+ adr r12, nb_31_0_1_32
-+ vld1.8 {q0, q1 }, [r1 :128]! @ Up
-+ vld1.8 {d30[0]}, [r2] @ Down left
-+ vld1.8 {d31[0]}, [r1] @ Up-right
-+ vldm r12, { q8-q11} @ 1..32, 31..0
-+
-+ vdup.8 d30, d30[0]
-+ vdup.8 d31, d31[0]
-+
-+ vsubl.u8 q7, d30, d3
-+ vsubl.u8 q6, d30, d2
-+ vsubl.u8 q5, d30, d1
-+ vsubl.u8 q4, d30, d0 @ Add set up
-+
-+ vshll.u8 q3, d3, #5
-+ vshll.u8 q2, d2, #5
-+ vshll.u8 q1, d1, #5
-+ vshll.u8 q0, d0, #5
-+ vmlal.u8 q3, d23, d31
-+ vmlal.u8 q2, d22, d31
-+ vmlal.u8 q1, d21, d31
-+ vmlal.u8 q0, d20, d31 @ Acc set up - q8-q9 free
-+
-+ mov r1, #32
-+
-+@ u8 31..0 [2] q10, q11
-+@ u8 left[y] [2] q12, q13
-+@ u16 acc [4] q0 .. q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [4] q4 .. q7 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vadd.i16 q3, q7
-+ vadd.i16 q2, q6
-+ vadd.i16 q1, q5
-+ vadd.i16 q0, q4
-+
-+ vdup.u8 d20, d24[0]
-+ vext.8 q12, q13, #1
-+ vext.8 q13, q13, #1
-+
-+ vmull.u8 q15, d19, d20
-+ vmull.u8 q14, d18, d20
-+ vmull.u8 q11, d17, d20
-+ vmull.u8 q10, d16, d20
-+
-+ vadd.i16 q15, q3
-+ vadd.i16 q14, q2
-+ vadd.i16 q11, q1
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d31, q15, #6
-+ vrshrn.u16 d30, q14, #6
-+ vrshrn.u16 d29, q11, #6
-+ vrshrn.u16 d28, q10, #6
-+
-+ subs r1, #1
-+ vst1.8 {q14, q15}, [r0 :128], r3
-+
-+ bne 1b
-+
-+ vpop {q4-q7}
-+ bx lr
-+
-+endfunc
-+
-+
-+@ ff_hevc_rpi_pred_planar_c_4_neon_8
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_c_4_neon_8, export=1
-+ vld1.8 {q12}, [r2 :64] @ Left + down-left - <1d of overread is OK
-+ adr r12, nbx2_3_0_1_4
-+ vld1.8 {q0 }, [r1 :64] @ Up + up right
-+ vld1.8 {q8 }, [r12 :128] @ 3,3..
-+
-+ vdup.16 d30, d25[0]
-+ vdup.16 d31, d1[0]
-+
-+ mov r1, #4
-+ vsubl.u8 q2, d30, d0 @ Add set up
-+
-+ lsl r3, #1
-+ vshll.u8 q0, d0, #2
-+ vmlal.u8 q0, d17, d31 @ Acc set up - q8-q9 free
-+
-+@ u8 3,3..0,0 [1] d16
-+@ u8 left[y] [1] d24
-+@ u16 acc [1] q0 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [1] q2 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vadd.i16 q0, q2
-+
-+ vdup.u16 d20, d24[0]
-+ vext.16 d24, d24, #1
-+
-+ vmull.u8 q10, d16, d20
-+
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d28, q10, #3
-+
-+ subs r1, #1
-+ vst1.8 {d28}, [r0 :64], r3
-+
-+ bne 1b
-+
-+ bx lr
-+
-+endfunc
-+
-+
-+@ ff_hevc_rpi_pred_planar_c_8_neon_8
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_c_8_neon_8, export=1
-+ vld1.8 {q12}, [r2 :128] @ Left
-+ ldrh r2, [r2, #16] @ Down left - could have this in q13, but avoid that much overrread
-+ adr r12, nbx2_7_0_1_8
-+ vld1.8 {q0 }, [r1 :128] @ Up
-+ ldrh r1, [r1, #16] @ Up-right
-+ vld1.8 {q8, q9 }, [r12 :128] @ 7,7...
-+
-+ vdup.16 d30, r2
-+ vdup.16 d31, r1
-+
-+ mov r1, #8
-+ vsubl.u8 q3, d30, d1
-+ vsubl.u8 q2, d30, d0 @ Add set up
-+
-+ lsl r3, #1
-+ vshll.u8 q1, d1, #3
-+ vshll.u8 q0, d0, #3
-+ vmlal.u8 q1, d19, d31
-+ vmlal.u8 q0, d18, d31 @ Acc set up - q8-q9 free
-+
-+@ u8 7,7..0,0 [1] q8
-+@ u8 left[y] [1] q12
-+@ u16 acc [2] q0 .. q1 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [2] q2 .. q3 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vadd.i16 q1, q3
-+ vadd.i16 q0, q2
-+
-+ vdup.u16 d20, d24[0]
-+ vext.16 q12, q12, #1
-+
-+ vmull.u8 q11, d17, d20
-+ vmull.u8 q10, d16, d20
-+
-+ vadd.i16 q11, q1
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d29, q11, #4
-+ vrshrn.u16 d28, q10, #4
-+
-+ subs r1, #1
-+ vst1.8 {q14}, [r0 :128], r3
-+
-+ bne 1b
-+
-+ bx lr
-+
-+endfunc
-+
-+
-+
-+@ ff_hevc_rpi_pred_planar_c_16_neon_8
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_c_16_neon_8, export=1
-+ vpush {q4-q7}
-+ vld1.8 {q12, q13}, [r2 :128]! @ Left
-+ adr r12, nbx2_15_0_1_16
-+ vld1.8 {q0, q1 }, [r1 :128]! @ Up
-+ vld1.16 {d30[0]}, [r2] @ Down left
-+ vld1.16 {d31[0]}, [r1] @ Up-right
-+ vldm r12, { q8-q11} @ 1..32, 31..0
-+
-+ vdup.16 d30, d30[0]
-+ vdup.16 d31, d31[0]
-+
-+ mov r1, #16
-+ vsubl.u8 q7, d30, d3
-+ vsubl.u8 q6, d30, d2
-+ vsubl.u8 q5, d30, d1
-+ vsubl.u8 q4, d30, d0 @ Add set up
-+
-+ lsl r3, #1
-+ vshll.u8 q3, d3, #4
-+ vshll.u8 q2, d2, #4
-+ vshll.u8 q1, d1, #4
-+ vshll.u8 q0, d0, #4
-+ vmlal.u8 q3, d23, d31
-+ vmlal.u8 q2, d22, d31
-+ vmlal.u8 q1, d21, d31
-+ vmlal.u8 q0, d20, d31 @ Acc set up - q8-q9 free
-+
-+@ u8 31..0 [2] q10, q11
-+@ u8 left[y] [2] q12, q13
-+@ u16 acc [4] q0 .. q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [4] q4 .. q7 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vadd.i16 q3, q7
-+ vadd.i16 q2, q6
-+ vadd.i16 q1, q5
-+ vadd.i16 q0, q4
-+
-+ vdup.u16 d20, d24[0]
-+ vext.16 q12, q13, #1
-+ vext.16 q13, q13, #1
-+
-+ vmull.u8 q15, d19, d20
-+ vmull.u8 q14, d18, d20
-+ vmull.u8 q11, d17, d20
-+ vmull.u8 q10, d16, d20
-+
-+ vadd.i16 q15, q3
-+ vadd.i16 q14, q2
-+ vadd.i16 q11, q1
-+ vadd.i16 q10, q0
-+
-+ vrshrn.u16 d31, q15, #5
-+ vrshrn.u16 d30, q14, #5
-+ vrshrn.u16 d29, q11, #5
-+ vrshrn.u16 d28, q10, #5
-+
-+ subs r1, #1
-+ vst1.8 {q14, q15}, [r0 :256], r3
-+
-+ bne 1b
-+
-+ vpop {q4-q7}
-+ bx lr
-+
-+endfunc
-+
+@------------------------------------------------------------------------------
+@
-+@ Data - put btween the 2 code lumps so we can reach it with an adr from both
-+@ Beware - it gets quite close which is why nb_3_0_1_4 is 1st...
++@ Data - has to be in two lumps to ensure we can always reach using adr
+
-+ .text
+ .balign 64
+
-+ @ These could be extracted from the above array, but separate out
-+ @ out for better (16 byte) alignment
-+nb_3_0_1_4:
-+ .byte 3, 2, 1, 0, 3, 2, 1, 0
-+ .byte 1, 2, 3, 4, 1, 2, 3, 4
-+nb_7_0_1_8:
-+ .byte 7, 6, 5, 4, 3, 2, 1, 0
-+ .byte 1, 2, 3, 4, 5, 6, 7, 8
-+nbh_3_0_1_4:
-+ .short 3, 2, 1, 0, 1, 2, 3, 4
-+nbx2_3_0_1_4:
-+ .byte 3, 3, 2, 2, 1, 1, 0, 0
-+ .byte 1, 1, 2, 2, 3, 3, 4, 4
-+
-+ @ should be back on a 64-byte boundary here
+nb_31_0_1_32:
+ .byte 31, 30, 29, 28, 27, 26, 25, 24
+ .byte 23, 22, 21, 20, 19, 18, 17, 16
@@ -13478,6 +13288,509 @@ index 0000000000..9fb3633862
+ .byte 25, 26, 27, 28, 29, 30, 31, 32
+
+ @ should be back on a 64-byte boundary here
++
++ @ These could be extracted from the above array, but separate out
++ @ out for better (16 byte) alignment
++nb_3_0_1_4:
++ .byte 3, 2, 1, 0, 3, 2, 1, 0
++ .byte 1, 2, 3, 4, 1, 2, 3, 4
++nb_7_0_1_8:
++ .byte 7, 6, 5, 4, 3, 2, 1, 0
++ .byte 1, 2, 3, 4, 5, 6, 7, 8
++nbh_3_0_1_4:
++ .short 3, 2, 1, 0, 1, 2, 3, 4
++
++@------------------------------------------------------------------------------
++
++
++@ ff_hevc_rpi_pred_planar_16_neon_8
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_16_neon_8, export=1
++
++ adr ip, nb_15_0_1_16 + 16
++ vld1.8 {q0}, [r1 :128]! @ Top (left)
++ add r2, #16
++ vld1.8 {q1}, [ip: 128] @ {1,2,3...16}
++ vld1.8 {d4[]}, [r1] @ Top (right)
++ sub ip, #16
++ vshll.u8 q3, d0, #4
++ mov r1, #16
++ vshll.u8 q8, d1, #4
++ vld1.8 {d5[]}, [r2] @ Left (lower)
++ sub r2, #16
++ vmlal.u8 q3, d2, d4
++ vmlal.u8 q8, d3, d4 @ Acc set up
++ vsubl.u8 q1, d5, d0
++ vsubl.u8 q0, d5, d1 @ Add set up
++ vld1.8 {q2}, [ip :128] @ {15,14,13...0}
++
++@ u8 15..0 [1] q2
++@ u8 left[y] [1] [r2]
++@ u16 acc [2] q3,q8 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q1,q0 = p[-1][nTbs] - p[x][-1]
++
++ vadd.i16 q3, q1
++ vadd.i16 q8, q0
++1:
++ vadd.i16 q10, q3, q1
++ subs r1, #2
++ vld1.8 {d18[]}, [r2]!
++ vadd.i16 q11, q8, q0
++ vld1.8 {d19[]}, [r2]!
++ vmlal.u8 q3, d4, d18
++ vmlal.u8 q8, d5, d18
++ vadd.i16 q12, q10, q1
++ vmlal.u8 q10, d4, d19
++ vadd.i16 q13, q11, q0
++ vmlal.u8 q11, d5, d19
++ vrshrn.u16 d18, q3, #5
++ vrshrn.u16 d19, q8, #5
++ vmov q3, q12
++ vst1.8 {q9}, [r0 :128], r3
++ vrshrn.u16 d18, q10, #5
++ vrshrn.u16 d19, q11, #5
++ vmov q8, q13
++ vst1.8 {q9}, [r0 :128], r3
++ bne 1b
++
++ bx lr
++
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_16_neon_10
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_16_neon_10, export=1
++
++ @ Load from bytes & expand later - at the very least this uses less
++ @ memory than having a short table
++ adr ip, nb_15_0_1_16 + 16
++ vld1.16 {q0-q1}, [r1 :128]! @ Top (left)
++ add r2, #32
++ vld1.8 {q2}, [ip :128] @ {1,2,3...16}
++ lsl r3, #1
++ vld1.16 {d6[],d7[]}, [r1] @ Top (right)
++ sub ip, #16
++ vmovl.u8 q8, d4
++ mov r1, #16
++ vshl.i16 q9, q0, #4
++ vmovl.u8 q2, d5
++ vshl.i16 q10, q1, #4
++ vld1.16 {d22[],d23[]}, [r2] @ Left (lower)
++ sub r2, #32
++ vld1.8 {q12}, [ip] @ {15,14,13...0}
++ vmla.i16 q9, q8, q3
++ vmla.i16 q10, q2, q3 @ Acc set up
++ vsub.i16 q0, q11, q0
++ vsub.i16 q1, q11, q1 @ Add set up
++ vadd.i16 q2, q9, q0
++ vadd.i16 q3, q10, q1
++ vmovl.u8 q8, d24
++ vmovl.u8 q9, d25
++
++@ u16 15..0 [2] q8,q9
++@ u32 left[y] [2] [r2]
++@ u16 acc [2] q2,q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q0,q1 = p[-1][nTbs] - p[x][-1]
++
++1:
++ vadd.i16 q10, q2, q0
++ subs r1, #2
++ vld1.16 {d24[],d25[]}, [r2]!
++ vadd.i16 q11, q3, q1
++ vld1.16 {d28[],d29[]}, [r2]!
++ vmla.i16 q2, q8, q12
++ vmla.i16 q3, q9, q12
++ vadd.i16 q12, q10, q0
++ vmla.i16 q10, q8, q14
++ vadd.i16 q13, q11, q1
++ vmla.i16 q11, q9, q14
++ vrshr.u16 q14, q2, #5
++ vrshr.u16 q15, q3, #5
++ vmov q2, q12
++ vst1.16 {q14-q15}, [r0 :128], r3
++ vrshr.u16 q14, q10, #5
++ vrshr.u16 q15, q11, #5
++ vmov q3, q13
++ vst1.16 {q14-q15}, [r0 :128], r3
++ bne 1b
++
++ bx lr
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_32_neon_8
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_32_neon_8, export=1
++
++ vld1.8 {q0-q1}, [r1 :128]! @ Top (left)
++ adr ip, nb_31_0_1_32 + 32
++ vpush {d8-d12}
++ vld1.8 {q2-q3}, [ip :128] @ {1,2,3...32}
++ add r2, #32
++ vld1.8 {d8[]}, [r1] @ Top (right)
++ sub ip, #32
++ vshll.u8 q8, d0, #5
++ mov r1, #32
++ vld1.8 {d9[]}, [r2] @ Left (lower)
++ sub r2, #32
++ vshll.u8 q9, d1, #5
++ vshll.u8 q10, d2, #5
++ vshll.u8 q11, d3, #5
++ vmlal.u8 q8, d4, d8
++ vsubl.u8 q12, d9, d0
++ vmlal.u8 q9, d5, d8
++ vsubl.u8 q13, d9, d1
++ vmlal.u8 q10, d6, d8
++ vsubl.u8 q14, d9, d2
++ vmlal.u8 q11, d7, d8 @ Acc set up
++ vsubl.u8 q15, d9, d3 @ Add set up
++ vadd.i16 q8, q12
++ vadd.i16 q9, q13
++ vadd.i16 q10, q14
++ vadd.i16 q11, q15
++ vld1.8 {q4-q5}, [ip :128] @ {31,30,29...0}
++
++@ u8 31..0 [2] q4,q5
++@ u8 left[y] [2] [r2]
++@ u16 acc [4] q8-q11 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [4] q12-q15 = p[-1][nTbs] - p[x][-1]
++
++ vld1.8 {d12[]}, [r2]!
++ vadd.i16 q0, q8, q12
++ b 2f
++1:
++ vld1.8 {d12[]}, [r2]!
++ vrshrn.u16 d3, q1, #6
++ vrshrn.u16 d2, q0, #6
++ vadd.i16 q0, q8, q12
++ vrshrn.u16 d4, q2, #6
++ vrshrn.u16 d5, q3, #6
++ vst1.8 {q1-q2}, [r0 :128], r3
++2: vadd.i16 q1, q9, q13
++ subs r1, #2
++ vadd.i16 q2, q10, q14
++ vadd.i16 q3, q11, q15
++ vmlal.u8 q8, d8, d12
++ vmlal.u8 q9, d9, d12
++ vmlal.u8 q10, d10, d12
++ vmlal.u8 q11, d11, d12
++ vld1.8 {d12[]}, [r2]!
++ vrshrn.u16 d19, q9, #6
++ vrshrn.u16 d18, q8, #6
++ vadd.i16 q8, q0, q12
++ vrshrn.u16 d20, q10, #6
++ vrshrn.u16 d21, q11, #6
++ vst1.8 {q9-q10}, [r0 :128], r3
++ vadd.i16 q9, q1, q13
++ vadd.i16 q10, q2, q14
++ vadd.i16 q11, q3, q15
++ vmlal.u8 q0, d8, d12
++ vmlal.u8 q1, d9, d12
++ vmlal.u8 q2, d10, d12
++ vmlal.u8 q3, d11, d12
++
++ bne 1b
++
++ vpop {d8-d12}
++
++ vrshrn.u16 d3, q1, #6
++ vrshrn.u16 d2, q0, #6
++ vrshrn.u16 d4, q2, #6
++ vrshrn.u16 d5, q3, #6
++ vst1.8 {q1-q2}, [r0 :128]
++
++ bx lr
++
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_32_neon_10
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_32_neon_10, export=1
++
++ @ Load from bytes & expand later - at the very least this uses less
++ @ memory than having a short table
++ vld1.16 {q0-q1}, [r1 :128]! @ Top (left)
++ adr ip, nb_31_0_1_32 + 32
++ vpush {q4-q7}
++ vld1.16 {q2-q3}, [r1 :128]! @ Top (centre)
++ add r2, #64
++ vld1.8 {q14-q15}, [ip :128] @ {1,2,3...32}
++T lsl r3, #1
++ vld1.16 {d8[],d9[]}, [r1] @ Top (right)
++ sub ip, #32
++ vmovl.u8 q12, d28
++ mov r1, #32
++ vmovl.u8 q13, d29
++ vld1.8 {q6-q7}, [ip :128] @ {31,30,29...0}
++ vmovl.u8 q14, d30
++ vmovl.u8 q15, d31
++ vld1.16 {d10[],d11[]}, [r2] @ Left (lower)
++ sub r2, #64
++ vshl.i16 q8, q0, #5
++ vshl.i16 q9, q1, #5
++ vshl.i16 q10, q2, #5
++ vshl.i16 q11, q3, #5
++ vmla.i16 q8, q12, q4
++ vsub.i16 q0, q5, q0
++ vmla.i16 q9, q13, q4
++ vsub.i16 q1, q5, q1
++ vmla.i16 q10, q14, q4
++ vmov.u16 ip, d0[0]
++ vsub.i16 q2, q5, q2
++ vmla.i16 q11, q15, q4 @ Acc set up
++ vsub.i16 q3, q5, q3 @ Add set up
++ vadd.i16 q8, q0
++ vadd.i16 q9, q1
++ vadd.i16 q10, q2
++ vadd.i16 q11, q3
++ vmovl.u8 q4, d12
++ vmovl.u8 q5, d13
++ vmovl.u8 q6, d14
++ vmovl.u8 q7, d15
++
++@ u16 31..0 [4] q4-q7
++@ u16 left[y] [4] [r2]
++@ u16 acc [4] q8-q11 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [4] q0-q3 = p[-1][nTbs] - p[x][-1]
++
++ vadd.i16 q12, q8, q0
++A sub r0, r0, r3, lsl #1
++T sub r0, r3
++1:
++ vld1.16 {d0[0]}, [r2]!
++A add r0, r0, r3, lsl #1
++T add r0, r3
++ vadd.i16 q13, q9, q1
++ subs r1, #2
++ vadd.i16 q14, q10, q2
++ vadd.i16 q15, q11, q3
++ vmla.i16 q8, q4, d0[0]
++ vmla.i16 q9, q5, d0[0]
++ vmla.i16 q10, q6, d0[0]
++ vmla.i16 q11, q7, d0[0]
++ vmov.16 d0[0], ip
++ vrshr.u16 q8, #6
++ vrshr.u16 q9, #6
++ vrshr.u16 q10, #6
++ vrshr.u16 q11, #6
++ vstm r0, {q8-q11}
++ vadd.i16 q8, q12, q0
++A add r0, r0, r3, lsl #1
++T add r0, r3
++ vld1.16 {d0[0]}, [r2]!
++ vadd.i16 q9, q13, q1
++ vadd.i16 q10, q14, q2
++ vadd.i16 q11, q15, q3
++ vmla.i16 q12, q4, d0[0]
++ vmla.i16 q13, q5, d0[0]
++ vmla.i16 q14, q6, d0[0]
++ vmla.i16 q15, q7, d0[0]
++ vmov.16 d0[0], ip
++ vrshr.u16 q12, #6
++ vrshr.u16 q13, #6
++ vrshr.u16 q14, #6
++ vrshr.u16 q15, #6
++ vstm r0, {q12-q15}
++ vadd.i16 q12, q8, q0
++ bne 1b
++
++ vpop {q4-q7}
++ bx lr
++
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_c_4_neon_8
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_c_4_neon_8, export=1
++
++ vld1.8 {q0}, [r1] @ Top
++ adr ip, nbx2_3_0_1_4
++ vldr d2, [r2, #8] @ Left (lower)
++ mov r1, #4
++ vldr d3, [ip, #8] @ {1,1,2,2,3,3,4,4}
++ lsl r3, #1
++ vshll.u8 q2, d0, #2
++ vdup.16 d1, d1[0] @ {t4,t4,t4,t4,t4,t4,t4,t4}
++ vdup.16 d2, d2[0] @ {l4,l4,l4,l4,l4,l4,l4,l4}
++ vldr d6, [r2] @ Left (upper)
++ vmlal.u8 q2, d3, d1
++ vsubl.u8 q0, d2, d0
++ vldr d7, [ip] @ {3,3,2,2,1,1,0,0}
++
++@ u8 3..0 [1] d7
++@ u8 left[y] [1] d6
++@ u16 acc [2] q2 (even rows) or q8 (odd rows) = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q0 = p[-1][nTbs] - p[x][-1]
++
++ vdup.16 d2, d6[0]
++ vadd.i16 q2, q0
++ vdup.16 d3, d6[1]
++ vadd.i16 q8, q2, q0
++1:
++ vmlal.u8 q2, d7, d2
++ subs r1, #2
++ vadd.i16 q9, q8, q0
++ vmlal.u8 q8, d7, d3
++ vdup.16 d2, d6[2]
++ vdup.16 d3, d6[3]
++ vrshrn.i16 d20, q2, #3
++ vmov q2, q9
++ vst1.8 {d20}, [r0], r3
++ vrshrn.i16 d20, q8, #3
++ vadd.i16 q8, q2, q0
++ vst1.8 {d20}, [r0], r3
++ bne 1b
++
++ bx lr
++
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_c_4_neon_10
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_c_4_neon_10, export=1
++
++ adr ip, nbx2_3_0_1_4
++ vld1.16 {q0}, [r1 :128]! @ Top (left)
++ lsl r3, #2
++ vld1.16 {q1}, [ip :128] @ {3,3,2,2,1,1,0,0,1,1,2,2,3,3,4,4}
++ add ip, r2, #16
++ vld1.32 {d4[],d5[]}, [r1] @ Top (right)
++ vshl.s16 q3, q0, #2
++ vmovl.u8 q8, d3 @ {1,1,2,2,3,3,4,4}
++ vld1.32 {d18[],d19[]}, [ip] @ Left (lower)
++ vmla.i16 q3, q8, q2 @ Acc set up
++ vsub.i16 q0, q9, q0 @ Add set up
++ vmovl.u8 q1, d2 @ {3,3,2,2,1,1,0,0}
++ vadd.i16 q2, q3, q0
++
++@ u16 3..0 [1] q1
++@ u32 left[y] [1] [r2]
++@ u16 acc [1] q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [1] q0 = p[-1][nTbs] - p[x][-1]
++
++ vld1.32 {d6[],d7[]}, [r2]!
++ vadd.i16 q8, q2, q0
++ vld1.32 {d18[],d19[]}, [r2]!
++ vmla.i16 q2, q1, q3
++ vadd.i16 q3, q8, q0
++ vmla.i16 q8, q1, q9
++
++ vrshr.u16 q9, q2, #3
++ vmov q2, q3
++ vrshr.u16 q10, q8, #3
++ vld1.32 {d6[],d7[]}, [r2]!
++ vst1.16 {q9}, [r0 :128], r3
++ vadd.i16 q8, q2, q0
++ vld1.32 {d18[],d19[]}, [r2]!
++ vmla.i16 q2, q1, q3
++ vadd.i16 q3, q8, q0
++ vmla.i16 q8, q1, q9
++ vst1.16 {q10}, [r0 :128], r3
++
++ vrshr.u16 q9, q2, #3
++ add r3, r0
++ vrshr.u16 q10, q8, #3
++ vst1.16 {q9}, [r0 :128]
++ vst1.16 {q10}, [r3 :128]
++
++ bx lr
++endfunc
++
++
++@ ff_hevc_rpi_pred_planar_c_8_neon_8
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_c_8_neon_8, export=1
++
++ adr ip, nbx2_7_0_1_8 + 16
++ vld1.8 {q0}, [r1 :128]! @ Top (left)
++ add r2, #16
++ vld1.8 {q1}, [ip: 128] @ {1,1,2,2,3,3...8,8}
++ lsl r3, #1
++ vld1.16 {d4[]}, [r1] @ Top (right)
++ sub ip, #16
++ vshll.u8 q3, d0, #3
++ mov r1, #8
++ vshll.u8 q8, d1, #3
++ vld1.16 {d5[]}, [r2] @ Left (lower)
++ sub r2, #16
++ vmlal.u8 q3, d2, d4
++ vmlal.u8 q8, d3, d4 @ Acc set up
++ vsubl.u8 q1, d5, d0
++ vsubl.u8 q0, d5, d1 @ Add set up
++ vld1.8 {q2}, [ip :128] @ {7,7,6,6,5,5...0,0}
++
++@ u8 7..0 [1] q2
++@ u8 left[y] [1] [r2]
++@ u16 acc [2] q3,q8 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q1,q0 = p[-1][nTbs] - p[x][-1]
++
++ vadd.i16 q3, q1
++ vadd.i16 q8, q0
++1:
++ vadd.i16 q10, q3, q1
++ subs r1, #2
++ vld1.16 {d18[]}, [r2]!
++ vadd.i16 q11, q8, q0
++ vld1.16 {d19[]}, [r2]!
++ vmlal.u8 q3, d4, d18
++ vmlal.u8 q8, d5, d18
++ vadd.i16 q12, q10, q1
++ vmlal.u8 q10, d4, d19
++ vadd.i16 q13, q11, q0
++ vmlal.u8 q11, d5, d19
++ vrshrn.u16 d18, q3, #4
++ vrshrn.u16 d19, q8, #4
++ vmov q3, q12
++ vst1.8 {q9}, [r0 :128], r3
++ vrshrn.u16 d18, q10, #4
++ vrshrn.u16 d19, q11, #4
++ vmov q8, q13
++ vst1.8 {q9}, [r0 :128], r3
++ bne 1b
++
++ bx lr
++
++endfunc
++
++
++@------------------------------------------------------------------------------
++@
++@ Data - has to be in two lumps to ensure we can always reach using adr
++
++ .balign 64
++
+nbx2_15_0_1_16:
+ .byte 15, 15, 14, 14, 13, 13, 12, 12
+ .byte 11, 11, 10, 10, 9, 9, 8, 8
@@ -13489,306 +13802,13 @@ index 0000000000..9fb3633862
+ .byte 9, 9, 10, 10, 11, 11, 12, 12
+ .byte 13, 13, 14, 14, 15, 15, 16, 16
+
++ @ should be back on a 64-byte boundary here
++
++nbx2_3_0_1_4:
++ .byte 3, 3, 2, 2, 1, 1, 0, 0
++ .byte 1, 1, 2, 2, 3, 3, 4, 4
++
+@------------------------------------------------------------------------------
-+@
-+@ 10 bits
-+@ (all would work with 9)
-+
-+@ ff_hevc_rpi_pred_planar_4_neon_10
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_4_neon_10, export=1
-+ @ Load from bytes & expand later - at the very least this uses less
-+ @ memory than having a short table
-+ adr r12, nbh_3_0_1_4
-+ vld1.16 {q14}, [r2 :64]
-+ vld1.16 {q8 }, [r12 :128] @ 3..0,1,..4
-+ vld1.16 {q12}, [r1 :64] @ Up
-+ vdup.16 d2, d29[0]
-+
-+ lsl r3, #1
-+ vsub.i16 d4, d2, d24 @ Add set up
-+
-+ vdup.16 d0, d25[0]
-+ vshl.i16 d24, #2
-+ vmla.i16 d24, d17, d0 @ Acc set up
-+ add r1, r0, r3
-+ vmov d17, d16
-+
-+ vadd.i16 d24, d4
-+ vadd.i16 d25, d24, d4
-+ vshl.i16 d4, d4, #1 @ x2
-+ lsl r3, #1
-+ vadd.i16 d26, d24, d4
-+ vadd.i16 d27, d25, d4
-+
-+ vdup.16 d0, d28[0]
-+ vdup.16 d1, d28[1]
-+ vdup.16 d2, d28[2]
-+ vdup.16 d3, d28[3]
-+
-+ vmul.i16 q0, q8, q0
-+ vmul.i16 q1, q8, q1
-+ vadd.i16 q0, q12
-+ vadd.i16 q1, q13
-+
-+ vrshr.u16 q0, #3
-+ vrshr.u16 q1, #3
-+
-+ vst1.16 {d0}, [r0], r3
-+ vst1.16 {d1}, [r1], r3
-+ vst1.16 {d2}, [r0]
-+ vst1.16 {d3}, [r1]
-+
-+ bx lr
-+endfunc
-+
-+
-+@ ff_hevc_rpi_pred_planar_8_neon_10
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_8_neon_10, export=1
-+ @ Load from bytes & expand later - at the very least this uses less
-+ @ memory than having a short table
-+ adr r12, nb_7_0_1_8
-+ vld1.16 {q14}, [r2 :128]
-+ ldrh r2, [r2, #16] @ Down left
-+ vld1.8 {q0 }, [r12 :128] @ 7..0,1,..8
-+ vld1.16 {q12}, [r1 :128] @ Up
-+ ldrh r1, [r1, #16] @ Up-right
-+ vmovl.u8 q8, d1
-+ vdup.16 q1, r2
-+ vmovl.u8 q10, d0
-+
-+ lsl r3, #1
-+ vsub.i16 q2, q1, q12 @ Add set up
-+
-+ vdup.16 q0, r1
-+ mov r1, #8
-+ vshl.i16 q12, #3
-+ vmla.i16 q12, q8, q0 @ Acc set up - q8-q11 free
-+
-+@ u16 15..0 [1] q10
-+@ u32 left[y] [1] q14
-+@ u16 acc [1] q12 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [1] q2 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vdup.16 q0, d28[0]
-+ vext.16 q14, q14, #1
-+
-+ vadd.i16 q12, q2
-+
-+ vmul.i16 q0, q10, q0
-+ vadd.i16 q0, q12
-+ vrshr.u16 q0, #4
-+
-+ subs r1, #1
-+ vst1.16 {q0 }, [r0 :128], r3
-+
-+ bne 1b
-+
-+ bx lr
-+endfunc
-+
-+
-+@ ff_hevc_rpi_pred_planar_16_neon_10
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_16_neon_10, export=1
-+ @ Load from bytes & expand later - at the very least this uses less
-+ @ memory than having a short table
-+ adr r12, nb_15_0_1_16
-+ vld1.16 {q14, q15}, [r2 :128]
-+ ldrh r2, [r2, #32] @ Down left
-+ vld1.8 {q0, q1 }, [r12 :128] @ 15..0,1,..16
-+ vld1.16 {q12, q13}, [r1 :128] @ Up
-+ ldrh r1, [r1, #32] @ Up-right
-+ vmovl.u8 q9, d3
-+ vmovl.u8 q8, d2
-+ vdup.16 q1, r2
-+ vmovl.u8 q11, d1
-+ vmovl.u8 q10, d0
-+
-+ lsl r3, #1
-+ vsub.i16 q3, q1, q13
-+ vsub.i16 q2, q1, q12 @ Add set up
-+
-+ vdup.16 q0, r1
-+ mov r1, #16
-+ vshl.i16 q13, #4
-+ vshl.i16 q12, #4
-+ vmla.i16 q13, q9, q0
-+ vmla.i16 q12, q8, q0 @ Acc set up - q8-q11 free
-+
-+@ u16 15..0 [2] q10..q11
-+@ u32 left[y] [2] q14..q15
-+@ u16 acc [2] q12..q13 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [2] q2..q3 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vdup.16 q0, d28[0]
-+ vext.16 q14, q15, #1
-+ vext.16 q15, q15, #1
-+
-+ vadd.i16 q13, q3
-+ vadd.i16 q12, q2
-+
-+ vmul.i16 q1, q11, q0
-+ vmul.i16 q0, q10, q0
-+
-+ vadd.i16 q1, q13
-+ vadd.i16 q0, q12
-+
-+ vrshr.u16 q1, #5
-+ vrshr.u16 q0, #5
-+
-+ subs r1, #1
-+ vst1.16 {q0, q1 }, [r0 :128], r3
-+
-+ bne 1b
-+
-+ bx lr
-+endfunc
-+
-+
-+@ ff_hevc_rpi_pred_planar_32_neon_10
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_32_neon_10, export=1
-+ push {r4, lr}
-+ @ Load from bytes & expand later - at the very least this uses less
-+ @ memory than having a short table
-+ adr r12, nb_31_0_1_32
-+ vpush { q4-q7 }
-+ vldm r12, { q0-q3 } @ 1..32, r12 points at 31..0
-+ vldm r1!, {q12-q15} @ Up
-+ ldrh r12, [r2, #64] @ Down left
-+ vmovl.u8 q8, d4
-+ vmovl.u8 q9, d5
-+ vmovl.u8 q10, d6
-+ vmovl.u8 q11, d7
-+ vdup.16 q3, r12
-+ vld1.16 {d4[0]}, [r1] @ Up-right
-+
-+ vsub.i16 q7, q3, q15
-+ vsub.i16 q6, q3, q14
-+ vsub.i16 q5, q3, q13
-+ vsub.i16 q4, q3, q12 @ Add set up
-+
-+ vshl.i16 q15, #5
-+ vshl.i16 q14, #5
-+ vshl.i16 q13, #5
-+ vshl.i16 q12, #5
-+ vmla.i16 q15, q11, d4[0]
-+ vmla.i16 q14, q10, d4[0]
-+ vmla.i16 q13, q9, d4[0]
-+ vmla.i16 q12, q8, d4[0] @ Acc set up - q8-q11 free
-+
-+ mov r1, #32
-+ vmovl.u8 q8, d0
-+ vmovl.u8 q9, d1
-+ vmovl.u8 q10, d2
-+ vmovl.u8 q11, d3
-+
-+@ u8 31..0 [4] q8..q11
-+@ u8 left[y] [4] [r2]
-+@ u16 acc [4] q12..q15 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [4] q4..q7 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vld1.16 {d0[0]}, [r2]!
-+
-+ vadd.i16 q15, q7
-+ vadd.i16 q14, q6
-+ vadd.i16 q13, q5
-+ vadd.i16 q12, q4
-+
-+ vmul.i16 q3, q11, d0[0]
-+ vmul.i16 q2, q10, d0[0]
-+ vmul.i16 q1, q9, d0[0]
-+ vmul.i16 q0, q8, d0[0]
-+
-+ vadd.i16 q3, q15
-+ vadd.i16 q2, q14
-+ vadd.i16 q1, q13
-+ vadd.i16 q0, q12
-+
-+ vrshr.u16 q3, #6
-+ vrshr.u16 q2, #6
-+ vrshr.u16 q1, #6
-+ vrshr.u16 q0, #6
-+
-+ subs r1, #1
-+ vstm r0, { q0-q3 }
-+ add r0, r0, r3, lsl #1
-+
-+ bne 1b
-+
-+ vpop {q4-q7}
-+ pop {r4, pc}
-+
-+endfunc
-+
-+@ ff_hevc_rpi_pred_planar_c_8_neon_10
-+@ uint8_t *_src, [r0]
-+@ const uint8_t *_top, [r1]
-+@ const uint8_t *_left, [r2]
-+@ ptrdiff_t stride) [r3]
-+
-+function ff_hevc_rpi_pred_planar_c_4_neon_10, export=1
-+ @ Load from bytes & expand later - at the very least this uses less
-+ @ memory than having a short table
-+ adr r12, nbx2_3_0_1_4
-+ vld1.8 {q0 }, [r12 :128] @ 3,3..0,0,1,1..4,4
-+ vld1.16 {q14}, [r2 :128] @ left
-+ ldr r12, [r2, #16] @ Down left
-+ vld1.16 {q12}, [r1 :128] @ Up
-+ vmovl.u8 q8, d1
-+ vdup.32 q1, r12
-+ ldr r12, [r1, #16] @ Up-right
-+ vmovl.u8 q10, d0
-+
-+ lsl r3, #2
-+ vsub.i16 q2, q1, q12 @ Add set up
-+
-+ mov r1, #4
-+ vdup.32 q0, r12
-+ vshl.i16 q12, #2
-+ vmla.i16 q12, q8, q0 @ Acc set up - q8-q11 free
-+
-+@ u16 3,3..0,0 [1] q10
-+@ u32 left[y] [1] q14
-+@ u16 acc [1] q12 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [1] q2 = p[-1][nTbs] - p[x][-1]
-+1:
-+ vdup.32 q0, d28[0]
-+ vext.32 q14, q14, #1
-+
-+ vadd.i16 q12, q2
-+
-+ vmul.i16 q0, q10, q0
-+
-+ vadd.i16 q0, q12
-+
-+ vrshr.u16 q0, #3
-+
-+ subs r1, #1
-+ vst1.16 {q0 }, [r0 :128], r3
-+
-+ bne 1b
-+
-+ bx lr
-+endfunc
+
+
+@ ff_hevc_rpi_pred_planar_c_8_neon_10
@@ -13798,61 +13818,155 @@ index 0000000000..9fb3633862
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_planar_c_8_neon_10, export=1
++
+ @ Load from bytes & expand later - at the very least this uses less
+ @ memory than having a short table
-+ adr r12, nbx2_7_0_1_8
-+ vld1.8 {q0, q1 }, [r12 :128] @ 7,7..0,0,1,1..8,8
-+ vld1.16 {q14, q15}, [r2 :128]
-+ ldr r12, [r2, #32] @ Down left
-+ vld1.16 {q12, q13}, [r1 :128] @ Up
-+ vmovl.u8 q9, d3
-+ vmovl.u8 q8, d2
-+ vdup.32 q1, r12
-+ ldr r12, [r1, #32] @ Up-right
-+ vmovl.u8 q11, d1
-+ vmovl.u8 q10, d0
++ adr ip, nbx2_7_0_1_8 + 16
++ vld1.16 {q0-q1}, [r1 :128]! @ Top (left)
++ add r2, #32
++ vld1.8 {q2}, [ip :128] @ {1,1,2,2,3,3...8,8}
++ lsl r3, #2
++ vld1.32 {d6[],d7[]}, [r1] @ Top (right)
++ sub ip, #16
++ vmovl.u8 q8, d4
++ mov r1, #8
++ vshl.i16 q9, q0, #3
++ vmovl.u8 q2, d5
++ vshl.i16 q10, q1, #3
++ vld1.32 {d22[],d23[]}, [r2] @ Left (lower)
++ sub r2, #32
++ vld1.8 {q12}, [ip] @ {7,7,6,6,5,5...0,0}
++ vmla.i16 q9, q8, q3
++ vmla.i16 q10, q2, q3 @ Acc set up
++ vsub.i16 q0, q11, q0
++ vsub.i16 q1, q11, q1 @ Add set up
++ vadd.i16 q2, q9, q0
++ vadd.i16 q3, q10, q1
++ vmovl.u8 q8, d24
++ vmovl.u8 q9, d25
+
-+ lsl r3, #2
-+ vsub.i16 q3, q1, q13
-+ vsub.i16 q2, q1, q12 @ Add set up
++@ u16 7..0 [2] q8,q9
++@ u32 left[y] [2] [r2]
++@ u16 acc [2] q2,q3 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [2] q0,q1 = p[-1][nTbs] - p[x][-1]
+
-+ mov r1, #8
-+ vdup.32 q0, r12
-+ vshl.i16 q13, #3
-+ vshl.i16 q12, #3
-+ vmla.i16 q13, q9, q0
-+ vmla.i16 q12, q8, q0 @ Acc set up - q8-q11 free
-+
-+@ u16 7,7..0,0 [2] q10..q11
-+@ u32 left[y] [2] q14..q15
-+@ u16 acc [2] q12..q13 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [2] q2..q3 = p[-1][nTbs] - p[x][-1]
+1:
-+ vdup.32 q0, d28[0]
-+ vext.32 q14, q15, #1
-+ vext.32 q15, q15, #1
-+
-+ vadd.i16 q13, q3
-+ vadd.i16 q12, q2
-+
-+ vmul.i16 q1, q11, q0
-+ vmul.i16 q0, q10, q0
-+
-+ vadd.i16 q1, q13
-+ vadd.i16 q0, q12
-+
-+ vrshr.u16 q1, #4
-+ vrshr.u16 q0, #4
-+
-+ subs r1, #1
-+ vst1.16 {q0, q1 }, [r0 :256], r3
-+
++ vadd.i16 q10, q2, q0
++ subs r1, #2
++ vld1.32 {d24[],d25[]}, [r2]!
++ vadd.i16 q11, q3, q1
++ vld1.32 {d28[],d29[]}, [r2]!
++ vmla.i16 q2, q8, q12
++ vmla.i16 q3, q9, q12
++ vadd.i16 q12, q10, q0
++ vmla.i16 q10, q8, q14
++ vadd.i16 q13, q11, q1
++ vmla.i16 q11, q9, q14
++ vrshr.u16 q14, q2, #4
++ vrshr.u16 q15, q3, #4
++ vmov q2, q12
++ vst1.16 {q14-q15}, [r0 :128], r3
++ vrshr.u16 q14, q10, #4
++ vrshr.u16 q15, q11, #4
++ vmov q3, q13
++ vst1.16 {q14-q15}, [r0 :128], r3
+ bne 1b
+
+ bx lr
+endfunc
+
+
++@ ff_hevc_rpi_pred_planar_c_16_neon_8
++@ uint8_t *_src, [r0]
++@ const uint8_t *_top, [r1]
++@ const uint8_t *_left, [r2]
++@ ptrdiff_t stride) [r3]
++
++function ff_hevc_rpi_pred_planar_c_16_neon_8, export=1
++
++ vld1.8 {q0-q1}, [r1 :128]! @ Top (left)
++ adr ip, nbx2_15_0_1_16 + 32
++ vpush {d8-d12}
++ vld1.8 {q2-q3}, [ip :128] @ {1,1,2,2,3,3...16,16}
++ add r2, #32
++ vld1.16 {d8[]}, [r1] @ Top (right)
++ sub ip, #32
++ vshll.u8 q8, d0, #4
++ mov r1, #16
++ vld1.16 {d9[]}, [r2] @ Left (lower)
++ sub r2, #32
++ vshll.u8 q9, d1, #4
++ lsl r3, #1
++ vshll.u8 q10, d2, #4
++ vshll.u8 q11, d3, #4
++ vmlal.u8 q8, d4, d8
++ vsubl.u8 q12, d9, d0
++ vmlal.u8 q9, d5, d8
++ vsubl.u8 q13, d9, d1
++ vmlal.u8 q10, d6, d8
++ vsubl.u8 q14, d9, d2
++ vmlal.u8 q11, d7, d8 @ Acc set up
++ vsubl.u8 q15, d9, d3 @ Add set up
++ vadd.i16 q8, q12
++ vadd.i16 q9, q13
++ vadd.i16 q10, q14
++ vadd.i16 q11, q15
++ vld1.8 {q4-q5}, [ip :128] @ {15,15,14,14,13,13...0,0}
++
++@ u8 15..0 [2] q4,q5
++@ u8 left[y] [2] [r2]
++@ u16 acc [4] q8-q11 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [4] q12-q15 = p[-1][nTbs] - p[x][-1]
++
++ vld1.16 {d12[]}, [r2]!
++ vadd.i16 q0, q8, q12
++ b 2f
++1:
++ vld1.16 {d12[]}, [r2]!
++ vrshrn.u16 d3, q1, #5
++ vrshrn.u16 d2, q0, #5
++ vadd.i16 q0, q8, q12
++ vrshrn.u16 d4, q2, #5
++ vrshrn.u16 d5, q3, #5
++ vst1.8 {q1-q2}, [r0 :128], r3
++2: vadd.i16 q1, q9, q13
++ subs r1, #2
++ vadd.i16 q2, q10, q14
++ vadd.i16 q3, q11, q15
++ vmlal.u8 q8, d8, d12
++ vmlal.u8 q9, d9, d12
++ vmlal.u8 q10, d10, d12
++ vmlal.u8 q11, d11, d12
++ vld1.16 {d12[]}, [r2]!
++ vrshrn.u16 d19, q9, #5
++ vrshrn.u16 d18, q8, #5
++ vadd.i16 q8, q0, q12
++ vrshrn.u16 d20, q10, #5
++ vrshrn.u16 d21, q11, #5
++ vst1.8 {q9-q10}, [r0 :128], r3
++ vadd.i16 q9, q1, q13
++ vadd.i16 q10, q2, q14
++ vadd.i16 q11, q3, q15
++ vmlal.u8 q0, d8, d12
++ vmlal.u8 q1, d9, d12
++ vmlal.u8 q2, d10, d12
++ vmlal.u8 q3, d11, d12
++
++ bne 1b
++
++ vpop {d8-d12}
++
++ vrshrn.u16 d3, q1, #5
++ vrshrn.u16 d2, q0, #5
++ vrshrn.u16 d4, q2, #5
++ vrshrn.u16 d5, q3, #5
++ vst1.8 {q1-q2}, [r0 :128]
++
++ bx lr
++
++endfunc
++
++
+@ ff_hevc_rpi_pred_planar_c_16_neon_10
+@ uint8_t *_src, [r0]
+@ const uint8_t *_top, [r1]
@@ -13860,80 +13974,98 @@ index 0000000000..9fb3633862
+@ ptrdiff_t stride) [r3]
+
+function ff_hevc_rpi_pred_planar_c_16_neon_10, export=1
++
+ @ Load from bytes & expand later - at the very least this uses less
+ @ memory than having a short table
-+ adr r12, nbx2_15_0_1_16
-+ vpush { q4-q7 }
-+ vldm r12, { q0-q3 } @ 1..32, r12 points at 31..0
-+ vldm r1!, {q12-q15} @ Up
-+ ldr r12, [r2, #64] @ Down left
-+ vmovl.u8 q11, d7
-+ vmovl.u8 q10, d6
-+ vmovl.u8 q9, d5
-+ vmovl.u8 q8, d4
-+ vdup.32 q3, r12
-+ ldr r12, [r1] @ Up-right
++ vld1.16 {q0-q1}, [r1 :128]! @ Top (left)
++ adr ip, nbx2_15_0_1_16 + 32
++ vpush {q4-q7}
++ vld1.16 {q2-q3}, [r1 :128]! @ Top (centre)
++ add r2, #64
++ vld1.8 {q14-q15}, [ip :128] @ {1,1,2,2,3,3...16,16}
++T lsl r3, #2
++ vld1.32 {d8[],d9[]}, [r1] @ Top (right)
++ sub ip, #32
++ vmovl.u8 q12, d28
++ mov r1, #16
++ vmovl.u8 q13, d29
++ vld1.8 {q6-q7}, [ip :128] @ {15,15,14,14,13,13...0,0}
++ vmovl.u8 q14, d30
++ vmovl.u8 q15, d31
++ vld1.32 {d10[],d11[]}, [r2] @ Left (lower)
++ sub r2, #64
++ vshl.i16 q8, q0, #4
++ vshl.i16 q9, q1, #4
++ vshl.i16 q10, q2, #4
++ vshl.i16 q11, q3, #4
++ vmla.i16 q8, q12, q4
++ vsub.i16 q0, q5, q0
++ vmla.i16 q9, q13, q4
++ vpush {q0}
++ vsub.i16 q1, q5, q1
++ vmla.i16 q10, q14, q4
++ vsub.i16 q2, q5, q2
++ vmla.i16 q11, q15, q4 @ Acc set up
++ vsub.i16 q3, q5, q3 @ Add set up
++ vadd.i16 q8, q0
++ vadd.i16 q9, q1
++ vadd.i16 q10, q2
++ vadd.i16 q11, q3
++ vmovl.u8 q4, d12
++ vmovl.u8 q5, d13
++ vmovl.u8 q6, d14
++ vmovl.u8 q7, d15
+
-+ vsub.i16 q7, q3, q15
-+ vsub.i16 q6, q3, q14
-+ vsub.i16 q5, q3, q13
-+ vsub.i16 q4, q3, q12 @ Add set up
++@ u16 31..0 [4] q4-q7
++@ u16 left[y] [4] [r2]
++@ u16 acc [4] q8-q11 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
++@ u16 add [4] q0-q3 = p[-1][nTbs] - p[x][-1]
+
-+ vdup.32 q2, r12
-+ vshl.i16 q15, #4
-+ vshl.i16 q14, #4
-+ vshl.i16 q13, #4
-+ vshl.i16 q12, #4
-+ vmla.i16 q15, q11, q2
-+ vmla.i16 q14, q10, q2
-+ vmla.i16 q13, q9, q2
-+ vmla.i16 q12, q8, q2 @ Acc set up - q8-q11 free
-+
-+ mov r1, #16
-+ vmovl.u8 q11, d3
-+ vmovl.u8 q10, d2
-+ vmovl.u8 q9, d1
-+ vmovl.u8 q8, d0
-+
-+@ u16 15,15..0,0 [4] q8..q11
-+@ u32 left[y] [4] [r2]
-+@ u16 acc [4] q12..q15 = (x+1)*p[nTbS][-1] + 32*p[x][-1] initially
-+@ u16 add [4] q4..q7 = p[-1][nTbs] - p[x][-1]
++ vadd.i16 q12, q8, q0
++A sub r0, r0, r3, lsl #2
++T sub r0, r3
+1:
-+ ldr r12, [r2], #4
-+
-+ vadd.i16 q15, q7
-+ vadd.i16 q14, q6
-+ vdup.32 q0, r12
-+ vadd.i16 q13, q5
-+ vadd.i16 q12, q4
-+
-+ vmul.i16 q3, q11, q0
-+ vmul.i16 q2, q10, q0
-+ vmul.i16 q1, q9, q0
-+ vmul.i16 q0, q8, q0
-+
-+ vadd.i16 q3, q15
-+ vadd.i16 q2, q14
-+ vadd.i16 q1, q13
-+ vadd.i16 q0, q12
-+
-+ vrshr.u16 q3, #5
-+ vrshr.u16 q2, #5
-+ vrshr.u16 q1, #5
-+ vrshr.u16 q0, #5
-+
-+ subs r1, #1
-+ vstm r0, { q0-q3 }
-+ add r0, r0, r3, lsl #2
-+
++ vld1.32 {d0[],d1[]}, [r2]!
++A add r0, r0, r3, lsl #2
++T add r0, r3
++ vadd.i16 q13, q9, q1
++ subs r1, #2
++ vadd.i16 q14, q10, q2
++ vadd.i16 q15, q11, q3
++ vmla.i16 q8, q4, q0
++ vmla.i16 q9, q5, q0
++ vmla.i16 q10, q6, q0
++ vmla.i16 q11, q7, q0
++ vld1.16 {q0}, [sp]
++ vrshr.u16 q8, #5
++ vrshr.u16 q9, #5
++ vrshr.u16 q10, #5
++ vrshr.u16 q11, #5
++ vstm r0, {q8-q11}
++ vadd.i16 q8, q12, q0
++A add r0, r0, r3, lsl #2
++T add r0, r3
++ vld1.32 {d0[],d1[]}, [r2]!
++ vadd.i16 q9, q13, q1
++ vadd.i16 q10, q14, q2
++ vadd.i16 q11, q15, q3
++ vmla.i16 q12, q4, q0
++ vmla.i16 q13, q5, q0
++ vmla.i16 q14, q6, q0
++ vmla.i16 q15, q7, q0
++ vld1.16 {q0}, [sp]
++ vrshr.u16 q12, #5
++ vrshr.u16 q13, #5
++ vrshr.u16 q14, #5
++ vrshr.u16 q15, #5
++ vstm r0, {q12-q15}
++ vadd.i16 q12, q8, q0
+ bne 1b
+
-+ vpop {q4-q7}
-+ bx lr
++ vpop {q3-q7}
++ bx lr
++
+endfunc
-+
-+
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fb0c6fae70..9f2ebb16f3 100644
--- a/libavcodec/avcodec.h
@@ -14124,10 +14256,10 @@ index d181b74570..c52c450956 100644
if ((ret = av_image_copy_to_buffer(pkt->data, pkt->size,
diff --git a/libavcodec/rpi_hevc_cabac.c b/libavcodec/rpi_hevc_cabac.c
new file mode 100644
-index 0000000000..f053ebcc59
+index 0000000000..79549c411a
--- /dev/null
+++ b/libavcodec/rpi_hevc_cabac.c
-@@ -0,0 +1,2266 @@
+@@ -0,0 +1,2253 @@
+/*
+ * HEVC CABAC decoding
+ *
@@ -15007,25 +15139,6 @@ index 0000000000..f053ebcc59
+ return i;
+}
+
-+int ff_hevc_rpi_split_coding_unit_flag_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc, int ct_depth, int x0, int y0)
-+{
-+ int inc = 0, depth_left = 0, depth_top = 0;
-+ int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size);
-+ int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size);
-+ int x_cb = x0 >> s->ps.sps->log2_min_cb_size;
-+ int y_cb = y0 >> s->ps.sps->log2_min_cb_size;
-+
-+ if ((lc->ctb_avail & AVAIL_L) != 0 || x0b)
-+ depth_left = s->tab_ct_depth[(y_cb) * s->ps.sps->min_cb_width + x_cb - 1];
-+ if ((lc->ctb_avail & AVAIL_U) != 0 || y0b)
-+ depth_top = s->tab_ct_depth[(y_cb - 1) * s->ps.sps->min_cb_width + x_cb];
-+
-+ inc += (depth_left > ct_depth);
-+ inc += (depth_top > ct_depth);
-+
-+ return GET_CABAC_LC(elem_offset[SPLIT_CODING_UNIT_FLAG] + inc);
-+}
-+
+int ff_hevc_rpi_part_mode_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc, const int log2_cb_size)
+{
+ if (GET_CABAC_LC(elem_offset[PART_MODE])) // 1
@@ -15667,6 +15780,8 @@ index 0000000000..f053ebcc59
+ int prev_sig = 0;
+ int may_hide_sign;
+
++ int16_t dummy_coeffs[16];
++
+ // Derive QP for dequant
+ if (!lc->cu.cu_transquant_bypass_flag) {
+ may_hide_sign = s->ps.pps->sign_data_hiding_flag;
@@ -15831,14 +15946,14 @@ index 0000000000..f053ebcc59
+
+ {
+ const unsigned int ccount = 1 << (log2_trafo_size * 2);
-+ const int special = lc->cu.cu_transquant_bypass_flag || trans_skip_or_bypass || lc->tu.cross_pf; // These need special processing
++ const int special = trans_skip_or_bypass /* || lc->tu.cross_pf */; // These need special processing
+ use_vpu = 0;
+ use_dc = (num_coeff == 1) && !special &&
+ !(lc->cu.pred_mode == MODE_INTRA && c_idx == 0 && log2_trafo_size == 2);
+
+ if (use_dc) {
+ // Just need a little empty space
-+ coeffs = (int16_t*)(c_idx_nz ? lc->edge_emu_buffer2 : lc->edge_emu_buffer);
++ coeffs = dummy_coeffs;
+ // No need to clear
+ }
+ else
@@ -16237,6 +16352,9 @@ index 0000000000..f053ebcc59
+ }
+ }
+ }
++
++#if 0
++ // Mildly rotted - we support no mode where cross is valid
+ if (lc->tu.cross_pf) {
+ int16_t * const coeffs_y = (int16_t*)lc->edge_emu_buffer;
+ const int ccount = 1 << (log2_trafo_size * 2);
@@ -16245,6 +16363,7 @@ index 0000000000..f053ebcc59
+ coeffs[i] = coeffs[i] + ((lc->tu.res_scale_val * coeffs_y[i]) >> 3);
+ }
+ }
++#endif
+
+ if (!use_dc) {
+#if RPI_COMPRESS_COEFFS
@@ -16396,10 +16515,10 @@ index 0000000000..f053ebcc59
+#endif
diff --git a/libavcodec/rpi_hevc_cabac_fns.h b/libavcodec/rpi_hevc_cabac_fns.h
new file mode 100644
-index 0000000000..f6daf936ca
+index 0000000000..47c9c7029d
--- /dev/null
+++ b/libavcodec/rpi_hevc_cabac_fns.h
-@@ -0,0 +1,190 @@
+@@ -0,0 +1,191 @@
+#ifndef AVCODEC_RPI_HEVC_CABAC_FNS_H
+#define AVCODEC_RPI_HEVC_CABAC_FNS_H
+
@@ -16414,8 +16533,6 @@ index 0000000000..f6daf936ca
+int ff_hevc_rpi_sao_offset_abs_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc);
+int ff_hevc_rpi_sao_offset_sign_decode(HEVCRpiLocalContext * const lc);
+int ff_hevc_rpi_sao_eo_class_decode(HEVCRpiLocalContext * const lc);
-+int ff_hevc_rpi_split_coding_unit_flag_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc, const int ct_depth,
-+ const int x0, const int y0);
+int ff_hevc_rpi_part_mode_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc, const int log2_cb_size);
+int ff_hevc_rpi_mpm_idx_decode(HEVCRpiLocalContext * const lc);
+int ff_hevc_rpi_rem_intra_luma_pred_mode_decode(HEVCRpiLocalContext * const lc);
@@ -16522,18 +16639,21 @@ index 0000000000..f6daf936ca
+ return ff_hevc_rpi_get_cabac(&lc->cc, lc->cabac_state + HEVC_BIN_CU_CHROMA_QP_OFFSET_FLAG);
+}
+
++static inline int ff_hevc_rpi_split_coding_unit_flag_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc,
++ const unsigned int ct_depth,
++ const unsigned int x0, const unsigned int y0)
++{
++ return ff_hevc_rpi_get_cabac(&lc->cc, lc->cabac_state + HEVC_BIN_SPLIT_CODING_UNIT_FLAG +
++ ((s->cabac_stash_left[y0 >> 3] >> 1) > ct_depth) +
++ ((s->cabac_stash_up[x0 >> 3] >> 1) > ct_depth));
++}
++
+static inline int ff_hevc_rpi_skip_flag_decode(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc,
+ const int x0, const int y0, const int x_cb, const int y_cb)
+{
-+ const unsigned int ctb_mask = (1 << s->ps.sps->log2_ctb_size) - 1;
-+ const unsigned int stride = s->skip_flag_stride;
-+ const uint8_t * const skip_bits = s->skip_flag + y_cb * stride;
-+
+ return ff_hevc_rpi_get_cabac(&lc->cc, lc->cabac_state + HEVC_BIN_SKIP_FLAG +
-+ (((lc->ctb_avail & AVAIL_L) == 0 && (x0 & ctb_mask) == 0) ? 0 :
-+ (skip_bits[((x_cb - 1) >> 3)] >> ((x_cb - 1) & 7)) & 1) +
-+ (((lc->ctb_avail & AVAIL_U) == 0 && (y0 & ctb_mask) == 0) ? 0 :
-+ (skip_bits[(x_cb >> 3) - stride] >> (x_cb & 7)) & 1));
++ (s->cabac_stash_left[y0 >> 3] & 1) +
++ (s->cabac_stash_up[x0 >> 3] & 1));
+}
+
+static inline int ff_hevc_rpi_pred_mode_decode(HEVCRpiLocalContext * const lc)
@@ -16710,10 +16830,10 @@ index 0000000000..0aee673d8b
+#endif /* AVCODEC_RPI_HEVC_DATA_H */
diff --git a/libavcodec/rpi_hevc_filter.c b/libavcodec/rpi_hevc_filter.c
new file mode 100644
-index 0000000000..05d447eaa5
+index 0000000000..8e7695bcf9
--- /dev/null
+++ b/libavcodec/rpi_hevc_filter.c
-@@ -0,0 +1,1210 @@
+@@ -0,0 +1,1204 @@
+/*
+ * HEVC video decoder
+ *
@@ -17896,12 +18016,6 @@ index 0000000000..05d447eaa5
+ il, it, ir - il, ib - it,
+ ctx_vshift(s, 1), 1, 1);
+
-+ // *** Tiles where V tile boundries aren't on cache boundries
-+ // We have a race condition between ARM side recon in the tlle
-+ // on the left & QPU pred in the tile on the right
-+ // The code below ameliorates it as does turning off WPP in
-+ // these cases but it still exists :-(
-+
+ // If we have to commit the right hand tile boundry due to
+ // cache boundry considerations then at EoTile we must commit
+ // that boundry to bottom of tile (bounds)
@@ -18826,10 +18940,10 @@ index 0000000000..4b4d032a16
+#endif /* AVCODEC_RPI_HEVC_PARSE_H */
diff --git a/libavcodec/rpi_hevc_ps.c b/libavcodec/rpi_hevc_ps.c
new file mode 100644
-index 0000000000..4967b3f44c
+index 0000000000..98e2fd7009
--- /dev/null
+++ b/libavcodec/rpi_hevc_ps.c
-@@ -0,0 +1,1934 @@
+@@ -0,0 +1,1940 @@
+/*
+ * HEVC Parameter Set decoding
+ *
@@ -20232,6 +20346,12 @@ index 0000000000..4967b3f44c
+ pps->log2_max_transform_skip_block_size = get_ue_golomb_long(gb) + 2;
+ }
+ pps->cross_component_prediction_enabled_flag = get_bits1(gb);
++ if (pps->cross_component_prediction_enabled_flag &&
++ (sps->chroma_format_idc != 3 || sps->separate_colour_plane_flag))
++ {
++ av_log(avctx, AV_LOG_ERROR, "cross_component_prediction_enabled but chroma_format_idc != 3\n");
++ return AVERROR_INVALIDDATA;
++ }
+ pps->chroma_qp_offset_list_enabled_flag = get_bits1(gb);
+ if (pps->chroma_qp_offset_list_enabled_flag) {
+ int err;
@@ -27029,10 +27149,10 @@ index 0000000000..3557348e30
+};
diff --git a/libavcodec/rpi_hevcdec.c b/libavcodec/rpi_hevcdec.c
new file mode 100644
-index 0000000000..7c98f707d3
+index 0000000000..255dd6835a
--- /dev/null
+++ b/libavcodec/rpi_hevcdec.c
-@@ -0,0 +1,5850 @@
+@@ -0,0 +1,5799 @@
+/*
+ * HEVC video Decoder
+ *
@@ -27226,7 +27346,7 @@ index 0000000000..7c98f707d3
+ ipe_chan_info_t chroma;
+} ipe_init_info_t;
+
-+static void set_bytes(uint8_t * b, const unsigned int stride, const unsigned int ln, unsigned int a)
++static void set_bytes(uint8_t * b, const unsigned int stride, const int ln, unsigned int a)
+{
+ switch (ln)
+ {
@@ -27278,6 +27398,60 @@ index 0000000000..7c98f707d3
+ }
+}
+
++// We expect this to be called with ln = (log2_cb_size - 3) so range = -1..3
++// (4 not required)
++static void set_cabac_stash(uint8_t * b_u, uint8_t * b_l, const int ln, unsigned int a)
++{
++ switch (ln)
++ {
++ default: // 0 or -1
++ *b_u = a;
++ *b_l = a;
++ break;
++ case 1:
++ a |= a << 8;
++ *(uint16_t *)b_u = a;
++ *(uint16_t *)b_l = a;
++ break;
++ case 2:
++ a |= a << 8;
++ a |= a << 16;
++ *(uint32_t *)b_u = a;
++ *(uint32_t *)b_l = a;
++ break;
++ case 3:
++ a |= a << 8;
++ a |= a << 16;
++ *(uint32_t *)b_u = a;
++ *(uint32_t *)(b_u + 4) = a;
++ *(uint32_t *)b_l = a;
++ *(uint32_t *)(b_l + 4) = a;
++ break;
++ }
++}
++
++static void zap_cabac_stash(uint8_t * b, const int ln)
++{
++ switch (ln)
++ {
++ default: // 0
++ *b = 0;
++ break;
++ case 1:
++ *(uint16_t *)b = 0;
++ break;
++ case 2:
++ *(uint32_t *)b = 0;
++ break;
++ case 3:
++ *(uint32_t *)b = 0;
++ *(uint32_t *)(b + 4) = 0;
++ break;
++ }
++}
++
++
++
+// Set a small square block of bits in a bitmap
+// Bits must be aligned on their size boundry (which will be true of all split CBs)
+static void set_bits(uint8_t * f, const unsigned int x, const unsigned int stride, const unsigned int ln)
@@ -27958,8 +28132,8 @@ index 0000000000..7c98f707d3
+ av_freep(&s->sao);
+ av_freep(&s->deblock);
+
-+ av_freep(&s->skip_flag);
-+ av_freep(&s->tab_ct_depth);
++ av_freep(&s->cabac_stash_up);
++ s->cabac_stash_left = NULL; // freed with _up
+
+ av_freep(&s->tab_ipm);
+ av_freep(&s->is_pcm);
@@ -27969,7 +28143,6 @@ index 0000000000..7c98f707d3
+ av_freep(&s->filter_slice_edges);
+
+ av_freep(&s->bs_horizontal);
-+// av_freep(&s->vertical_bs);
+ av_freep(&s->bs_vertical);
+ av_freep(&s->bsf_stash_left);
+ av_freep(&s->bsf_stash_up);
@@ -28004,10 +28177,9 @@ index 0000000000..7c98f707d3
+ if (!s->sao || !s->deblock)
+ goto fail;
+
-+ s->skip_flag_stride = (sps->min_cb_width + 7) >> 3;
-+ s->skip_flag = av_malloc_array(sps->min_cb_height, s->skip_flag_stride);
-+ s->tab_ct_depth = av_malloc_array(sps->min_cb_height, sps->min_cb_width);
-+ if (!s->skip_flag || !s->tab_ct_depth)
++ s->cabac_stash_up = av_malloc((((width + 63) & ~63) >> 3) + (((height + 63) & ~63) >> 3));
++ s->cabac_stash_left = s->cabac_stash_up + (((width + 63) & ~63) >> 3);
++ if (s->cabac_stash_up == NULL)
+ goto fail;
+
+ s->tab_ipm = av_mallocz(min_pu_size);
@@ -28749,7 +28921,7 @@ index 0000000000..7c98f707d3
+
+ sh->num_entry_point_offsets = 0;
+ sh->offload_wpp = 0;
-+ sh->offload_wpp = 0;
++ sh->offload_tiles = 0;
+
+ if (s->ps.pps->tiles_enabled_flag || s->ps.pps->entropy_coding_sync_enabled_flag) {
+ unsigned num_entry_point_offsets = get_ue_golomb_long(gb);
@@ -28791,7 +28963,7 @@ index 0000000000..7c98f707d3
+ // Do we want to offload this
+ if (s->threads_type != 0)
+ {
-+ sh->offload_wpp = (!s->ps.pps->tile_wpp_inter_disable || sh->slice_type == HEVC_SLICE_I) &&
++ sh->offload_tiles = (!s->ps.pps->tile_wpp_inter_disable || sh->slice_type == HEVC_SLICE_I) &&
+ s->ps.pps->num_tile_columns > 1;
+ // * We only cope with WPP in a single column
+ // Probably want to deal with that case as tiles rather than WPP anyway
@@ -28910,7 +29082,7 @@ index 0000000000..7c98f707d3
+ }
+}
+
-+
++#if 0
+static int hls_cross_component_pred(HEVCRpiLocalContext * const lc, const int idx) {
+ int log2_res_scale_abs_plus1 = ff_hevc_rpi_log2_res_scale_abs(lc, idx); // 0..4
+
@@ -28925,6 +29097,7 @@ index 0000000000..7c98f707d3
+
+ return 0;
+}
++#endif
+
+static inline HEVCPredCmd * rpi_new_intra_cmd(HEVCRpiJob * const jb)
+{
@@ -28956,40 +29129,30 @@ index 0000000000..7c98f707d3
+ const HEVCRpiContext * const s, const HEVCRpiLocalContext * const lc,
+ const unsigned int x, const unsigned int y, const unsigned int w, const unsigned int h)
+{
-+ const unsigned int ctb_size = 1 << s->ps.sps->log2_ctb_size;
-+ const unsigned int ctb_mask = ctb_size - 1;
-+ const unsigned int tb_x = x & ctb_mask;
-+ const unsigned int tb_y = y & ctb_mask;
++ const unsigned int ctb_mask = ~0U << s->ps.sps->log2_ctb_size;
++ const unsigned int tb_x = x & ~ctb_mask;
++ const unsigned int tb_y = y & ~ctb_mask;
++ const unsigned int ctb_avail = lc->ctb_avail;
+
+ const uint8_t * const tb_f = tb_flags + (tb_x >> 2) + (tb_y >> 2) * 16;
+
-+ unsigned int f = (lc->ctb_avail | tb_f[0]) & (AVAIL_L | AVAIL_U | AVAIL_UL);
++ unsigned int f = (ctb_avail | tb_f[0]) & (AVAIL_L | AVAIL_U | AVAIL_UL);
+
-+ if ((tb_x != 0 || tb_y != 0) && (~f & (AVAIL_L | AVAIL_U)) == 0)
++ // This deals with both the U & L edges
++ if ((tb_x | tb_y) != 0 && (~f & (AVAIL_L | AVAIL_U)) == 0)
+ f |= AVAIL_UL;
+
-+
-+ if (x + w >= lc->end_of_ctb_x)
-+ {
-+ if (tb_y == 0)
-+ f |= (lc->ctb_avail & AVAIL_UR);
-+ }
-+ else
-+ {
-+ f |= (tb_y != 0) ? (tb_f[(w - 1) >> 2] & AVAIL_UR) : (lc->ctb_avail >> (AVAIL_S_U - AVAIL_S_UR)) & AVAIL_UR;
-+ }
++ if (x + w < lc->end_of_ctb_x)
++ f |= (tb_y == 0 ? ctb_avail >> (AVAIL_S_U - AVAIL_S_UR) : tb_f[(w - 1) >> 2]) & AVAIL_UR;
++ else if (tb_y == 0)
++ f |= (ctb_avail & AVAIL_UR);
+#if AVAIL_S_U - AVAIL_S_UR < 0
+#error Shift problem
+#endif
+
+ // Never any D if Y beyond eoctb
+ if (y + h < lc->end_of_ctb_y)
-+ {
-+ if (tb_x == 0)
-+ f |= (lc->ctb_avail << (AVAIL_S_DL - AVAIL_S_L)) & AVAIL_DL;
-+ else
-+ f |= tb_f[((h - 1) >> 2) * 16] & AVAIL_DL;
-+ }
++ f |= (tb_x == 0 ? ctb_avail << (AVAIL_S_DL - AVAIL_S_L) : tb_f[((h - 1) >> 2) * 16]) & AVAIL_DL;
+#if AVAIL_S_DL - AVAIL_S_L < 0
+#error Shift problem
+#endif
@@ -29035,67 +29198,34 @@ index 0000000000..7c98f707d3
+#define CBF_CB1 (1 << CBF_CB1_S)
+#define CBF_CR1 (1 << CBF_CR1_S)
+
-+
++// * Only good for chroma_idx == 1
+static int hls_transform_unit(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc,
+ const unsigned int x0, const unsigned int y0,
-+ const unsigned int xBase, const unsigned int yBase,
-+ const unsigned int cb_xBase, const unsigned int cb_yBase,
+ const unsigned int log2_cb_size, const unsigned int log2_trafo_size,
+ const unsigned int blk_idx, const int cbf_luma,
+ const unsigned int const cbf_chroma)
+{
-+ const unsigned int log2_trafo_size_c = log2_trafo_size - ctx_hshift(s, 1);
-+ int i;
++ const unsigned int log2_trafo_size_c = FFMAX(2, log2_trafo_size - 1);
++ const unsigned int x0_c = x0 & ~7;
++ const unsigned int y0_c = y0 & ~7;
+
-+ if (lc->cu.pred_mode == MODE_INTRA) {
-+ const unsigned int trafo_size = 1 << log2_trafo_size;
-+ do_intra_pred(s, lc, log2_trafo_size, x0, y0, 0,
-+ ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0, trafo_size, trafo_size));
-+ }
++ enum ScanType scan_idx = SCAN_DIAG;
++ enum ScanType scan_idx_c = SCAN_DIAG;
+
-+ if (cbf_luma || cbf_chroma != 0)
++ if (lc->cu.pred_mode == MODE_INTRA)
+ {
-+ int scan_idx = SCAN_DIAG;
-+ int scan_idx_c = SCAN_DIAG;
++ const unsigned int trafo_size = 1 << log2_trafo_size;
++ const unsigned int avail = ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0, trafo_size, trafo_size);
+
-+ if (s->ps.pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded)
-+ {
-+ const int qp_delta = ff_hevc_rpi_cu_qp_delta(lc);
++ do_intra_pred(s, lc, log2_trafo_size, x0, y0, 0, avail);
+
-+ if (qp_delta < -(26 + (s->ps.sps->qp_bd_offset >> 1)) ||
-+ qp_delta > (25 + (s->ps.sps->qp_bd_offset >> 1)))
-+ {
-+ av_log(s->avctx, AV_LOG_ERROR,
-+ "The cu_qp_delta %d is outside the valid range "
-+ "[%d, %d].\n",
-+ qp_delta,
-+ -(26 + (s->ps.sps->qp_bd_offset >> 1)),
-+ (25 + (s->ps.sps->qp_bd_offset >> 1)));
-+ return AVERROR_INVALIDDATA;
-+ }
++ if (log2_trafo_size > 2)
++ do_intra_pred(s, lc, log2_trafo_size_c, x0_c, y0_c, 1, avail);
++ else if (blk_idx == 3)
++ do_intra_pred(s, lc, log2_trafo_size_c, x0_c, y0_c, 1,
++ ff_hevc_rpi_tb_avail_flags(s, lc, x0_c, y0_c, 8, 8));
+
-+ lc->tu.is_cu_qp_delta_coded = 1;
-+ lc->tu.cu_qp_delta = qp_delta;
-+ ff_hevc_rpi_set_qPy(s, lc, cb_xBase, cb_yBase);
-+ }
-+
-+ if (lc->tu.cu_chroma_qp_offset_wanted && cbf_chroma &&
-+ !lc->cu.cu_transquant_bypass_flag) {
-+ int cu_chroma_qp_offset_flag = ff_hevc_rpi_cu_chroma_qp_offset_flag(lc);
-+ if (cu_chroma_qp_offset_flag) {
-+ int cu_chroma_qp_offset_idx = 0;
-+ if (s->ps.pps->chroma_qp_offset_list_len_minus1 > 0) {
-+ cu_chroma_qp_offset_idx = ff_hevc_rpi_cu_chroma_qp_offset_idx(s, lc);
-+ av_log(s->avctx, AV_LOG_ERROR,
-+ "cu_chroma_qp_offset_idx not yet tested.\n");
-+ }
-+ lc->tu.qp_divmod6[1] += s->ps.pps->cb_qp_offset_list[cu_chroma_qp_offset_idx];
-+ lc->tu.qp_divmod6[2] += s->ps.pps->cr_qp_offset_list[cu_chroma_qp_offset_idx];
-+ }
-+ lc->tu.cu_chroma_qp_offset_wanted = 0;
-+ }
-+
-+ if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {
++ if (log2_trafo_size < 4) {
+ if (lc->tu.intra_pred_mode >= 6 &&
+ lc->tu.intra_pred_mode <= 14) {
+ scan_idx = SCAN_VERT;
@@ -29112,126 +29242,59 @@ index 0000000000..7c98f707d3
+ scan_idx_c = SCAN_HORIZ;
+ }
+ }
++ }
+
-+ lc->tu.cross_pf = 0;
++ if (!cbf_luma && cbf_chroma == 0)
++ return 0;
+
-+ if (cbf_luma)
-+ ff_hevc_rpi_hls_residual_coding(s, lc, x0, y0, log2_trafo_size, scan_idx, 0);
++ if (lc->tu.is_cu_qp_delta_wanted)
++ {
++ const int qp_delta = ff_hevc_rpi_cu_qp_delta(lc);
++ const unsigned int cb_mask = ~0U << log2_cb_size;
+
-+
-+ if (ctx_cfmt(s) != 0 && (log2_trafo_size > 2 || ctx_cfmt(s) == 3)) {
-+ const int trafo_size_h = 1 << (log2_trafo_size_c + ctx_hshift(s, 1));
-+ const int trafo_size_v = 1 << (log2_trafo_size_c + ctx_vshift(s, 1));
-+ lc->tu.cross_pf = (s->ps.pps->cross_component_prediction_enabled_flag && cbf_luma &&
-+ (lc->cu.pred_mode == MODE_INTER ||
-+ (lc->tu.chroma_mode_c == 4)));
-+
-+ if (lc->tu.cross_pf) {
-+ hls_cross_component_pred(lc, 0);
-+ }
-+ for (i = 0; i < (ctx_cfmt(s) == 2 ? 2 : 1); i++) {
-+ if (lc->cu.pred_mode == MODE_INTRA) {
-+ do_intra_pred(s, lc, log2_trafo_size_c, x0, y0 + (i << log2_trafo_size_c), 1,
-+ ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v));
-+ }
-+ if (((cbf_chroma >> i) & CBF_CB0) != 0)
-+ ff_hevc_rpi_hls_residual_coding(s, lc, x0, y0 + (i << log2_trafo_size_c),
-+ log2_trafo_size_c, scan_idx_c, 1);
-+ else if (lc->tu.cross_pf) {
-+ const ptrdiff_t stride = frame_stride1(s->frame, 1);
-+ const int hshift = ctx_hshift(s, 1);
-+ const int vshift = ctx_vshift(s, 1);
-+ int16_t * const coeffs_y = (int16_t*)lc->edge_emu_buffer;
-+ int16_t * const coeffs = (int16_t*)lc->edge_emu_buffer2;
-+ int size = 1 << log2_trafo_size_c;
-+
-+ uint8_t *dst = &s->frame->data[1][(y0 >> vshift) * stride +
-+ ((x0 >> hshift) << s->ps.sps->pixel_shift)];
-+ for (i = 0; i < (size * size); i++) {
-+ coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3);
-+ }
-+ s->hevcdsp.add_residual[log2_trafo_size_c-2](dst, coeffs, stride);
-+ }
-+ }
-+
-+ if (lc->tu.cross_pf) {
-+ hls_cross_component_pred(lc, 1);
-+ }
-+ for (i = 0; i < (ctx_cfmt(s) == 2 ? 2 : 1); i++) {
-+// if (lc->cu.pred_mode == MODE_INTRA) {
-+// do_intra_pred(s, lc, log2_trafo_size_c, x0, y0 + (i << log2_trafo_size_c), 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v));
-+// }
-+ if (((cbf_chroma >> i) & CBF_CR0) != 0)
-+ ff_hevc_rpi_hls_residual_coding(s, lc, x0, y0 + (i << log2_trafo_size_c),
-+ log2_trafo_size_c, scan_idx_c, 2);
-+ else if (lc->tu.cross_pf) {
-+ ptrdiff_t stride = frame_stride1(s->frame, 2);
-+ const int hshift = ctx_hshift(s, 2);
-+ const int vshift = ctx_vshift(s, 2);
-+ int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
-+ int16_t *coeffs = (int16_t*)lc->edge_emu_buffer2;
-+ const int size = 1 << log2_trafo_size_c;
-+ int j;
-+
-+ uint8_t *dst = &s->frame->data[2][(y0 >> vshift) * stride +
-+ ((x0 >> hshift) << s->ps.sps->pixel_shift)];
-+ for (j = 0; j < (size * size); j++) {
-+ coeffs[j] = ((lc->tu.res_scale_val * coeffs_y[j]) >> 3);
-+ }
-+ s->hevcdsp.add_residual[log2_trafo_size_c-2](dst, coeffs, stride);
-+ }
-+ }
-+ } else if (ctx_cfmt(s) != 0 && blk_idx == 3) {
-+ int trafo_size_h = 1 << (log2_trafo_size + 1);
-+ int trafo_size_v = 1 << (log2_trafo_size + ctx_vshift(s, 1));
-+ for (i = 0; i < (ctx_cfmt(s) == 2 ? 2 : 1); i++) {
-+ if (lc->cu.pred_mode == MODE_INTRA) {
-+ do_intra_pred(s, lc, log2_trafo_size, xBase, yBase + (i << log2_trafo_size), 1,
-+ ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase + (i << log2_trafo_size), trafo_size_h, trafo_size_v));
-+ }
-+ if (((cbf_chroma >> i) & CBF_CB0) != 0)
-+ ff_hevc_rpi_hls_residual_coding(s, lc, xBase, yBase + (i << log2_trafo_size),
-+ log2_trafo_size, scan_idx_c, 1);
-+ }
-+ for (i = 0; i < (ctx_cfmt(s) == 2 ? 2 : 1); i++) {
-+// if (lc->cu.pred_mode == MODE_INTRA) {
-+// do_intra_pred(s, lc, log2_trafo_size, xBase, yBase + (i << log2_trafo_size), 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase + (i << log2_trafo_size), trafo_size_h, trafo_size_v));
-+// }
-+ if (((cbf_chroma >> i) & CBF_CR0) != 0)
-+ ff_hevc_rpi_hls_residual_coding(s, lc, xBase, yBase + (i << log2_trafo_size),
-+ log2_trafo_size, scan_idx_c, 2);
-+ }
++ if (qp_delta < -(26 + (s->ps.sps->qp_bd_offset >> 1)) ||
++ qp_delta > (25 + (s->ps.sps->qp_bd_offset >> 1)))
++ {
++ av_log(s->avctx, AV_LOG_ERROR,
++ "The cu_qp_delta %d is outside the valid range "
++ "[%d, %d].\n",
++ qp_delta,
++ -(26 + (s->ps.sps->qp_bd_offset >> 1)),
++ (25 + (s->ps.sps->qp_bd_offset >> 1)));
++ return AVERROR_INVALIDDATA;
+ }
-+ } else if (ctx_cfmt(s) != 0 && lc->cu.pred_mode == MODE_INTRA) {
-+ if (log2_trafo_size > 2 || ctx_cfmt(s) == 3) {
-+ int trafo_size_h = 1 << (log2_trafo_size_c + ctx_hshift(s, 1));
-+ int trafo_size_v = 1 << (log2_trafo_size_c + ctx_vshift(s, 1));
-+ do_intra_pred(s, lc, log2_trafo_size_c, x0, y0, 1,
-+ ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0, trafo_size_h, trafo_size_v));
-+// do_intra_pred(s, lc, log2_trafo_size_c, x0, y0, 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0, trafo_size_h, trafo_size_v));
-+// if (ctx_cfmt(s) == 2) {
-+// do_intra_pred(s, lc, log2_trafo_size_c, x0, y0 + (1 << log2_trafo_size_c), 1,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0 + (1 << log2_trafo_size_c), trafo_size_h, trafo_size_v));
-+// do_intra_pred(s, lc, log2_trafo_size_c, x0, y0 + (1 << log2_trafo_size_c), 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, x0, y0 + (1 << log2_trafo_size_c), trafo_size_h, trafo_size_v));
-+// }
-+ } else if (blk_idx == 3) {
-+ int trafo_size_h = 1 << (log2_trafo_size + 1);
-+ int trafo_size_v = 1 << (log2_trafo_size + ctx_vshift(s, 1));
-+ do_intra_pred(s, lc, log2_trafo_size, xBase, yBase, 1,
-+ ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase, trafo_size_h, trafo_size_v));
-+// do_intra_pred(s, lc, log2_trafo_size, xBase, yBase, 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase, trafo_size_h, trafo_size_v));
-+// if (ctx_cfmt(s) == 2) {
-+// do_intra_pred(s, lc, log2_trafo_size, xBase, yBase + (1 << (log2_trafo_size)), 1,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase + (1 << (log2_trafo_size)), trafo_size_h, trafo_size_v));
-+// do_intra_pred(s, lc, log2_trafo_size, xBase, yBase + (1 << (log2_trafo_size)), 2,
-+// ff_hevc_rpi_tb_avail_flags(s, lc, xBase, yBase + (1 << (log2_trafo_size)), trafo_size_h, trafo_size_v));
-+// }
++
++ lc->tu.is_cu_qp_delta_wanted = 0;
++ lc->tu.cu_qp_delta = qp_delta;
++ ff_hevc_rpi_set_qPy(s, lc, x0 & cb_mask, y0 & cb_mask);
++ }
++
++ // * Not main profile & untested due to no conform streams
++ if (lc->tu.cu_chroma_qp_offset_wanted && cbf_chroma &&
++ !lc->cu.cu_transquant_bypass_flag) {
++ int cu_chroma_qp_offset_flag = ff_hevc_rpi_cu_chroma_qp_offset_flag(lc);
++ if (cu_chroma_qp_offset_flag) {
++ int cu_chroma_qp_offset_idx = 0;
++ if (s->ps.pps->chroma_qp_offset_list_len_minus1 > 0) {
++ cu_chroma_qp_offset_idx = ff_hevc_rpi_cu_chroma_qp_offset_idx(s, lc);
++ }
++ lc->tu.qp_divmod6[1] += s->ps.pps->cb_qp_offset_list[cu_chroma_qp_offset_idx];
++ lc->tu.qp_divmod6[2] += s->ps.pps->cr_qp_offset_list[cu_chroma_qp_offset_idx];
+ }
++ lc->tu.cu_chroma_qp_offset_wanted = 0;
++ }
++
++ if (cbf_luma)
++ ff_hevc_rpi_hls_residual_coding(s, lc, x0, y0, log2_trafo_size, scan_idx, 0);
++
++ if (log2_trafo_size > 2 || blk_idx == 3)
++ {
++ if ((cbf_chroma & CBF_CB0) != 0)
++ ff_hevc_rpi_hls_residual_coding(s, lc, x0_c, y0_c,
++ log2_trafo_size_c, scan_idx_c, 1);
++ if ((cbf_chroma & CBF_CR0) != 0)
++ ff_hevc_rpi_hls_residual_coding(s, lc, x0_c, y0_c,
++ log2_trafo_size_c, scan_idx_c, 2);
+ }
+
+ return 0;
@@ -29245,9 +29308,6 @@ index 0000000000..7c98f707d3
+
+static int hls_transform_tree(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc,
+ const unsigned int x0, const unsigned int y0,
-+ const unsigned int xBase, const unsigned int yBase,
-+ const unsigned int cb_xBase, const unsigned int cb_yBase,
-+ const unsigned int log2_cb_size,
+ const unsigned int log2_trafo_size,
+ const unsigned int trafo_depth, const unsigned int blk_idx,
+ const unsigned int cbf_c0)
@@ -29318,9 +29378,9 @@ index 0000000000..7c98f707d3
+
+#define SUBDIVIDE(x, y, idx) \
+do { \
-+ ret = hls_transform_tree(s, lc, x, y, x0, y0, cb_xBase, cb_yBase, log2_cb_size, \
++ ret = hls_transform_tree(s, lc, x, y, \
+ log2_trafo_size - 1, trafo_depth + 1, idx, \
-+ cbf_c1); \
++ cbf_c1); \
+ if (ret < 0) \
+ return ret; \
+} while (0)
@@ -29337,8 +29397,8 @@ index 0000000000..7c98f707d3
+ const int cbf_luma = ((lc->cu.pred_mode != MODE_INTRA && trafo_depth == 0 && cbf_c1 == 0) ||
+ ff_hevc_rpi_cbf_luma_decode(lc, trafo_depth));
+
-+ ret = hls_transform_unit(s, lc, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
-+ log2_cb_size, log2_trafo_size,
++ ret = hls_transform_unit(s, lc, x0, y0,
++ log2_trafo_size + trafo_depth, log2_trafo_size,
+ blk_idx, cbf_luma, cbf_c1);
+ if (ret < 0)
+ return ret;
@@ -30300,12 +30360,6 @@ index 0000000000..7c98f707d3
+ }
+}
+
-+static inline void set_skip(const HEVCRpiContext * const s, const unsigned int x_cb, const unsigned int y_cb, const unsigned int ln)
-+{
-+ const unsigned int stride = s->skip_flag_stride;
-+ set_bits(s->skip_flag + y_cb * stride, x_cb, stride, ln);
-+}
-+
+static int hls_coding_unit(const HEVCRpiContext * const s, HEVCRpiLocalContext * const lc,
+ const unsigned int x0, const unsigned int y0, const unsigned int log2_cb_size)
+{
@@ -30344,7 +30398,6 @@ index 0000000000..7c98f707d3
+ }
+
+ if (skip_flag) {
-+ set_skip(s, x_cb, y_cb, log2_cb_size - log2_min_cb_size);
+ lc->cu.pred_mode = MODE_SKIP;
+
+ hls_prediction_unit(s, lc, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
@@ -30443,8 +30496,7 @@ index 0000000000..7c98f707d3
+ s->ps.sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
+ s->ps.sps->max_transform_hierarchy_depth_inter;
+ // transform_tree does deblock_boundary_strengths
-+ ret = hls_transform_tree(s, lc, x0, y0, x0, y0, x0, y0,
-+ log2_cb_size,
++ ret = hls_transform_tree(s, lc, x0, y0,
+ log2_cb_size, 0, 0, cbf_c);
+ if (ret < 0)
+ return ret;
@@ -30455,8 +30507,8 @@ index 0000000000..7c98f707d3
+ }
+ }
+
-+ // ?? We do a set where we read the delta too ??
-+ if (s->ps.pps->cu_qp_delta_enabled_flag && lc->tu.is_cu_qp_delta_coded == 0)
++ // If the delta is still wanted then we haven't read the delta & therefore need to set qp here
++ if (lc->tu.is_cu_qp_delta_wanted)
+ ff_hevc_rpi_set_qPy(s, lc, x0, y0);
+
+ if(((x0 + (1<qp_y_tab + y_cb * min_cb_width + x_cb, min_cb_width, log2_cb_size - log2_min_cb_size, lc->qp_y & 0xff);
+
-+ set_bytes(s->tab_ct_depth + y_cb * min_cb_width + x_cb, min_cb_width, log2_cb_size - log2_min_cb_size, lc->ct_depth);
++ set_cabac_stash(s->cabac_stash_up + (x0 >> 3), s->cabac_stash_left + (y0 >> 3), log2_cb_size - 3, (lc->ct_depth << 1) | skip_flag);
+
+ return 0;
+}
@@ -30483,21 +30535,29 @@ index 0000000000..7c98f707d3
+ int split_cu;
+
+ lc->ct_depth = cb_depth;
++ split_cu = (log2_cb_size > s->ps.sps->log2_min_cb_size);
+ if (x0 + cb_size <= s->ps.sps->width &&
+ y0 + cb_size <= s->ps.sps->height &&
-+ log2_cb_size > s->ps.sps->log2_min_cb_size) {
++ split_cu)
++ {
+ split_cu = ff_hevc_rpi_split_coding_unit_flag_decode(s, lc, cb_depth, x0, y0);
-+ } else {
-+ split_cu = (log2_cb_size > s->ps.sps->log2_min_cb_size);
-+ }
-+ if (s->ps.pps->cu_qp_delta_enabled_flag &&
-+ log2_cb_size >= s->ps.pps->log2_min_cu_qp_delta_size) {
-+ lc->tu.is_cu_qp_delta_coded = 0;
-+ lc->tu.cu_qp_delta = 0;
+ }
+
-+ lc->tu.cu_chroma_qp_offset_wanted = s->sh.cu_chroma_qp_offset_enabled_flag &&
-+ log2_cb_size >= s->ps.pps->log2_min_cu_qp_delta_size;
++ // Qp delta (and offset) need to remain wanted if cb_size < min until
++ // a coded block is found so we still initial state at depth 0 (outside
++ // this fn) and only reset here
++ if (s->ps.pps->cu_qp_delta_enabled_flag &&
++ log2_cb_size >= s->ps.pps->log2_min_cu_qp_delta_size)
++ {
++ lc->tu.is_cu_qp_delta_wanted = 1;
++ lc->tu.cu_qp_delta = 0;
++ }
++ if (s->sh.cu_chroma_qp_offset_enabled_flag &&
++ log2_cb_size >= s->ps.pps->log2_min_cu_qp_delta_size)
++ {
++ lc->tu.cu_chroma_qp_offset_wanted = 1;
++ }
++
+ lc->tu.qp_divmod6[0] = s->ps.pps->qp_bd_x[0];
+ lc->tu.qp_divmod6[1] = s->ps.pps->qp_bd_x[1] + s->sh.slice_cb_qp_offset;
+ lc->tu.qp_divmod6[2] = s->ps.pps->qp_bd_x[2] + s->sh.slice_cr_qp_offset;
@@ -31337,6 +31397,16 @@ index 0000000000..7c98f707d3
+ s->deblock[ctb_addr_rs].tc_offset = s->sh.tc_offset;
+ s->filter_slice_edges[ctb_addr_rs] = s->sh.slice_loop_filter_across_slices_enabled_flag;
+
++ // Zap stashes if navail
++ if ((lc->ctb_avail & AVAIL_U) == 0)
++ zap_cabac_stash(s->cabac_stash_up + (x_ctb >> 3), s->ps.sps->log2_ctb_size - 3);
++ if ((lc->ctb_avail & AVAIL_L) == 0)
++ zap_cabac_stash(s->cabac_stash_left + (y_ctb >> 3), s->ps.sps->log2_ctb_size - 3);
++
++ // Set initial tu states
++ lc->tu.cu_qp_delta = 0;
++ lc->tu.is_cu_qp_delta_wanted = 0;
++ lc->tu.cu_chroma_qp_offset_wanted = 0;
+ more_data = hls_coding_quadtree(s, lc, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
+
+ if (ff_hevc_rpi_cabac_overflow(lc))
@@ -32073,7 +32143,6 @@ index 0000000000..7c98f707d3
+ memset(s->bs_horizontal, 0, s->bs_size);
+ memset(s->bs_vertical, 0, s->bs_size);
+ memset(s->is_pcm, 0, s->ps.sps->pcm_width * s->ps.sps->pcm_height);
-+ memset(s->skip_flag, 0, s->ps.sps->min_cb_height * s->skip_flag_stride);
+ memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address));
+
+ s->is_decoded = 0;
@@ -32885,10 +32954,10 @@ index 0000000000..7c98f707d3
+
diff --git a/libavcodec/rpi_hevcdec.h b/libavcodec/rpi_hevcdec.h
new file mode 100644
-index 0000000000..d2ac038c9b
+index 0000000000..a5ce342ab3
--- /dev/null
+++ b/libavcodec/rpi_hevcdec.h
-@@ -0,0 +1,958 @@
+@@ -0,0 +1,956 @@
+/*
+ * HEVC video decoder
+ *
@@ -33177,20 +33246,17 @@ index 0000000000..d2ac038c9b
+ uint8_t merge_flag;
+} RpiPredictionUnit;
+
-+typedef struct TransformUnit {
++typedef struct HEVCRpiTransformUnit {
+ int8_t cu_qp_delta;
-+ int8_t res_scale_val;
+
+ // Inferred parameters;
+ uint8_t intra_pred_mode;
+ uint8_t intra_pred_mode_c;
+ uint8_t chroma_mode_c;
-+ uint8_t is_cu_qp_delta_coded;
++ uint8_t is_cu_qp_delta_wanted;
+ uint8_t cu_chroma_qp_offset_wanted;
-+ uint8_t cross_pf;
-+
+ const int8_t * qp_divmod6[3];
-+} TransformUnit;
++} HEVCRpiTransformUnit;
+
+typedef struct DBParams {
+ int8_t beta_offset; // -12 to +12
@@ -33235,7 +33301,7 @@ index 0000000000..d2ac038c9b
+} HEVCFrame;
+
+typedef struct HEVCRpiLocalContext {
-+ TransformUnit tu;
++ HEVCRpiTransformUnit tu;
+
+ CABACContext cc;
+
@@ -33305,10 +33371,10 @@ index 0000000000..d2ac038c9b
+ unsigned int boundary_flags;
+
+ /* +7 is for subpixel interpolation, *2 for high bit depths */
-+ DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
++// DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
+ /* The extended size between the new edge emu buffer is abused by SAO */
-+ DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer2)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
-+ DECLARE_ALIGNED(32, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
++// DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer2)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
++// DECLARE_ALIGNED(32, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
+
+} HEVCRpiLocalContext;
+
@@ -33572,6 +33638,11 @@ index 0000000000..d2ac038c9b
+ char offload_recon;
+
+ HEVCRpiJobCtl * jbc;
++ // cabac stash
++ // b0 skip flag
++ // b1+ ct_depth
++ uint8_t * cabac_stash_left;
++ uint8_t * cabac_stash_up;
+
+ // Function pointers
+#if RPI_QPU_EMU_Y || RPI_QPU_EMU_C
@@ -33630,10 +33701,6 @@ index 0000000000..d2ac038c9b
+
+ int32_t *tab_slice_address;
+
-+ // CU
-+ unsigned int skip_flag_stride;
-+ uint8_t *skip_flag;
-+ uint8_t *tab_ct_depth;
+ // PU
+ uint8_t *tab_ipm;
+
@@ -42642,7 +42709,7 @@ index 0000000000..59c0d3959e
+# -Wa,-ahls
diff --git a/pi-util/conf_pi2.sh b/pi-util/conf_pi2.sh
new file mode 100755
-index 0000000000..c8da66514b
+index 0000000000..66c455539d
--- /dev/null
+++ b/pi-util/conf_pi2.sh
@@ -0,0 +1,32 @@
@@ -42653,7 +42720,7 @@ index 0000000000..c8da66514b
+
+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_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib"
-+RPI_DEFINES="-D__VCCOREVER__=0x4000000 -mfpu=neon"
++RPI_DEFINES="-D__VCCOREVER__=0x4000000 -mfpu=neon-vfpv4"
+#RPI_KEEPS="-save-temps=obj"
+RPI_KEEPS=""
+
diff --git a/projects/RPi/patches/kodi/kodi-0100-temp-add-pr13594.patch b/projects/RPi/patches/kodi/kodi-0100-temp-add-pr13594.patch
deleted file mode 100644
index b6e1bc4646..0000000000
--- a/projects/RPi/patches/kodi/kodi-0100-temp-add-pr13594.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 73fc8d7461e50426c20036e97a28af6fc974cbb9 Mon Sep 17 00:00:00 2001
-From: popcornmix
-Date: Mon, 26 Feb 2018 20:58:08 +0000
-Subject: [PATCH] DVDVideoCodec: Initialise VideoPicture fields to zero
-
-After the memset on VideoPicture was removed we are now accessing
-uninitialised class members, e.g. pts and dts
-
-This caused stalls on start of playback and wild values in
-a/v: offset.
-
-Make sure they are initialised.
----
- xbmc/cores/VideoPlayer/DVDFileInfo.cpp | 5 +++--
- xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp | 1 +
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
-index 1350dcf9c2aa..cb7b8bc682d5 100644
---- a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
-+++ b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
-@@ -216,8 +216,8 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath,
- if (pDemuxer->SeekTime(nSeekTo, true))
- {
- CDVDVideoCodec::VCReturn iDecoderState = CDVDVideoCodec::VC_NONE;
-- VideoPicture picture = {};
--
-+ VideoPicture picture;
-+ picture.Reset();
- // num streams * 160 frames, should get a valid frame, if not abort.
- int abort_index = pDemuxer->GetNrOfStreams() * 160;
- do
-@@ -240,6 +240,7 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath,
- iDecoderState = CDVDVideoCodec::VC_NONE;
- while (iDecoderState == CDVDVideoCodec::VC_NONE)
- {
-+ picture.Reset();
- iDecoderState = pVideoCodec->GetPicture(&picture);
- }
-
-diff --git a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
-index b547d17cb27a..b8a7797ba0b6 100644
---- a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
-+++ b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
-@@ -317,6 +317,7 @@ void CVideoPlayerVideo::Process()
- int iDropDirective;
- bool onlyPrioMsgs = false;
-
-+ m_picture.Reset();
- m_videoStats.Start();
- m_droppingStats.Reset();
- m_iDroppedFrames = 0;
diff --git a/projects/WeTek_Core/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch b/projects/WeTek_Core/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch
new file mode 100644
index 0000000000..8457c54288
--- /dev/null
+++ b/projects/WeTek_Core/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch
@@ -0,0 +1,49 @@
+From 2b29cb0830548d4957f1d5ca86640831d224670e Mon Sep 17 00:00:00 2001
+From: Sam Nazarko
+Date: Sun, 9 Apr 2017 17:34:36 +0100
+Subject: [PATCH] Make p8platform mutex mutable without changing libplatform
+
+Signed-off-by: Sam Nazarko
+---
+ src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp | 2 +-
+ src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
+index 60813ed..798454e 100644
+--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
++++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
+@@ -193,7 +193,7 @@ uint16_t CAmlogicCECAdapterCommunication::GetPhysicalAddress(void)
+ }
+
+
+-cec_logical_addresses CAmlogicCECAdapterCommunication::GetLogicalAddresses(void)
++cec_logical_addresses CAmlogicCECAdapterCommunication::GetLogicalAddresses(void) const
+ {
+ CLockObject lock(m_mutex);
+ return m_logicalAddresses;
+diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
+index 0e99cf8..635bb81 100644
+--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
++++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
+@@ -66,7 +66,7 @@ namespace CEC
+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; }
+ bool StartBootloader(void) { return false; }
+ bool SetLogicalAddresses(const cec_logical_addresses &addresses);
+- cec_logical_addresses GetLogicalAddresses(void);
++ cec_logical_addresses GetLogicalAddresses(void) const;
+ bool PingAdapter(void) { return IsInitialised(); }
+ uint16_t GetFirmwareVersion(void);
+ uint32_t GetFirmwareBuildDate(void) { return 0; }
+@@ -98,7 +98,7 @@ namespace CEC
+
+ bool m_bLogicalAddressChanged;
+ cec_logical_addresses m_logicalAddresses;
+- P8PLATFORM::CMutex m_mutex;
++ mutable P8PLATFORM::CMutex m_mutex;
+ int m_fd;
+ };
+ };
+--
+2.7.4
+
diff --git a/projects/WeTek_Play/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch b/projects/WeTek_Play/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch
new file mode 100644
index 0000000000..8457c54288
--- /dev/null
+++ b/projects/WeTek_Play/patches/libcec/libcec-01-amlogic-make-p8platform-mutex-mutable.patch
@@ -0,0 +1,49 @@
+From 2b29cb0830548d4957f1d5ca86640831d224670e Mon Sep 17 00:00:00 2001
+From: Sam Nazarko
+Date: Sun, 9 Apr 2017 17:34:36 +0100
+Subject: [PATCH] Make p8platform mutex mutable without changing libplatform
+
+Signed-off-by: Sam Nazarko
+---
+ src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp | 2 +-
+ src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
+index 60813ed..798454e 100644
+--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
++++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
+@@ -193,7 +193,7 @@ uint16_t CAmlogicCECAdapterCommunication::GetPhysicalAddress(void)
+ }
+
+
+-cec_logical_addresses CAmlogicCECAdapterCommunication::GetLogicalAddresses(void)
++cec_logical_addresses CAmlogicCECAdapterCommunication::GetLogicalAddresses(void) const
+ {
+ CLockObject lock(m_mutex);
+ return m_logicalAddresses;
+diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
+index 0e99cf8..635bb81 100644
+--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
++++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
+@@ -66,7 +66,7 @@ namespace CEC
+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; }
+ bool StartBootloader(void) { return false; }
+ bool SetLogicalAddresses(const cec_logical_addresses &addresses);
+- cec_logical_addresses GetLogicalAddresses(void);
++ cec_logical_addresses GetLogicalAddresses(void) const;
+ bool PingAdapter(void) { return IsInitialised(); }
+ uint16_t GetFirmwareVersion(void);
+ uint32_t GetFirmwareBuildDate(void) { return 0; }
+@@ -98,7 +98,7 @@ namespace CEC
+
+ bool m_bLogicalAddressChanged;
+ cec_logical_addresses m_logicalAddresses;
+- P8PLATFORM::CMutex m_mutex;
++ mutable P8PLATFORM::CMutex m_mutex;
+ int m_fd;
+ };
+ };
+--
+2.7.4
+