This commit is contained in:
parent
f4d138b89a
commit
6f0ee9ff13
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@ -30,6 +30,9 @@ jobs:
|
||||
known_hosts: ${{ secrets.KNOWN_HOSTS }}
|
||||
if_key_exists: replace
|
||||
|
||||
- name: Update apt cache
|
||||
run: apt-get update
|
||||
|
||||
- name: Build Package
|
||||
run: ./main.sh
|
||||
|
||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
obs-studio (29.1.3-100pika1) pikauwu; urgency=low
|
||||
|
||||
Update to 29.1.3
|
||||
|
||||
-- Kevin Henkel <obs.goldace@gmail.com> Sat, 04 Feb 2023 12:48:06 +0100
|
||||
|
||||
obs-studio (29.0.2.git2ac3767-99pika1.lunar) lunar; urgency=low
|
||||
|
||||
Update to lunar
|
||||
|
1
debian/control
vendored
1
debian/control
vendored
@ -6,7 +6,6 @@ Uploaders: Kevin Henkel <obs.goldace@gmail.com>
|
||||
Build-Depends: debhelper (>= 9), cdbs, cmake, git, libx11-dev, libgl1-mesa-dev | libgl-dev, libpulse-dev, libxcb-composite0-dev, libxinerama-dev, libv4l-dev, libudev-dev, libfreetype6-dev, libfontconfig-dev, qt6-base-dev, qt6-base-private-dev, libqt6svg6-dev, libx264-dev, libxcb-xinerama0-dev, libxcb-shm0-dev, libavformat-dev, libavcodec-dev, libavutil-dev, libswscale-dev, libswresample-dev, libavdevice-dev, libavfilter-dev, libfdk-aac-dev, libjack-jackd2-dev, libcurl4-openssl-dev, libspeexdsp-dev, libvlc-dev, libasound2-dev, libluajit-5.1-dev, python3-dev, swig, libmbedtls-dev, pkg-config, libxcb-randr0-dev, libxcb-xfixes0-dev, libx11-xcb-dev, libxcb1-dev, libjansson-dev, libnss3-dev, libxtst-dev, libatspi2.0-dev, libatk-bridge2.0-dev, libatk1.0-dev, libgtk2.0-dev, libgtkglext1-dev, libxss-dev, linux-generic, v4l2loopback-dkms, libwayland-dev, libpci-dev, libdrm-dev, libpipewire-0.3-dev, librist-dev, libsrt-openssl-dev, libva-dev, libuuid1, nlohmann-json3-dev, libwebsocketpp-dev, libasio-dev, libffmpeg-amf-dev
|
||||
Homepage: http://obsproject.org
|
||||
|
||||
|
||||
Package: obs-studio
|
||||
Architecture: amd64
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, qt6-wayland, qt6-qpa-plugins, obs-gstreamer-vaapi-plugin, obs-gamecapture-plugin
|
||||
|
4
debian/rules
vendored
4
debian/rules
vendored
@ -7,5 +7,5 @@ AJA_DIR := $(BASE_DIR)/ntv2
|
||||
%:
|
||||
dh $@
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- -DOBS_VERSION_OVERRIDE="29.0.2" -DBUILD_FOR_PPA=ON -DTWITCH_CLIENTID='unla3~mb`xq9`1dhr?1lhhg`65mah0' -DTWITCH_HASH='2D4A98C454B4B0B6' -DRESTREAM_CLIENTID='ml6b16ec(n9?1#9g?m#>9f0,gnkojhhd;oh6' -DRESTREAM_HASH='2DE8E8C514397EE9' -DYOUTUBE_CLIENTID='153066229607$$;a7mw2ig756r?vc<f{`3tr3|i4gq167?$$lrpw,``jbnerwb{ibltals!fjo' -DYOUTUBE_CLIENTID_HASH='2DA97470255F7240' -DYOUTUBE_SECRET=';kV4NTXP5r>D`7bdLO^>gT8U' -DYOUTUBE_SECRET_HASH='F6215E72FC78C76F' -DENABLE_PIPEWIRE=ON -DENABLE_AJA=OFF -DENABLE_NEW_MPEGTS_OUTPUT=ON -DCEF_ROOT_DIR=$(CEF_DIR) -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
dh_auto_configure -- -DOBS_VERSION_OVERRIDE="29.1.3" -DBUILD_FOR_PPA=ON -DTWITCH_CLIENTID='unla3~mb`xq9`1dhr?1lhhg`65mah0' -DTWITCH_HASH='2D4A98C454B4B0B6' -DRESTREAM_CLIENTID='ml6b16ec(n9?1#9g?m#>9f0,gnkojhhd;oh6' -DRESTREAM_HASH='2DE8E8C514397EE9' -DYOUTUBE_CLIENTID='153066229607$$;a7mw2ig756r?vc<f{`3tr3|i4gq167?$$lrpw,``jbnerwb{ibltals!fjo' -DYOUTUBE_CLIENTID_HASH='2DA97470255F7240' -DYOUTUBE_SECRET=';kV4NTXP5r>D`7bdLO^>gT8U' -DYOUTUBE_SECRET_HASH='F6215E72FC78C76F' -DENABLE_PIPEWIRE=ON -DENABLE_AJA=ON -DENABLE_NEW_MPEGTS_OUTPUT=ON -DCMAKE_PREFIX_PATH=$(AJA_DIR) -DCEF_ROOT_DIR=$(CEF_DIR) -DCMAKE_BUILD_TYPE=Release
|
||||
|
4
main.sh
4
main.sh
@ -2,7 +2,7 @@
|
||||
set -e
|
||||
|
||||
# Clone Upstream
|
||||
git clone --recursive https://github.com/obsproject/obs-studio.git
|
||||
git clone --recursive https://github.com/obsproject/obs-studio.git -b 29.1.3
|
||||
|
||||
cp -rvf ./debian ./obs-studio/
|
||||
cd ./obs-studio
|
||||
@ -18,7 +18,7 @@ sed -i 's|-Werror-implicit-function-declaration||g' CMakeLists.txt
|
||||
sed -i 's| -Werror||g' cmake/Modules/CompilerConfig.cmake
|
||||
sed -i 's| -Wswitch||g' cmake/Modules/CompilerConfig.cmake
|
||||
|
||||
for i in ../patches/*.patch; do patch -Np1 -i $i ;done
|
||||
for i in ../patches/* ; do echo "Applying Patch: $i" && patch -Np1 -i $i || echo "Applying Patch $i Failed!"; done
|
||||
|
||||
# Get build deps brute force
|
||||
apt-get build-dep -y ./
|
||||
|
624
patches/0000-7206.patch
Normal file
624
patches/0000-7206.patch
Normal file
@ -0,0 +1,624 @@
|
||||
diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
index 3eba00932..778d93ffb 100644
|
||||
--- a/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
+++ b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
@@ -108,10 +108,12 @@ if(OS_WINDOWS)
|
||||
jim-nvenc-ver.h
|
||||
obs-ffmpeg.rc)
|
||||
elseif(OS_LINUX OR OS_FREEBSD)
|
||||
+ add_subdirectory(obs-amf-test)
|
||||
+
|
||||
find_package(Libva REQUIRED)
|
||||
find_package(Libpci REQUIRED)
|
||||
|
||||
- target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-vaapi.c vaapi-utils.c vaapi-utils.h)
|
||||
+ target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-vaapi.c vaapi-utils.c vaapi-utils.h texture-amf.cpp)
|
||||
target_link_libraries(obs-ffmpeg PRIVATE Libva::va Libva::drm Libpci::pci)
|
||||
endif()
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/cmake/legacy.cmake b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
index 5540676ea..78b8c30a1 100644
|
||||
--- a/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
+++ b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
@@ -106,9 +106,10 @@ if(OS_WINDOWS)
|
||||
obs-ffmpeg.rc)
|
||||
|
||||
elseif(OS_POSIX AND NOT OS_MACOS)
|
||||
+ add_subdirectory(obs-amf-test)
|
||||
find_package(Libva REQUIRED)
|
||||
find_package(Libpci REQUIRED)
|
||||
- target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-vaapi.c vaapi-utils.c vaapi-utils.h)
|
||||
+ target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-vaapi.c vaapi-utils.c vaapi-utils.h texture-amf.cpp)
|
||||
target_link_libraries(obs-ffmpeg PRIVATE Libva::va Libva::drm LIBPCI::LIBPCI)
|
||||
endif()
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
index e00cef1cf..07cf1e0fc 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
+++ b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
@@ -6,8 +6,14 @@ find_package(AMF 1.4.29 REQUIRED)
|
||||
|
||||
target_include_directories(obs-amf-test PRIVATE ${CMAKE_SOURCE_DIR}/libobs)
|
||||
|
||||
-target_sources(obs-amf-test PRIVATE obs-amf-test.cpp)
|
||||
-target_link_libraries(obs-amf-test d3d11 dxgi dxguid AMF::AMF)
|
||||
+if(OS_WINDOWS)
|
||||
+ target_sources(obs-amf-test PRIVATE obs-amf-test.cpp)
|
||||
+ target_link_libraries(obs-amf-test d3d11 dxgi dxguid AMF::AMF)
|
||||
+elseif(OS_POSIX AND NOT OS_MACOS)
|
||||
+ find_package(Vulkan REQUIRED)
|
||||
+ target_sources(obs-amf-test PRIVATE obs-amf-test-linux.cpp)
|
||||
+ target_link_libraries(obs-amf-test dl Vulkan::Vulkan AMF::AMF)
|
||||
+endif()
|
||||
|
||||
set_target_properties(obs-amf-test PROPERTIES FOLDER "plugins/obs-ffmpeg")
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp b/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp
|
||||
new file mode 100644
|
||||
index 000000000..db437d851
|
||||
--- /dev/null
|
||||
+++ b/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp
|
||||
@@ -0,0 +1,140 @@
|
||||
+#include <AMF/core/Factory.h>
|
||||
+#include <AMF/core/Trace.h>
|
||||
+#include <AMF/components/VideoEncoderVCE.h>
|
||||
+#include <AMF/components/VideoEncoderHEVC.h>
|
||||
+#include <AMF/components/VideoEncoderAV1.h>
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <vulkan/vulkan.hpp>
|
||||
+
|
||||
+#include <string>
|
||||
+#include <map>
|
||||
+
|
||||
+using namespace amf;
|
||||
+
|
||||
+struct adapter_caps {
|
||||
+ bool is_amd = false;
|
||||
+ bool supports_avc = false;
|
||||
+ bool supports_hevc = false;
|
||||
+ bool supports_av1 = false;
|
||||
+};
|
||||
+
|
||||
+static AMFFactory *amf_factory = nullptr;
|
||||
+static std::map<uint32_t, adapter_caps> adapter_info;
|
||||
+
|
||||
+static bool has_encoder(AMFContextPtr &amf_context, const wchar_t *encoder_name)
|
||||
+{
|
||||
+ AMFComponentPtr encoder;
|
||||
+ AMF_RESULT res = amf_factory->CreateComponent(amf_context, encoder_name,
|
||||
+ &encoder);
|
||||
+ return res == AMF_OK;
|
||||
+}
|
||||
+
|
||||
+static bool get_adapter_caps(uint32_t adapter_idx)
|
||||
+{
|
||||
+ if (adapter_idx)
|
||||
+ return false;
|
||||
+
|
||||
+ adapter_caps &caps = adapter_info[adapter_idx];
|
||||
+
|
||||
+ AMF_RESULT res;
|
||||
+ AMFContextPtr amf_context;
|
||||
+ res = amf_factory->CreateContext(&amf_context);
|
||||
+ if (res != AMF_OK)
|
||||
+ return true;
|
||||
+
|
||||
+ AMFContext1 *context1 = NULL;
|
||||
+ res = amf_context->QueryInterface(AMFContext1::IID(),
|
||||
+ (void **)&context1);
|
||||
+ if (res != AMF_OK)
|
||||
+ return false;
|
||||
+ res = context1->InitVulkan(nullptr);
|
||||
+ context1->Release();
|
||||
+ if (res != AMF_OK)
|
||||
+ return false;
|
||||
+
|
||||
+ caps.is_amd = true;
|
||||
+ caps.supports_avc = has_encoder(amf_context, AMFVideoEncoderVCE_AVC);
|
||||
+ caps.supports_hevc = has_encoder(amf_context, AMFVideoEncoder_HEVC);
|
||||
+ caps.supports_av1 = has_encoder(amf_context, AMFVideoEncoder_AV1);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+int main(void)
|
||||
+try {
|
||||
+ AMF_RESULT res;
|
||||
+ VkResult vkres;
|
||||
+
|
||||
+ VkApplicationInfo app_info = {};
|
||||
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
+ app_info.pApplicationName = "obs-amf-test";
|
||||
+ app_info.apiVersion = VK_API_VERSION_1_2;
|
||||
+
|
||||
+ VkInstanceCreateInfo info = {};
|
||||
+ info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
+ info.pApplicationInfo = &app_info;
|
||||
+
|
||||
+ VkInstance instance;
|
||||
+ vkres = vkCreateInstance(&info, nullptr, &instance);
|
||||
+ if (vkres != VK_SUCCESS)
|
||||
+ throw "Failed to initialize Vulkan";
|
||||
+
|
||||
+ uint32_t device_count;
|
||||
+ vkres = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
|
||||
+ if (vkres != VK_SUCCESS || !device_count)
|
||||
+ throw "Failed to enumerate Vulkan devices";
|
||||
+
|
||||
+ VkPhysicalDevice *devices = new VkPhysicalDevice[device_count];
|
||||
+ vkres = vkEnumeratePhysicalDevices(instance, &device_count, devices);
|
||||
+ if (vkres != VK_SUCCESS)
|
||||
+ throw "Failed to enumerate Vulkan devices";
|
||||
+
|
||||
+ VkPhysicalDeviceDriverProperties driver_props = {};
|
||||
+ driver_props.sType =
|
||||
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
|
||||
+ VkPhysicalDeviceProperties2 device_props = {};
|
||||
+ device_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
+ device_props.pNext = &driver_props;
|
||||
+ vkGetPhysicalDeviceProperties2(devices[0], &device_props);
|
||||
+
|
||||
+ if (strcmp(driver_props.driverName, "AMD proprietary driver"))
|
||||
+ throw "Not running AMD proprietary driver";
|
||||
+
|
||||
+ vkDestroyInstance(instance, nullptr);
|
||||
+
|
||||
+ /* --------------------------------------------------------- */
|
||||
+ /* try initializing amf, I guess */
|
||||
+
|
||||
+ void *amf_module = dlopen(AMF_DLL_NAMEA, RTLD_LAZY);
|
||||
+ if (!amf_module)
|
||||
+ throw "Failed to load AMF lib";
|
||||
+
|
||||
+ auto init = (AMFInit_Fn)dlsym(amf_module, AMF_INIT_FUNCTION_NAME);
|
||||
+ if (!init)
|
||||
+ throw "Failed to get init func";
|
||||
+
|
||||
+ res = init(AMF_FULL_VERSION, &amf_factory);
|
||||
+ if (res != AMF_OK)
|
||||
+ throw "AMFInit failed";
|
||||
+
|
||||
+ uint32_t idx = 0;
|
||||
+ while (get_adapter_caps(idx++))
|
||||
+ ;
|
||||
+
|
||||
+ for (auto &[idx, caps] : adapter_info) {
|
||||
+ printf("[%u]\n", idx);
|
||||
+ printf("is_amd=%s\n", caps.is_amd ? "true" : "false");
|
||||
+ printf("supports_avc=%s\n",
|
||||
+ caps.supports_avc ? "true" : "false");
|
||||
+ printf("supports_hevc=%s\n",
|
||||
+ caps.supports_hevc ? "true" : "false");
|
||||
+ printf("supports_av1=%s\n",
|
||||
+ caps.supports_av1 ? "true" : "false");
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+} catch (const char *text) {
|
||||
+ printf("[error]\nstring=%s\n", text);
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
index da0b2c2b4..92421c6f3 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
@@ -360,6 +360,9 @@ static bool hevc_vaapi_supported(void)
|
||||
#ifdef _WIN32
|
||||
extern void jim_nvenc_load(bool h264, bool hevc, bool av1);
|
||||
extern void jim_nvenc_unload(void);
|
||||
+#endif
|
||||
+
|
||||
+#if defined(_WIN32) || defined(__linux__)
|
||||
extern void amf_load(void);
|
||||
extern void amf_unload(void);
|
||||
#endif
|
||||
@@ -434,7 +437,7 @@ bool obs_module_load(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
-#ifdef _WIN32
|
||||
+#if defined(_WIN32) || defined(__linux__)
|
||||
amf_load();
|
||||
#endif
|
||||
|
||||
@@ -475,8 +478,11 @@ void obs_module_unload(void)
|
||||
obs_ffmpeg_unload_logging();
|
||||
#endif
|
||||
|
||||
-#ifdef _WIN32
|
||||
+#if defined(_WIN32) || defined(__linux__)
|
||||
amf_unload();
|
||||
+#endif
|
||||
+
|
||||
+#ifdef _WIN32
|
||||
jim_nvenc_unload();
|
||||
#endif
|
||||
}
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf-opts.hpp b/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
index b1c37d200..d28e3f77e 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
@@ -321,7 +321,7 @@ static void amf_apply_opt(amf_base *enc, obs_option *opt)
|
||||
val = atoi(opt->value);
|
||||
}
|
||||
|
||||
- os_utf8_to_wcs(opt->name, 0, wname, _countof(wname));
|
||||
+ os_utf8_to_wcs(opt->name, 0, wname, amf_countof(wname));
|
||||
if (is_bool) {
|
||||
bool bool_val = (bool)val;
|
||||
set_amf_property(enc, wname, bool_val);
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
index abd1d6f92..871087710 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
+#include <inttypes.h>
|
||||
|
||||
#include <AMF/components/VideoEncoderHEVC.h>
|
||||
#include <AMF/components/VideoEncoderVCE.h>
|
||||
@@ -18,6 +19,7 @@
|
||||
#include <AMF/core/Factory.h>
|
||||
#include <AMF/core/Trace.h>
|
||||
|
||||
+#ifdef _WIN32
|
||||
#include <dxgi.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_1.h>
|
||||
@@ -25,6 +27,8 @@
|
||||
#include <util/windows/device-enum.h>
|
||||
#include <util/windows/HRError.hpp>
|
||||
#include <util/windows/ComPtr.hpp>
|
||||
+#endif
|
||||
+
|
||||
#include <util/platform.h>
|
||||
#include <util/util.hpp>
|
||||
#include <util/pipe.h>
|
||||
@@ -55,8 +59,10 @@ struct amf_error {
|
||||
|
||||
struct handle_tex {
|
||||
uint32_t handle;
|
||||
+#ifdef _WIN32
|
||||
ComPtr<ID3D11Texture2D> tex;
|
||||
ComPtr<IDXGIKeyedMutex> km;
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct adapter_caps {
|
||||
@@ -72,7 +78,7 @@ static std::map<uint32_t, adapter_caps> caps;
|
||||
static bool h264_supported = false;
|
||||
static AMFFactory *amf_factory = nullptr;
|
||||
static AMFTrace *amf_trace = nullptr;
|
||||
-static HMODULE amf_module = nullptr;
|
||||
+static void *amf_module = nullptr;
|
||||
static uint64_t amf_version = 0;
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -120,9 +126,11 @@ struct amf_base {
|
||||
virtual void init() = 0;
|
||||
};
|
||||
|
||||
-using d3dtex_t = ComPtr<ID3D11Texture2D>;
|
||||
using buf_t = std::vector<uint8_t>;
|
||||
|
||||
+#ifdef _WIN32
|
||||
+using d3dtex_t = ComPtr<ID3D11Texture2D>;
|
||||
+
|
||||
struct amf_texencode : amf_base, public AMFSurfaceObserver {
|
||||
volatile bool destroying = false;
|
||||
|
||||
@@ -159,6 +167,7 @@ struct amf_texencode : amf_base, public AMFSurfaceObserver {
|
||||
throw amf_error("InitDX11 failed", res);
|
||||
}
|
||||
};
|
||||
+#endif
|
||||
|
||||
struct amf_fallback : amf_base, public AMFSurfaceObserver {
|
||||
volatile bool destroying = false;
|
||||
@@ -186,9 +195,21 @@ struct amf_fallback : amf_base, public AMFSurfaceObserver {
|
||||
|
||||
void init() override
|
||||
{
|
||||
+#if defined(_WIN32)
|
||||
AMF_RESULT res = amf_context->InitDX11(nullptr, AMF_DX11_1);
|
||||
if (res != AMF_OK)
|
||||
throw amf_error("InitDX11 failed", res);
|
||||
+#elif defined(__linux__)
|
||||
+ AMFContext1 *context1 = NULL;
|
||||
+ AMF_RESULT res = amf_context->QueryInterface(
|
||||
+ AMFContext1::IID(), (void **)&context1);
|
||||
+ if (res != AMF_OK)
|
||||
+ throw amf_error("CreateContext1 failed", res);
|
||||
+ res = context1->InitVulkan(nullptr);
|
||||
+ context1->Release();
|
||||
+ if (res != AMF_OK)
|
||||
+ throw amf_error("InitVulkan failed", res);
|
||||
+#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,13 +251,18 @@ static void set_amf_property(amf_base *enc, const wchar_t *name, const T &value)
|
||||
: (enc->codec == amf_codec_type::HEVC) \
|
||||
? AMF_VIDEO_ENCODER_HEVC_##name \
|
||||
: AMF_VIDEO_ENCODER_AV1_##name)
|
||||
+#define get_opt_name_enum(name) \
|
||||
+ ((enc->codec == amf_codec_type::AVC) ? (int)AMF_VIDEO_ENCODER_##name \
|
||||
+ : (enc->codec == amf_codec_type::HEVC) \
|
||||
+ ? (int)AMF_VIDEO_ENCODER_HEVC_##name \
|
||||
+ : (int)AMF_VIDEO_ENCODER_AV1_##name)
|
||||
#define set_opt(name, value) set_amf_property(enc, get_opt_name(name), value)
|
||||
#define get_opt(name, value) get_amf_property(enc, get_opt_name(name), value)
|
||||
#define set_avc_opt(name, value) set_avc_property(enc, name, value)
|
||||
#define set_hevc_opt(name, value) set_hevc_property(enc, name, value)
|
||||
#define set_av1_opt(name, value) set_av1_property(enc, name, value)
|
||||
#define set_enum_opt(name, value) \
|
||||
- set_amf_property(enc, get_opt_name(name), get_opt_name(name##_##value))
|
||||
+ set_amf_property(enc, get_opt_name(name), get_opt_name_enum(name##_##value))
|
||||
#define set_avc_enum(name, value) \
|
||||
set_avc_property(enc, name, AMF_VIDEO_ENCODER_##name##_##value)
|
||||
#define set_hevc_enum(name, value) \
|
||||
@@ -247,6 +273,7 @@ static void set_amf_property(amf_base *enc, const wchar_t *name, const T &value)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Implementation */
|
||||
|
||||
+#ifdef _WIN32
|
||||
static HMODULE get_lib(const char *lib)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA(lib);
|
||||
@@ -393,6 +420,7 @@ static void get_tex_from_handle(amf_texencode *enc, uint32_t handle,
|
||||
*km_out = km.Detach();
|
||||
*tex_out = tex.Detach();
|
||||
}
|
||||
+#endif
|
||||
|
||||
static constexpr amf_int64 macroblock_size = 16;
|
||||
|
||||
@@ -504,7 +532,7 @@ static void convert_to_encoder_packet(amf_base *enc, AMFDataPtr &data,
|
||||
enc->packet_data = AMFBufferPtr(data);
|
||||
data->GetProperty(L"PTS", &packet->pts);
|
||||
|
||||
- const wchar_t *get_output_type;
|
||||
+ const wchar_t *get_output_type = NULL;
|
||||
switch (enc->codec) {
|
||||
case amf_codec_type::AVC:
|
||||
get_output_type = AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE;
|
||||
@@ -638,6 +666,7 @@ static void amf_encode_base(amf_base *enc, AMFSurface *amf_surf,
|
||||
static bool amf_encode_tex(void *data, uint32_t handle, int64_t pts,
|
||||
uint64_t lock_key, uint64_t *next_key,
|
||||
encoder_packet *packet, bool *received_packet)
|
||||
+#ifdef _WIN32
|
||||
try {
|
||||
amf_texencode *enc = (amf_texencode *)data;
|
||||
ID3D11DeviceContext *context = enc->context;
|
||||
@@ -714,6 +743,18 @@ try {
|
||||
*received_packet = false;
|
||||
return false;
|
||||
}
|
||||
+#else
|
||||
+{
|
||||
+ UNUSED_PARAMETER(data);
|
||||
+ UNUSED_PARAMETER(handle);
|
||||
+ UNUSED_PARAMETER(pts);
|
||||
+ UNUSED_PARAMETER(lock_key);
|
||||
+ UNUSED_PARAMETER(next_key);
|
||||
+ UNUSED_PARAMETER(packet);
|
||||
+ UNUSED_PARAMETER(received_packet);
|
||||
+ return false;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static buf_t alloc_buf(amf_fallback *enc)
|
||||
{
|
||||
@@ -1177,6 +1218,7 @@ static const char *amf_avc_get_name(void *)
|
||||
|
||||
static inline int get_avc_preset(amf_base *enc, const char *preset)
|
||||
{
|
||||
+ UNUSED_PARAMETER(enc);
|
||||
if (astrcmpi(preset, "quality") == 0)
|
||||
return AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY;
|
||||
else if (astrcmpi(preset, "speed") == 0)
|
||||
@@ -1287,7 +1329,7 @@ static bool amf_avc_init(void *data, obs_data_t *settings)
|
||||
set_avc_property(enc, B_PIC_PATTERN, bf);
|
||||
|
||||
} else if (bf != 0) {
|
||||
- warn("B-Frames set to %lld but b-frames are not "
|
||||
+ warn("B-Frames set to %" PRId64 " but b-frames are not "
|
||||
"supported by this device",
|
||||
bf);
|
||||
bf = 0;
|
||||
@@ -1332,12 +1374,12 @@ static bool amf_avc_init(void *data, obs_data_t *settings)
|
||||
|
||||
info("settings:\n"
|
||||
"\trate_control: %s\n"
|
||||
- "\tbitrate: %d\n"
|
||||
- "\tcqp: %d\n"
|
||||
+ "\tbitrate: %" PRId64 "\n"
|
||||
+ "\tcqp: %" PRId64 "\n"
|
||||
"\tkeyint: %d\n"
|
||||
"\tpreset: %s\n"
|
||||
"\tprofile: %s\n"
|
||||
- "\tb-frames: %d\n"
|
||||
+ "\tb-frames: %" PRId64 "\n"
|
||||
"\twidth: %d\n"
|
||||
"\theight: %d\n"
|
||||
"\tparams: %s",
|
||||
@@ -1407,6 +1449,7 @@ static void amf_avc_create_internal(amf_base *enc, obs_data_t *settings)
|
||||
|
||||
static void *amf_avc_create_texencode(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
+#ifdef _WIN32
|
||||
try {
|
||||
check_texture_encode_capability(encoder, amf_codec_type::AVC);
|
||||
|
||||
@@ -1429,6 +1472,12 @@ try {
|
||||
blog(LOG_ERROR, "[texture-amf-h264] %s: %s", __FUNCTION__, err);
|
||||
return obs_encoder_create_rerouted(encoder, "h264_fallback_amf");
|
||||
}
|
||||
+#else
|
||||
+{
|
||||
+ UNUSED_PARAMETER(settings);
|
||||
+ return obs_encoder_create_rerouted(encoder, "h264_fallback_amf");
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static void *amf_avc_create_fallback(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
@@ -1521,6 +1570,7 @@ static const char *amf_hevc_get_name(void *)
|
||||
|
||||
static inline int get_hevc_preset(amf_base *enc, const char *preset)
|
||||
{
|
||||
+ UNUSED_PARAMETER(enc);
|
||||
if (astrcmpi(preset, "balanced") == 0)
|
||||
return AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED;
|
||||
else if (astrcmpi(preset, "speed") == 0)
|
||||
@@ -1640,8 +1690,8 @@ static bool amf_hevc_init(void *data, obs_data_t *settings)
|
||||
|
||||
info("settings:\n"
|
||||
"\trate_control: %s\n"
|
||||
- "\tbitrate: %d\n"
|
||||
- "\tcqp: %d\n"
|
||||
+ "\tbitrate: %" PRId64 "\n"
|
||||
+ "\tcqp: %" PRId64 "\n"
|
||||
"\tkeyint: %d\n"
|
||||
"\tpreset: %s\n"
|
||||
"\tprofile: %s\n"
|
||||
@@ -1758,6 +1808,7 @@ static void amf_hevc_create_internal(amf_base *enc, obs_data_t *settings)
|
||||
|
||||
static void *amf_hevc_create_texencode(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
+#ifdef _WIN32
|
||||
try {
|
||||
check_texture_encode_capability(encoder, amf_codec_type::HEVC);
|
||||
|
||||
@@ -1780,6 +1831,12 @@ try {
|
||||
blog(LOG_ERROR, "[texture-amf-h265] %s: %s", __FUNCTION__, err);
|
||||
return obs_encoder_create_rerouted(encoder, "h265_fallback_amf");
|
||||
}
|
||||
+#else
|
||||
+{
|
||||
+ UNUSED_PARAMETER(settings);
|
||||
+ return obs_encoder_create_rerouted(encoder, "h265_fallback_amf");
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static void *amf_hevc_create_fallback(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
@@ -1868,6 +1925,7 @@ static const char *amf_av1_get_name(void *)
|
||||
|
||||
static inline int get_av1_preset(amf_base *enc, const char *preset)
|
||||
{
|
||||
+ UNUSED_PARAMETER(enc);
|
||||
if (astrcmpi(preset, "highquality") == 0)
|
||||
return AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY;
|
||||
else if (astrcmpi(preset, "quality") == 0)
|
||||
@@ -2001,8 +2059,8 @@ static bool amf_av1_init(void *data, obs_data_t *settings)
|
||||
|
||||
info("settings:\n"
|
||||
"\trate_control: %s\n"
|
||||
- "\tbitrate: %d\n"
|
||||
- "\tcqp: %d\n"
|
||||
+ "\tbitrate: %" PRId64 "\n"
|
||||
+ "\tcqp: %" PRId64 "\n"
|
||||
"\tkeyint: %d\n"
|
||||
"\tpreset: %s\n"
|
||||
"\tprofile: %s\n"
|
||||
@@ -2066,6 +2124,7 @@ static void amf_av1_create_internal(amf_base *enc, obs_data_t *settings)
|
||||
|
||||
static void *amf_av1_create_texencode(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
+#ifdef _WIN32
|
||||
try {
|
||||
check_texture_encode_capability(encoder, amf_codec_type::AV1);
|
||||
|
||||
@@ -2088,6 +2147,12 @@ try {
|
||||
blog(LOG_ERROR, "[texture-amf-av1] %s: %s", __FUNCTION__, err);
|
||||
return obs_encoder_create_rerouted(encoder, "av1_fallback_amf");
|
||||
}
|
||||
+#else
|
||||
+{
|
||||
+ UNUSED_PARAMETER(settings);
|
||||
+ return obs_encoder_create_rerouted(encoder, "av1_fallback_amf");
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static void *amf_av1_create_fallback(obs_data_t *settings,
|
||||
obs_encoder_t *encoder)
|
||||
@@ -2185,9 +2250,16 @@ static bool enum_luids(void *param, uint32_t idx, uint64_t luid)
|
||||
return true;
|
||||
}
|
||||
|
||||
+#ifdef _WIN32
|
||||
+#define OBS_AMF_TEST "obs-amf-test.exe"
|
||||
+#else
|
||||
+#define OBS_AMF_TEST "obs-amf-test"
|
||||
+#endif
|
||||
+
|
||||
extern "C" void amf_load(void)
|
||||
try {
|
||||
AMF_RESULT res;
|
||||
+#ifdef _WIN32
|
||||
HMODULE amf_module_test;
|
||||
|
||||
/* Check if the DLL is present before running the more expensive */
|
||||
@@ -2197,16 +2269,24 @@ try {
|
||||
if (!amf_module_test)
|
||||
throw "No AMF library";
|
||||
FreeLibrary(amf_module_test);
|
||||
+#else
|
||||
+ void *amf_module_test = os_dlopen(AMF_DLL_NAMEA);
|
||||
+ if (!amf_module_test)
|
||||
+ throw "No AMF library";
|
||||
+ os_dlclose(amf_module_test);
|
||||
+#endif
|
||||
|
||||
/* ----------------------------------- */
|
||||
/* Check for supported codecs */
|
||||
|
||||
- BPtr<char> test_exe = os_get_executable_path_ptr("obs-amf-test.exe");
|
||||
+ BPtr<char> test_exe = os_get_executable_path_ptr(OBS_AMF_TEST);
|
||||
std::stringstream cmd;
|
||||
std::string caps_str;
|
||||
|
||||
cmd << test_exe;
|
||||
+#ifdef _WIN32
|
||||
enum_graphics_device_luids(enum_luids, &cmd);
|
||||
+#endif
|
||||
|
||||
os_process_pipe_t *pp = os_process_pipe_create(cmd.str().c_str(), "r");
|
||||
if (!pp)
|
||||
@@ -2266,12 +2346,12 @@ try {
|
||||
/* ----------------------------------- */
|
||||
/* Init AMF */
|
||||
|
||||
- amf_module = LoadLibraryW(AMF_DLL_NAME);
|
||||
+ amf_module = os_dlopen(AMF_DLL_NAMEA);
|
||||
if (!amf_module)
|
||||
throw "AMF library failed to load";
|
||||
|
||||
AMFInit_Fn init =
|
||||
- (AMFInit_Fn)GetProcAddress(amf_module, AMF_INIT_FUNCTION_NAME);
|
||||
+ (AMFInit_Fn)os_dlsym(amf_module, AMF_INIT_FUNCTION_NAME);
|
||||
if (!init)
|
||||
throw "Failed to get AMFInit address";
|
||||
|
||||
@@ -2283,7 +2363,7 @@ try {
|
||||
if (res != AMF_OK)
|
||||
throw amf_error("GetTrace failed", res);
|
||||
|
||||
- AMFQueryVersion_Fn get_ver = (AMFQueryVersion_Fn)GetProcAddress(
|
||||
+ AMFQueryVersion_Fn get_ver = (AMFQueryVersion_Fn)os_dlsym(
|
||||
amf_module, AMF_QUERY_VERSION_FUNCTION_NAME);
|
||||
if (!get_ver)
|
||||
throw "Failed to get AMFQueryVersion address";
|
||||
@@ -2322,7 +2402,7 @@ try {
|
||||
} catch (const amf_error &err) {
|
||||
/* doing an error here because it means at least the library has loaded
|
||||
* successfully, so they probably have AMD at this point */
|
||||
- blog(LOG_ERROR, "%s: %s: 0x%lX", __FUNCTION__, err.str,
|
||||
+ blog(LOG_ERROR, "%s: %s: 0x%uX", __FUNCTION__, err.str,
|
||||
(uint32_t)err.res);
|
||||
}
|
||||
|
@ -2269,3 +2269,4 @@ index 0000000000000..316276df75e54
|
||||
+void pipewire_audio_capture_load(void);
|
||||
+void pipewire_audio_capture_app_load(void);
|
||||
+/* ------------------------------------------------- */
|
||||
|
@ -19,7 +19,7 @@ will be detected on startup and the encoders disabled.
|
||||
create mode 100644 plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
index 3eba00932ab9f..778d93ffba753 100644
|
||||
index 3eba00932..778d93ffb 100644
|
||||
--- a/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
+++ b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
@@ -108,10 +108,12 @@ if(OS_WINDOWS)
|
||||
@ -37,7 +37,7 @@ index 3eba00932ab9f..778d93ffba753 100644
|
||||
endif()
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/cmake/legacy.cmake b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
index 5540676eacba1..78b8c30a10d32 100644
|
||||
index 5540676ea..78b8c30a1 100644
|
||||
--- a/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
+++ b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
@@ -106,9 +106,10 @@ if(OS_WINDOWS)
|
||||
@ -53,7 +53,7 @@ index 5540676eacba1..78b8c30a10d32 100644
|
||||
endif()
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
index e00cef1cf1d8a..07cf1e0fc0e83 100644
|
||||
index e00cef1cf..07cf1e0fc 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
+++ b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
|
||||
@@ -6,8 +6,14 @@ find_package(AMF 1.4.29 REQUIRED)
|
||||
@ -75,7 +75,7 @@ index e00cef1cf1d8a..07cf1e0fc0e83 100644
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp b/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp
|
||||
new file mode 100644
|
||||
index 0000000000000..db437d85164f7
|
||||
index 000000000..db437d851
|
||||
--- /dev/null
|
||||
+++ b/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test-linux.cpp
|
||||
@@ -0,0 +1,140 @@
|
||||
@ -220,7 +220,7 @@ index 0000000000000..db437d85164f7
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
index da0b2c2b46f7a..92421c6f34d9a 100644
|
||||
index da0b2c2b4..92421c6f3 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
@@ -360,6 +360,9 @@ static bool hevc_vaapi_supported(void)
|
||||
@ -256,7 +256,7 @@ index da0b2c2b46f7a..92421c6f34d9a 100644
|
||||
#endif
|
||||
}
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf-opts.hpp b/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
index b1c37d200d8b0..d28e3f77e412f 100644
|
||||
index b1c37d200..d28e3f77e 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf-opts.hpp
|
||||
@@ -321,7 +321,7 @@ static void amf_apply_opt(amf_base *enc, obs_option *opt)
|
||||
@ -269,7 +269,7 @@ index b1c37d200d8b0..d28e3f77e412f 100644
|
||||
bool bool_val = (bool)val;
|
||||
set_amf_property(enc, wname, bool_val);
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
index 88914a027f699..fe651f0e13d82 100644
|
||||
index 88914a027..fe651f0e1 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
@@ -11,6 +11,7 @@
|
||||
@ -642,6 +642,8 @@ index 88914a027f699..fe651f0e13d82 100644
|
||||
(uint32_t)err.res);
|
||||
}
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
||||
From 33d3c849e8e68f0d479548640202d2e8e7041396 Mon Sep 17 00:00:00 2001
|
||||
From: Kurt Kartaltepe <kkartaltepe@gmail.com>
|
||||
@ -658,7 +660,7 @@ frames destined for encoding.
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libobs-opengl/gl-egl-common.c b/libobs-opengl/gl-egl-common.c
|
||||
index f06cd19019b29..e53f5a27555d4 100644
|
||||
index f06cd1901..e53f5a275 100644
|
||||
--- a/libobs-opengl/gl-egl-common.c
|
||||
+++ b/libobs-opengl/gl-egl-common.c
|
||||
@@ -186,7 +186,7 @@ struct gs_texture *gl_egl_create_texture_from_eglimage(
|
||||
@ -670,6 +672,8 @@ index f06cd19019b29..e53f5a27555d4 100644
|
||||
const GLuint gltex = *(GLuint *)gs_texture_get_obj(texture);
|
||||
|
||||
gl_bind_texture(GL_TEXTURE_2D, gltex);
|
||||
--
|
||||
2.40.0
|
||||
|
||||
From de0dd29322328c003944905c89b7da6401159fb5 Mon Sep 17 00:00:00 2001
|
||||
From: Kurt Kartaltepe <kkartaltepe@gmail.com>
|
||||
@ -692,7 +696,7 @@ support encode_texture2
|
||||
10 files changed, 135 insertions(+), 126 deletions(-)
|
||||
|
||||
diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c
|
||||
index 0cdd46d08c58d..8499af20e0475 100644
|
||||
index 0cdd46d08..8499af20e 100644
|
||||
--- a/libobs-opengl/gl-subsystem.c
|
||||
+++ b/libobs-opengl/gl-subsystem.c
|
||||
@@ -1519,6 +1519,18 @@ void gs_swapchain_destroy(gs_swapchain_t *swapchain)
|
||||
@ -715,7 +719,7 @@ index 0cdd46d08c58d..8499af20e0475 100644
|
||||
{
|
||||
/* TODO */
|
||||
diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c
|
||||
index d6eaccccc71fc..8de5bebb6c6ee 100644
|
||||
index d6eaccccc..8de5bebb6 100644
|
||||
--- a/libobs/graphics/graphics-imports.c
|
||||
+++ b/libobs/graphics/graphics-imports.c
|
||||
@@ -195,6 +195,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
||||
@ -737,7 +741,7 @@ index d6eaccccc71fc..8de5bebb6c6ee 100644
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_p010);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
|
||||
diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h
|
||||
index d0ae5b895b39c..268ad36da522d 100644
|
||||
index d0ae5b895..268ad36da 100644
|
||||
--- a/libobs/graphics/graphics-internal.h
|
||||
+++ b/libobs/graphics/graphics-internal.h
|
||||
@@ -273,6 +273,16 @@ struct gs_exports {
|
||||
@ -775,7 +779,7 @@ index d0ae5b895b39c..268ad36da522d 100644
|
||||
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
||||
uint32_t width,
|
||||
diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c
|
||||
index 288fb1db6409c..78a7fc27bccb7 100644
|
||||
index 288fb1db6..78a7fc27b 100644
|
||||
--- a/libobs/graphics/graphics.c
|
||||
+++ b/libobs/graphics/graphics.c
|
||||
@@ -2908,6 +2908,84 @@ void gs_debug_marker_end(void)
|
||||
@ -949,7 +953,7 @@ index 288fb1db6409c..78a7fc27bccb7 100644
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h
|
||||
index 0f62d5b955062..ee17a65fa3357 100644
|
||||
index 0f62d5b95..ee17a65fa 100644
|
||||
--- a/libobs/graphics/graphics.h
|
||||
+++ b/libobs/graphics/graphics.h
|
||||
@@ -857,6 +857,12 @@ EXPORT bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint,
|
||||
@ -980,7 +984,7 @@ index 0f62d5b955062..ee17a65fa3357 100644
|
||||
uint32_t height);
|
||||
EXPORT gs_stagesurf_t *gs_stagesurface_create_p010(uint32_t width,
|
||||
diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h
|
||||
index 6e831af5cf064..c6184bfb595a2 100644
|
||||
index 6e831af5c..c6184bfb5 100644
|
||||
--- a/libobs/obs-encoder.h
|
||||
+++ b/libobs/obs-encoder.h
|
||||
@@ -29,6 +29,9 @@
|
||||
@ -994,7 +998,7 @@ index 6e831af5cf064..c6184bfb595a2 100644
|
||||
#define OBS_ENCODER_CAP_PASS_TEXTURE (1 << 1)
|
||||
#define OBS_ENCODER_CAP_DYN_BITRATE (1 << 2)
|
||||
diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h
|
||||
index 1ea555c3ac7a3..6e975d065417f 100644
|
||||
index 1ea555c3a..6e975d065 100644
|
||||
--- a/libobs/obs-internal.h
|
||||
+++ b/libobs/obs-internal.h
|
||||
@@ -268,9 +268,9 @@ struct obs_core_video_mix {
|
||||
@ -1009,7 +1013,7 @@ index 1ea555c3ac7a3..6e975d065417f 100644
|
||||
gs_texture_t *render_texture;
|
||||
gs_texture_t *output_texture;
|
||||
diff --git a/libobs/obs-video-gpu-encode.c b/libobs/obs-video-gpu-encode.c
|
||||
index 0dfb11df0508b..0d65a6d173e7a 100644
|
||||
index 0dfb11df0..0d65a6d17 100644
|
||||
--- a/libobs/obs-video-gpu-encode.c
|
||||
+++ b/libobs/obs-video-gpu-encode.c
|
||||
@@ -17,8 +17,11 @@
|
||||
@ -1087,7 +1091,7 @@ index 0dfb11df0508b..0d65a6d173e7a 100644
|
||||
|
||||
void stop_gpu_encoding_thread(struct obs_core_video_mix *video)
|
||||
diff --git a/libobs/obs-video.c b/libobs/obs-video.c
|
||||
index 60acaaf6f6536..8918b869d8832 100644
|
||||
index 60acaaf6f..8918b869d 100644
|
||||
--- a/libobs/obs-video.c
|
||||
+++ b/libobs/obs-video.c
|
||||
@@ -427,7 +427,6 @@ stage_output_texture(struct obs_core_video_mix *video, int cur_texture,
|
||||
@ -1201,7 +1205,7 @@ index 60acaaf6f6536..8918b869d8832 100644
|
||||
video->was_active = active;
|
||||
}
|
||||
diff --git a/libobs/obs.c b/libobs/obs.c
|
||||
index 1850ecc7584e5..1e57f25174a34 100644
|
||||
index 1850ecc75..1e57f2517 100644
|
||||
--- a/libobs/obs.c
|
||||
+++ b/libobs/obs.c
|
||||
@@ -179,7 +179,6 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
||||
@ -1247,6 +1251,8 @@ index 1850ecc7584e5..1e57f25174a34 100644
|
||||
}
|
||||
|
||||
gs_texture_destroy(video->output_texture);
|
||||
--
|
||||
2.40.0
|
||||
|
||||
From d9c1a0ce4ae3b7a2465b0f77dd1bc8e8ff74dd21 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <openglfreak@googlemail.com>
|
||||
@ -1264,7 +1270,7 @@ And use it if non-NULL instead of encode_texture.
|
||||
5 files changed, 111 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c
|
||||
index 677b92f7dabd7..83bf911c99484 100644
|
||||
index 677b92f7d..83bf911c9 100644
|
||||
--- a/libobs/obs-encoder.c
|
||||
+++ b/libobs/obs-encoder.c
|
||||
@@ -194,7 +194,7 @@ static void add_connection(struct obs_encoder *encoder)
|
||||
@ -1303,7 +1309,7 @@ index 677b92f7dabd7..83bf911c99484 100644
|
||||
get_callback_idx(const struct obs_encoder *encoder,
|
||||
void (*new_packet)(void *param, struct encoder_packet *packet),
|
||||
diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h
|
||||
index c6184bfb595a2..f33e668bfa5d8 100644
|
||||
index c6184bfb5..f33e668bf 100644
|
||||
--- a/libobs/obs-encoder.h
|
||||
+++ b/libobs/obs-encoder.h
|
||||
@@ -105,6 +105,18 @@ struct encoder_frame {
|
||||
@ -1354,7 +1360,7 @@ index c6184bfb595a2..f33e668bfa5d8 100644
|
||||
|
||||
EXPORT void obs_register_encoder_s(const struct obs_encoder_info *info,
|
||||
diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h
|
||||
index 6e975d065417f..2abfbddee08e8 100644
|
||||
index 6e975d065..2abfbddee 100644
|
||||
--- a/libobs/obs-internal.h
|
||||
+++ b/libobs/obs-internal.h
|
||||
@@ -1259,6 +1259,9 @@ extern struct obs_encoder_info *find_encoder(const char *id);
|
||||
@ -1368,10 +1374,10 @@ index 6e975d065417f..2abfbddee08e8 100644
|
||||
void (*new_packet)(void *param,
|
||||
struct encoder_packet *packet),
|
||||
diff --git a/libobs/obs-module.c b/libobs/obs-module.c
|
||||
index cd7841b6c1960..443c97b2303ac 100644
|
||||
index cd7841b6c..443c97b23 100644
|
||||
--- a/libobs/obs-module.c
|
||||
+++ b/libobs/obs-module.c
|
||||
@@ -679,16 +679,30 @@ lookup_t *obs_module_load_locale(obs_module_t *module,
|
||||
@@ -679,16 +679,30 @@ cleanup:
|
||||
da_push_back(dest, &data); \
|
||||
} while (false)
|
||||
|
||||
@ -1424,7 +1430,7 @@ index cd7841b6c1960..443c97b2303ac 100644
|
||||
CHECK_REQUIRED_VAL_(info, encode, obs_register_encoder);
|
||||
|
||||
diff --git a/libobs/obs-video-gpu-encode.c b/libobs/obs-video-gpu-encode.c
|
||||
index 0d65a6d173e7a..394ded9b68bca 100644
|
||||
index 0d65a6d17..394ded9b6 100644
|
||||
--- a/libobs/obs-video-gpu-encode.c
|
||||
+++ b/libobs/obs-video-gpu-encode.c
|
||||
@@ -78,7 +78,7 @@ static void *gpu_encode_thread(void *data)
|
||||
@ -1474,6 +1480,8 @@ index 0d65a6d173e7a..394ded9b68bca 100644
|
||||
send_off_encoder_packet(encoder, success, received,
|
||||
&pkt);
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
||||
From 0475795cdbf7c7bcb90bb373a10bbd5a7ce17a07 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
@ -1494,7 +1502,7 @@ v8: init AMF context with our Vulkan device
|
||||
3 files changed, 913 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
index 778d93ffba753..97376182fbfae 100644
|
||||
index 778d93ffb..97376182f 100644
|
||||
--- a/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
+++ b/plugins/obs-ffmpeg/CMakeLists.txt
|
||||
@@ -112,9 +112,10 @@ elseif(OS_LINUX OR OS_FREEBSD)
|
||||
@ -1510,7 +1518,7 @@ index 778d93ffba753..97376182fbfae 100644
|
||||
|
||||
set_target_properties_obs(obs-ffmpeg PROPERTIES FOLDER plugins/obs-ffmpeg PREFIX "")
|
||||
diff --git a/plugins/obs-ffmpeg/cmake/legacy.cmake b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
index 78b8c30a10d32..b29eef673586a 100644
|
||||
index 78b8c30a1..b29eef673 100644
|
||||
--- a/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
+++ b/plugins/obs-ffmpeg/cmake/legacy.cmake
|
||||
@@ -109,8 +109,9 @@ elseif(OS_POSIX AND NOT OS_MACOS)
|
||||
@ -1525,7 +1533,7 @@ index 78b8c30a10d32..b29eef673586a 100644
|
||||
|
||||
setup_plugin_target(obs-ffmpeg)
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
index fe651f0e13d82..0f5ee7b9105a8 100644
|
||||
index fe651f0e1..0f5ee7b91 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
@@ -29,6 +29,15 @@
|
||||
@ -2665,3 +2673,6 @@ index fe651f0e13d82..0f5ee7b9105a8 100644
|
||||
amf_encoder_info.create = amf_av1_create_fallback;
|
||||
amf_encoder_info.encode = amf_encode_fallback;
|
||||
amf_encoder_info.get_video_info = av1_video_info_fallback;
|
||||
--
|
||||
2.40.0
|
||||
|
63
patches/0003-8788.patch
Normal file
63
patches/0003-8788.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 8e5fec4c7765b1c43d40f652b46d034340877a31 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Foster <ryan@obsproject.com>
|
||||
Date: Fri, 14 Apr 2023 12:05:59 -0400
|
||||
Subject: [PATCH 1/2] obs-ffmpeg: Use 2x2 tiles in NVENC AV1 for 4K+
|
||||
|
||||
When resolution is 4K or higher, use 2x2 uniform tiles for NVENC AV1.
|
||||
---
|
||||
plugins/obs-ffmpeg/jim-nvenc.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
index 10a7dd18549b9..c1e8bee154770 100644
|
||||
--- a/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
@@ -922,6 +922,17 @@ static bool init_encoder_av1(struct nvenc_data *enc, obs_data_t *settings,
|
||||
if (config->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR)
|
||||
av1_config->enableBitstreamPadding = 1;
|
||||
|
||||
+#define FOUR_K_CX 3840
|
||||
+#define FOUR_K_CY 2160
|
||||
+#define PIXELCOUNT_4K (FOUR_K_CX * FOUR_K_CY)
|
||||
+
|
||||
+ /* If 4K+, set tiles to 2x2 uniform tiles. */
|
||||
+ if ((voi->width * voi->height) >= PIXELCOUNT_4K) {
|
||||
+ av1_config->enableCustomTileConfig = 0;
|
||||
+ av1_config->numTileColumns = 2;
|
||||
+ av1_config->numTileRows = 2;
|
||||
+ }
|
||||
+
|
||||
switch (voi->colorspace) {
|
||||
case VIDEO_CS_601:
|
||||
av1_config->colorPrimaries = 6;
|
||||
|
||||
From 872f0353e68191d69bcc4678a2d195144fdcabeb Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Foster <ryan@obsproject.com>
|
||||
Date: Fri, 14 Apr 2023 12:07:50 -0400
|
||||
Subject: [PATCH 2/2] obs-ffmpeg: Use 2 tiles per frame in AMF AV1 for 4K+
|
||||
|
||||
When resolution is 4K or higher, use 2 tiles per frame in AMF AV1.
|
||||
---
|
||||
plugins/obs-ffmpeg/texture-amf.cpp | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
index 88914a027f699..5979b903385ad 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
@@ -2018,6 +2018,15 @@ static void amf_av1_create_internal(amf_base *enc, obs_data_t *settings)
|
||||
const bool is10bit = enc->amf_format == AMF_SURFACE_P010;
|
||||
const char *preset = obs_data_get_string(settings, "preset");
|
||||
|
||||
+ constexpr uint32_t four_k_cx = 3840;
|
||||
+ constexpr uint32_t four_k_cy = 2160;
|
||||
+ constexpr uint32_t pixelcount_4k = four_k_cx * four_k_cy;
|
||||
+
|
||||
+ /* If 4K+, set tiles per frame to 2. */
|
||||
+ if ((enc->cx * enc->cy) >= pixelcount_4k) {
|
||||
+ set_av1_property(enc, TILES_PER_FRAME, 2);
|
||||
+ }
|
||||
+
|
||||
set_av1_property(enc, FRAMESIZE, AMFConstructSize(enc->cx, enc->cy));
|
||||
set_av1_property(enc, USAGE, AMF_VIDEO_ENCODER_USAGE_TRANSCODING);
|
||||
set_av1_property(enc, ALIGNMENT_MODE,
|
225
patches/0004-8794.patch
Normal file
225
patches/0004-8794.patch
Normal file
@ -0,0 +1,225 @@
|
||||
From 50270b270250a2a95a3d5e2799e40331fb4f83e9 Mon Sep 17 00:00:00 2001
|
||||
From: Bleuzen <12885163+Bleuzen@users.noreply.github.com>
|
||||
Date: Thu, 27 Apr 2023 22:42:49 +0200
|
||||
Subject: [PATCH] obs-ffmpeg: Add NVENC AV1 FFmpeg encoder, part 1
|
||||
|
||||
---
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 100 ++++++++++++++++++++++++--
|
||||
plugins/obs-ffmpeg/obs-ffmpeg.c | 8 ++-
|
||||
2 files changed, 100 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
index 8cd813837c1e8..35c3822453741 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
@@ -35,6 +35,7 @@ struct nvenc_encoder {
|
||||
#ifdef ENABLE_HEVC
|
||||
bool hevc;
|
||||
#endif
|
||||
+ bool av1;
|
||||
int gpu;
|
||||
DARRAY(uint8_t) header;
|
||||
DARRAY(uint8_t) sei;
|
||||
@@ -61,6 +62,13 @@ static const char *hevc_nvenc_getname(void *unused)
|
||||
}
|
||||
#endif
|
||||
|
||||
+#define ENCODER_NAME_AV1 "GPU: NVIDIA NVENC AV1 (FFmpeg)"
|
||||
+static const char *av1_nvenc_getname(void *unused)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(unused);
|
||||
+ return ENCODER_NAME_AV1;
|
||||
+}
|
||||
+
|
||||
static inline bool valid_format(enum video_format format)
|
||||
{
|
||||
switch (format) {
|
||||
@@ -286,7 +294,9 @@ static void on_first_packet(void *data, AVPacket *pkt, struct darray *da)
|
||||
&enc->sei.array, &enc->sei.num);
|
||||
} else
|
||||
#endif
|
||||
- {
|
||||
+ if (enc->av1) {
|
||||
+ // TODO: add obs_extract_av1_headers
|
||||
+ } else {
|
||||
obs_extract_avc_headers(pkt->data, pkt->size,
|
||||
(uint8_t **)&da->array, &da->num,
|
||||
&enc->header.array, &enc->header.num,
|
||||
@@ -305,10 +315,11 @@ static void on_first_packet(void *data, AVPacket *pkt, struct darray *da)
|
||||
}
|
||||
|
||||
static void *nvenc_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
- bool psycho_aq, bool hevc)
|
||||
+ bool psycho_aq, bool hevc, bool av1)
|
||||
{
|
||||
struct nvenc_encoder *enc = bzalloc(sizeof(*enc));
|
||||
|
||||
+ enc->av1 = av1;
|
||||
#ifdef ENABLE_HEVC
|
||||
enc->hevc = hevc;
|
||||
if (hevc) {
|
||||
@@ -321,7 +332,12 @@ static void *nvenc_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
#else
|
||||
UNUSED_PARAMETER(hevc);
|
||||
#endif
|
||||
- {
|
||||
+ if (av1) {
|
||||
+ if (!ffmpeg_video_encoder_init(
|
||||
+ &enc->ffve, enc, encoder, "av1_nvenc", "nvenc_av1",
|
||||
+ ENCODER_NAME_AV1, on_init_error, on_first_packet))
|
||||
+ goto fail;
|
||||
+ } else {
|
||||
if (!ffmpeg_video_encoder_init(&enc->ffve, enc, encoder,
|
||||
"h264_nvenc", "nvenc_h264",
|
||||
ENCODER_NAME_H264, on_init_error,
|
||||
@@ -365,12 +381,14 @@ static void *h264_nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
}
|
||||
|
||||
bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
|
||||
- void *enc = nvenc_create_internal(settings, encoder, psycho_aq, false);
|
||||
+ void *enc = nvenc_create_internal(settings, encoder, psycho_aq, false,
|
||||
+ false);
|
||||
if ((enc == NULL) && psycho_aq) {
|
||||
blog(LOG_WARNING,
|
||||
"[NVENC encoder] nvenc_create_internal failed, "
|
||||
"trying again without Psycho Visual Tuning");
|
||||
- enc = nvenc_create_internal(settings, encoder, false, false);
|
||||
+ enc = nvenc_create_internal(settings, encoder, false, false,
|
||||
+ false);
|
||||
}
|
||||
|
||||
return enc;
|
||||
@@ -404,18 +422,59 @@ static void *hevc_nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
}
|
||||
|
||||
bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
|
||||
- void *enc = nvenc_create_internal(settings, encoder, psycho_aq, true);
|
||||
+ void *enc = nvenc_create_internal(settings, encoder, psycho_aq, true,
|
||||
+ false);
|
||||
if ((enc == NULL) && psycho_aq) {
|
||||
blog(LOG_WARNING,
|
||||
"[NVENC encoder] nvenc_create_internal failed, "
|
||||
"trying again without Psycho Visual Tuning");
|
||||
- enc = nvenc_create_internal(settings, encoder, false, true);
|
||||
+ enc = nvenc_create_internal(settings, encoder, false, true,
|
||||
+ false);
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
#endif
|
||||
|
||||
+static void *av1_nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
+{
|
||||
+ video_t *video = obs_encoder_video(encoder);
|
||||
+ const struct video_output_info *voi = video_output_get_info(video);
|
||||
+ switch (voi->format) {
|
||||
+ case VIDEO_FORMAT_I010:
|
||||
+ case VIDEO_FORMAT_P010: {
|
||||
+ const char *const text =
|
||||
+ obs_module_text("NVENC.10bitUnsupported");
|
||||
+ obs_encoder_set_last_error(encoder, text);
|
||||
+ blog(LOG_ERROR, "[NVENC encoder] %s", text);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ default:
|
||||
+ if (voi->colorspace == VIDEO_CS_2100_PQ ||
|
||||
+ voi->colorspace == VIDEO_CS_2100_HLG) {
|
||||
+ const char *const text =
|
||||
+ obs_module_text("NVENC.8bitUnsupportedHdr");
|
||||
+ obs_encoder_set_last_error(encoder, text);
|
||||
+ blog(LOG_ERROR, "[NVENC encoder] %s", text);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
|
||||
+ void *enc = nvenc_create_internal(settings, encoder, psycho_aq, false,
|
||||
+ true);
|
||||
+ if ((enc == NULL) && psycho_aq) {
|
||||
+ blog(LOG_WARNING,
|
||||
+ "[NVENC encoder] nvenc_create_internal failed, "
|
||||
+ "trying again without Psycho Visual Tuning");
|
||||
+ enc = nvenc_create_internal(settings, encoder, false, false,
|
||||
+ true);
|
||||
+ }
|
||||
+
|
||||
+ return enc;
|
||||
+}
|
||||
+
|
||||
static bool nvenc_encode(void *data, struct encoder_frame *frame,
|
||||
struct encoder_packet *packet, bool *received_packet)
|
||||
{
|
||||
@@ -658,6 +717,12 @@ obs_properties_t *hevc_nvenc_properties_ffmpeg(void *unused)
|
||||
}
|
||||
#endif
|
||||
|
||||
+obs_properties_t *av1_nvenc_properties_ffmpeg(void *unused)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(unused);
|
||||
+ return nvenc_properties_internal(CODEC_AV1, true);
|
||||
+}
|
||||
+
|
||||
static bool nvenc_extra_data(void *data, uint8_t **extra_data, size_t *size)
|
||||
{
|
||||
struct nvenc_encoder *enc = data;
|
||||
@@ -719,3 +784,24 @@ struct obs_encoder_info hevc_nvenc_encoder_info = {
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
+
|
||||
+struct obs_encoder_info av1_nvenc_encoder_info = {
|
||||
+ .id = "ffmpeg_av1_nvenc",
|
||||
+ .type = OBS_ENCODER_VIDEO,
|
||||
+ .codec = "av1",
|
||||
+ .get_name = av1_nvenc_getname,
|
||||
+ .create = av1_nvenc_create,
|
||||
+ .destroy = nvenc_destroy,
|
||||
+ .encode = nvenc_encode,
|
||||
+ .update = nvenc_reconfigure,
|
||||
+ .get_defaults = av1_nvenc_defaults,
|
||||
+ .get_properties = av1_nvenc_properties_ffmpeg,
|
||||
+ .get_extra_data = nvenc_extra_data,
|
||||
+ .get_sei_data = nvenc_sei_data,
|
||||
+ .get_video_info = nvenc_video_info,
|
||||
+#ifdef _WIN32
|
||||
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
|
||||
+#else
|
||||
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE,
|
||||
+#endif
|
||||
+};
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
index da0b2c2b46f7a..e06f8ac7a9192 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
@@ -43,6 +43,7 @@ extern struct obs_encoder_info h264_nvenc_encoder_info;
|
||||
#ifdef ENABLE_HEVC
|
||||
extern struct obs_encoder_info hevc_nvenc_encoder_info;
|
||||
#endif
|
||||
+extern struct obs_encoder_info av1_nvenc_encoder_info;
|
||||
extern struct obs_encoder_info svt_av1_encoder_info;
|
||||
extern struct obs_encoder_info aom_av1_encoder_info;
|
||||
|
||||
@@ -307,8 +308,11 @@ static bool nvenc_supported(bool *out_h264, bool *out_hevc, bool *out_av1)
|
||||
if (success) {
|
||||
void *const lib = os_dlopen("libnvidia-encode.so.1");
|
||||
success = lib != NULL;
|
||||
- if (success)
|
||||
+ if (success) {
|
||||
os_dlclose(lib);
|
||||
+ av1 = nvenc_codec_exists("av1_nvenc",
|
||||
+ "nvenc_av1");
|
||||
+ }
|
||||
}
|
||||
#else
|
||||
void *const lib = os_dlopen("libnvidia-encode.so.1");
|
||||
@@ -432,6 +436,8 @@ bool obs_module_load(void)
|
||||
if (hevc)
|
||||
obs_register_encoder(&hevc_nvenc_encoder_info);
|
||||
#endif
|
||||
+ if (av1)
|
||||
+ obs_register_encoder(&av1_nvenc_encoder_info);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
925
patches/0005-8832.patch
Normal file
925
patches/0005-8832.patch
Normal file
@ -0,0 +1,925 @@
|
||||
From 7f0532049b2fe1f3c1f37f45d540e0a7a18663df Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
Date: Tue, 2 May 2023 13:14:18 +0200
|
||||
Subject: [PATCH 1/2] libobs: Add AV1 parsing functions
|
||||
|
||||
---
|
||||
libobs/CMakeLists.txt | 2 +
|
||||
libobs/cmake/legacy.cmake | 2 +
|
||||
libobs/obs-av1.c | 123 ++++++++++++++++++++++++++++++++++++++
|
||||
libobs/obs-av1.h | 35 +++++++++++
|
||||
4 files changed, 162 insertions(+)
|
||||
create mode 100644 libobs/obs-av1.c
|
||||
create mode 100644 libobs/obs-av1.h
|
||||
|
||||
diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt
|
||||
index d7bb1839c579e..0783feb07ccbb 100644
|
||||
--- a/libobs/CMakeLists.txt
|
||||
+++ b/libobs/CMakeLists.txt
|
||||
@@ -33,6 +33,8 @@ target_sources(
|
||||
obs-audio-controls.c
|
||||
obs-audio-controls.h
|
||||
obs-audio.c
|
||||
+ obs-av1.c
|
||||
+ obs-av1.h
|
||||
obs-avc.c
|
||||
obs-avc.h
|
||||
obs-data.c
|
||||
diff --git a/libobs/cmake/legacy.cmake b/libobs/cmake/legacy.cmake
|
||||
index e8458591c4f2f..a80c5b7c1df24 100644
|
||||
--- a/libobs/cmake/legacy.cmake
|
||||
+++ b/libobs/cmake/legacy.cmake
|
||||
@@ -37,6 +37,8 @@ target_sources(
|
||||
obs-audio.c
|
||||
obs-audio-controls.c
|
||||
obs-audio-controls.h
|
||||
+ obs-av1.c
|
||||
+ obs-av1.h
|
||||
obs-avc.c
|
||||
obs-avc.h
|
||||
obs-data.c
|
||||
diff --git a/libobs/obs-av1.c b/libobs/obs-av1.c
|
||||
new file mode 100644
|
||||
index 0000000000000..a015130537cf2
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-av1.c
|
||||
@@ -0,0 +1,123 @@
|
||||
+// SPDX-FileCopyrightText: 2023 David Rosca <nowrep@gmail.com>
|
||||
+//
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+
|
||||
+#include "obs-av1.h"
|
||||
+
|
||||
+#include "obs.h"
|
||||
+
|
||||
+static inline uint64_t leb128(const uint8_t *buf, size_t size, size_t *len)
|
||||
+{
|
||||
+ uint64_t value = 0;
|
||||
+ uint8_t leb128_byte;
|
||||
+
|
||||
+ *len = 0;
|
||||
+
|
||||
+ for (int i = 0; i < 8; i++) {
|
||||
+ if (size-- < 1)
|
||||
+ break;
|
||||
+ (*len)++;
|
||||
+ leb128_byte = buf[i];
|
||||
+ value |= (leb128_byte & 0x7f) << (i * 7);
|
||||
+ if (!(leb128_byte & 0x80))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return value;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int get_bits(uint8_t val, unsigned int n,
|
||||
+ unsigned int count)
|
||||
+{
|
||||
+ return (val >> (8 - n - count)) & ((1 << (count - 1)) * 2 - 1);
|
||||
+}
|
||||
+
|
||||
+static void parse_obu_header(const uint8_t *buf, size_t size, size_t *obu_start,
|
||||
+ size_t *obu_size, int *obu_type)
|
||||
+{
|
||||
+ int extension_flag, has_size_field;
|
||||
+ size_t size_len = 0;
|
||||
+
|
||||
+ *obu_start = 0;
|
||||
+ *obu_size = 0;
|
||||
+ *obu_type = 0;
|
||||
+
|
||||
+ if (size < 1)
|
||||
+ return;
|
||||
+
|
||||
+ *obu_type = get_bits(*buf, 1, 4);
|
||||
+ extension_flag = get_bits(*buf, 5, 1);
|
||||
+ has_size_field = get_bits(*buf, 6, 1);
|
||||
+
|
||||
+ if (extension_flag)
|
||||
+ (*obu_start)++;
|
||||
+
|
||||
+ (*obu_start)++;
|
||||
+
|
||||
+ if (has_size_field)
|
||||
+ *obu_size = (size_t)leb128(buf + *obu_start, size - *obu_start,
|
||||
+ &size_len);
|
||||
+ else
|
||||
+ *obu_size = size - 1;
|
||||
+
|
||||
+ *obu_start += size_len;
|
||||
+}
|
||||
+
|
||||
+bool obs_av1_keyframe(const uint8_t *data, size_t size)
|
||||
+{
|
||||
+ const uint8_t *start = data, *end = data + size;
|
||||
+
|
||||
+ while (start < end) {
|
||||
+ size_t obu_start, obu_size;
|
||||
+ int obu_type;
|
||||
+ parse_obu_header(start, end - start, &obu_start, &obu_size,
|
||||
+ &obu_type);
|
||||
+
|
||||
+ if (obu_size) {
|
||||
+ if (obu_type == OBS_OBU_FRAME ||
|
||||
+ obu_type == OBS_OBU_FRAME_HEADER) {
|
||||
+ uint8_t val = *(start + obu_start);
|
||||
+ if (!get_bits(val, 0, 1)) // show_existing_frame
|
||||
+ return get_bits(val, 1, 2) ==
|
||||
+ 0; // frame_type
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ start += obu_start + obu_size;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void obs_extract_av1_headers(const uint8_t *packet, size_t size,
|
||||
+ uint8_t **new_packet_data, size_t *new_packet_size,
|
||||
+ uint8_t **header_data, size_t *header_size)
|
||||
+{
|
||||
+ DARRAY(uint8_t) new_packet;
|
||||
+ DARRAY(uint8_t) header;
|
||||
+ const uint8_t *start = packet, *end = packet + size;
|
||||
+
|
||||
+ da_init(new_packet);
|
||||
+ da_init(header);
|
||||
+
|
||||
+ while (start < end) {
|
||||
+ size_t obu_start, obu_size;
|
||||
+ int obu_type;
|
||||
+ parse_obu_header(start, end - start, &obu_start, &obu_size,
|
||||
+ &obu_type);
|
||||
+
|
||||
+ if (obu_type == OBS_OBU_METADATA ||
|
||||
+ obu_type == OBS_OBU_SEQUENCE_HEADER) {
|
||||
+ da_push_back_array(header, start, obu_start + obu_size);
|
||||
+ }
|
||||
+ da_push_back_array(new_packet, start, obu_start + obu_size);
|
||||
+
|
||||
+ start += obu_start + obu_size;
|
||||
+ }
|
||||
+
|
||||
+ *new_packet_data = new_packet.array;
|
||||
+ *new_packet_size = new_packet.num;
|
||||
+ *header_data = header.array;
|
||||
+ *header_size = header.num;
|
||||
+}
|
||||
diff --git a/libobs/obs-av1.h b/libobs/obs-av1.h
|
||||
new file mode 100644
|
||||
index 0000000000000..031299da0a415
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-av1.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+// SPDX-FileCopyrightText: 2023 David Rosca <nowrep@gmail.com>
|
||||
+//
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "util/c99defs.h"
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+enum {
|
||||
+ OBS_OBU_SEQUENCE_HEADER = 1,
|
||||
+ OBS_OBU_TEMPORAL_DELIMITER = 2,
|
||||
+ OBS_OBU_FRAME_HEADER = 3,
|
||||
+ OBS_OBU_TILE_GROUP = 4,
|
||||
+ OBS_OBU_METADATA = 5,
|
||||
+ OBS_OBU_FRAME = 6,
|
||||
+ OBS_OBU_REDUNDANT_FRAME_HEADER = 7,
|
||||
+ OBS_OBU_TILE_LIST = 8,
|
||||
+ OBS_OBU_PADDING = 15,
|
||||
+};
|
||||
+
|
||||
+/* Helpers for parsing AV1 OB units. */
|
||||
+
|
||||
+EXPORT bool obs_av1_keyframe(const uint8_t *data, size_t size);
|
||||
+EXPORT void obs_extract_av1_headers(const uint8_t *packet, size_t size,
|
||||
+ uint8_t **new_packet_data,
|
||||
+ size_t *new_packet_size,
|
||||
+ uint8_t **header_data, size_t *header_size);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
|
||||
From 479e25f59234622e2f868b5f3f295f8c4f702db0 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
Date: Tue, 2 May 2023 13:39:13 +0200
|
||||
Subject: [PATCH 2/2] obs-ffmpeg: Add AV1 support for VA-API
|
||||
|
||||
---
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c | 295 +++++++++++++++++---------
|
||||
plugins/obs-ffmpeg/obs-ffmpeg.c | 19 ++
|
||||
plugins/obs-ffmpeg/vaapi-utils.c | 60 ++++++
|
||||
plugins/obs-ffmpeg/vaapi-utils.h | 4 +
|
||||
4 files changed, 274 insertions(+), 104 deletions(-)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
index c5aa0128a54b9..d6e61f8cb41b9 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <media-io/video-io.h>
|
||||
#include <obs-module.h>
|
||||
#include <obs-avc.h>
|
||||
+#include <obs-av1.h>
|
||||
#ifdef ENABLE_HEVC
|
||||
#include <obs-hevc.h>
|
||||
#endif
|
||||
@@ -53,8 +54,15 @@
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
+enum codec_type {
|
||||
+ CODEC_H264,
|
||||
+ CODEC_HEVC,
|
||||
+ CODEC_AV1,
|
||||
+};
|
||||
+
|
||||
struct vaapi_encoder {
|
||||
obs_encoder_t *encoder;
|
||||
+ enum codec_type codec;
|
||||
|
||||
AVBufferRef *vadevice_ref;
|
||||
AVBufferRef *vaframes_ref;
|
||||
@@ -85,59 +93,48 @@ static const char *h264_vaapi_getname(void *unused)
|
||||
return "FFmpeg VAAPI H.264";
|
||||
}
|
||||
|
||||
-#ifdef ENABLE_HEVC
|
||||
-static const char *hevc_vaapi_getname(void *unused)
|
||||
+static const char *av1_vaapi_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "FFmpeg VAAPI HEVC";
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-static inline bool h264_valid_format(enum video_format format)
|
||||
-{
|
||||
- return format == VIDEO_FORMAT_NV12;
|
||||
+ return "FFmpeg VAAPI AV1";
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
-static inline bool hevc_valid_format(enum video_format format)
|
||||
+static const char *hevc_vaapi_getname(void *unused)
|
||||
{
|
||||
- return (format == VIDEO_FORMAT_NV12) || (format == VIDEO_FORMAT_P010);
|
||||
+ UNUSED_PARAMETER(unused);
|
||||
+ return "FFmpeg VAAPI HEVC";
|
||||
}
|
||||
#endif
|
||||
|
||||
-static void h264_vaapi_video_info(void *data, struct video_scale_info *info)
|
||||
+static inline bool vaapi_valid_format(struct vaapi_encoder *enc,
|
||||
+ enum video_format format)
|
||||
{
|
||||
- struct vaapi_encoder *enc = data;
|
||||
- enum video_format pref_format;
|
||||
-
|
||||
- pref_format = obs_encoder_get_preferred_video_format(enc->encoder);
|
||||
-
|
||||
- if (!h264_valid_format(pref_format)) {
|
||||
- pref_format = h264_valid_format(info->format)
|
||||
- ? info->format
|
||||
- : VIDEO_FORMAT_NV12;
|
||||
+ if (enc->codec == CODEC_H264) {
|
||||
+ return format == VIDEO_FORMAT_NV12;
|
||||
+ } else if (enc->codec == CODEC_HEVC || enc->codec == CODEC_AV1) {
|
||||
+ return (format == VIDEO_FORMAT_NV12) ||
|
||||
+ (format == VIDEO_FORMAT_P010);
|
||||
+ } else {
|
||||
+ return false;
|
||||
}
|
||||
-
|
||||
- info->format = pref_format;
|
||||
}
|
||||
|
||||
-#ifdef ENABLE_HEVC
|
||||
-static void hevc_vaapi_video_info(void *data, struct video_scale_info *info)
|
||||
+static void vaapi_video_info(void *data, struct video_scale_info *info)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
enum video_format pref_format;
|
||||
|
||||
pref_format = obs_encoder_get_preferred_video_format(enc->encoder);
|
||||
|
||||
- if (!hevc_valid_format(pref_format)) {
|
||||
- pref_format = hevc_valid_format(info->format)
|
||||
+ if (!vaapi_valid_format(enc, pref_format)) {
|
||||
+ pref_format = vaapi_valid_format(enc, info->format)
|
||||
? info->format
|
||||
: VIDEO_FORMAT_NV12;
|
||||
}
|
||||
|
||||
info->format = pref_format;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path)
|
||||
{
|
||||
@@ -234,7 +231,7 @@ static const rc_mode_t *get_rc_mode(const char *name)
|
||||
return rc_mode ? rc_mode : RC_MODES;
|
||||
}
|
||||
|
||||
-static bool vaapi_update(void *data, obs_data_t *settings, bool hevc)
|
||||
+static bool vaapi_update(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
|
||||
@@ -249,7 +246,7 @@ static bool vaapi_update(void *data, obs_data_t *settings, bool hevc)
|
||||
int bf = (int)obs_data_get_int(settings, "bf");
|
||||
int qp = rc_mode->qp ? (int)obs_data_get_int(settings, "qp") : 0;
|
||||
|
||||
- av_opt_set_int(enc->context->priv_data, "qp", qp, 0);
|
||||
+ enc->context->global_quality = enc->codec == CODEC_AV1 ? qp * 4 : qp;
|
||||
|
||||
int level = (int)obs_data_get_int(settings, "level");
|
||||
int bitrate = rc_mode->bitrate
|
||||
@@ -279,21 +276,15 @@ static bool vaapi_update(void *data, obs_data_t *settings, bool hevc)
|
||||
info.range = voi->range;
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
- if (hevc) {
|
||||
+ if (enc->codec == CODEC_HEVC) {
|
||||
if ((profile == FF_PROFILE_HEVC_MAIN) &&
|
||||
(info.format == VIDEO_FORMAT_P010)) {
|
||||
warn("Forcing Main10 for P010");
|
||||
profile = FF_PROFILE_HEVC_MAIN_10;
|
||||
}
|
||||
-
|
||||
- hevc_vaapi_video_info(enc, &info);
|
||||
- } else
|
||||
-#else
|
||||
- UNUSED_PARAMETER(hevc);
|
||||
-#endif
|
||||
- {
|
||||
- h264_vaapi_video_info(enc, &info);
|
||||
}
|
||||
+#endif
|
||||
+ vaapi_video_info(enc, &info);
|
||||
|
||||
enc->context->profile = profile;
|
||||
enc->context->max_b_frames = bf;
|
||||
@@ -355,6 +346,17 @@ static bool vaapi_update(void *data, obs_data_t *settings, bool hevc)
|
||||
enc->context->gop_size = 120;
|
||||
}
|
||||
|
||||
+#define FOUR_K_CX 3840
|
||||
+#define FOUR_K_CY 2160
|
||||
+#define PIXELCOUNT_4K (FOUR_K_CX * FOUR_K_CY)
|
||||
+
|
||||
+ /* If 4K+, set tiles to 2x2 uniform tiles. */
|
||||
+ if (enc->codec == CODEC_AV1 &&
|
||||
+ (enc->context->width * enc->context->height) >= PIXELCOUNT_4K) {
|
||||
+ av_opt_set_int(enc->context->priv_data, "tile_cols", 2, 0);
|
||||
+ av_opt_set_int(enc->context->priv_data, "tile_rows", 2, 0);
|
||||
+ }
|
||||
+
|
||||
enc->height = enc->context->height;
|
||||
|
||||
const char *ffmpeg_opts = obs_data_get_string(settings, "ffmpeg_opts");
|
||||
@@ -424,8 +426,20 @@ static void vaapi_destroy(void *data)
|
||||
bfree(enc);
|
||||
}
|
||||
|
||||
+static inline const char *vaapi_encoder_name(enum codec_type codec)
|
||||
+{
|
||||
+ if (codec == CODEC_H264) {
|
||||
+ return "h264_vaapi";
|
||||
+ } else if (codec == CODEC_HEVC) {
|
||||
+ return "hevc_vaapi";
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ return "av1_vaapi";
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void *vaapi_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
- bool hevc)
|
||||
+ enum codec_type codec)
|
||||
{
|
||||
struct vaapi_encoder *enc;
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
@@ -435,8 +449,8 @@ static void *vaapi_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
enc = bzalloc(sizeof(*enc));
|
||||
enc->encoder = encoder;
|
||||
|
||||
- const char *const name = hevc ? "hevc_vaapi" : "h264_vaapi";
|
||||
- enc->vaapi = avcodec_find_encoder_by_name(name);
|
||||
+ enc->codec = codec;
|
||||
+ enc->vaapi = avcodec_find_encoder_by_name(vaapi_encoder_name(codec));
|
||||
|
||||
enc->first_packet = true;
|
||||
|
||||
@@ -453,7 +467,7 @@ static void *vaapi_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (!vaapi_update(enc, settings, hevc))
|
||||
+ if (!vaapi_update(enc, settings))
|
||||
goto fail;
|
||||
|
||||
return enc;
|
||||
@@ -465,13 +479,18 @@ static void *vaapi_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
|
||||
|
||||
static void *h264_vaapi_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
{
|
||||
- return vaapi_create_internal(settings, encoder, false);
|
||||
+ return vaapi_create_internal(settings, encoder, CODEC_H264);
|
||||
+}
|
||||
+
|
||||
+static void *av1_vaapi_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
+{
|
||||
+ return vaapi_create_internal(settings, encoder, CODEC_AV1);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
static void *hevc_vaapi_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
{
|
||||
- return vaapi_create_internal(settings, encoder, true);
|
||||
+ return vaapi_create_internal(settings, encoder, CODEC_HEVC);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -501,9 +520,8 @@ static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame,
|
||||
}
|
||||
}
|
||||
|
||||
-static bool vaapi_encode_internal(void *data, struct encoder_frame *frame,
|
||||
- struct encoder_packet *packet,
|
||||
- bool *received_packet, bool hevc)
|
||||
+static bool vaapi_encode(void *data, struct encoder_frame *frame,
|
||||
+ struct encoder_packet *packet, bool *received_packet)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
AVFrame *hwframe = NULL;
|
||||
@@ -569,7 +587,7 @@ static bool vaapi_encode_internal(void *data, struct encoder_frame *frame,
|
||||
|
||||
enc->first_packet = false;
|
||||
#ifdef ENABLE_HEVC
|
||||
- if (hevc) {
|
||||
+ if (enc->codec == CODEC_HEVC) {
|
||||
obs_extract_hevc_headers(
|
||||
enc->packet->data, enc->packet->size,
|
||||
&new_packet, &size, &enc->header,
|
||||
@@ -579,12 +597,18 @@ static bool vaapi_encode_internal(void *data, struct encoder_frame *frame,
|
||||
#else
|
||||
UNUSED_PARAMETER(hevc);
|
||||
#endif
|
||||
- {
|
||||
+ if (enc->codec == CODEC_H264) {
|
||||
obs_extract_avc_headers(
|
||||
enc->packet->data, enc->packet->size,
|
||||
&new_packet, &size, &enc->header,
|
||||
&enc->header_size, &enc->sei,
|
||||
&enc->sei_size);
|
||||
+ } else if (enc->codec == CODEC_AV1) {
|
||||
+ obs_extract_av1_headers(enc->packet->data,
|
||||
+ enc->packet->size,
|
||||
+ &new_packet, &size,
|
||||
+ &enc->header,
|
||||
+ &enc->header_size);
|
||||
}
|
||||
|
||||
da_copy_array(enc->buffer, new_packet, size);
|
||||
@@ -600,14 +624,17 @@ static bool vaapi_encode_internal(void *data, struct encoder_frame *frame,
|
||||
packet->size = enc->buffer.num;
|
||||
packet->type = OBS_ENCODER_VIDEO;
|
||||
#ifdef ENABLE_HEVC
|
||||
- if (hevc) {
|
||||
+ if (enc->codec == CODEC_HEVC) {
|
||||
packet->keyframe =
|
||||
obs_hevc_keyframe(packet->data, packet->size);
|
||||
} else
|
||||
#endif
|
||||
- {
|
||||
+ if (enc->codec == CODEC_H264) {
|
||||
packet->keyframe =
|
||||
obs_avc_keyframe(packet->data, packet->size);
|
||||
+ } else if (enc->codec == CODEC_AV1) {
|
||||
+ packet->keyframe =
|
||||
+ obs_av1_keyframe(packet->data, packet->size);
|
||||
}
|
||||
*received_packet = true;
|
||||
} else {
|
||||
@@ -623,54 +650,65 @@ static bool vaapi_encode_internal(void *data, struct encoder_frame *frame,
|
||||
return false;
|
||||
}
|
||||
|
||||
-static bool h264_vaapi_encode(void *data, struct encoder_frame *frame,
|
||||
- struct encoder_packet *packet,
|
||||
- bool *received_packet)
|
||||
+static void set_visible(obs_properties_t *ppts, const char *name, bool visible)
|
||||
{
|
||||
- return vaapi_encode_internal(data, frame, packet, received_packet,
|
||||
- false);
|
||||
+ obs_property_t *p = obs_properties_get(ppts, name);
|
||||
+ obs_property_set_visible(p, visible);
|
||||
}
|
||||
|
||||
-#ifdef ENABLE_HEVC
|
||||
-static bool hevc_vaapi_encode(void *data, struct encoder_frame *frame,
|
||||
- struct encoder_packet *packet,
|
||||
- bool *received_packet)
|
||||
+static inline VAProfile vaapi_profile(enum codec_type codec)
|
||||
{
|
||||
- return vaapi_encode_internal(data, frame, packet, received_packet,
|
||||
- true);
|
||||
-}
|
||||
+ if (codec == CODEC_H264) {
|
||||
+ return VAProfileH264ConstrainedBaseline;
|
||||
+#if VA_CHECK_VERSION(1, 14, 0)
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ return VAProfileAV1Profile0;
|
||||
#endif
|
||||
-
|
||||
-static void set_visible(obs_properties_t *ppts, const char *name, bool visible)
|
||||
-{
|
||||
- obs_property_t *p = obs_properties_get(ppts, name);
|
||||
- obs_property_set_visible(p, visible);
|
||||
+#if ENABLE_HEVC
|
||||
+ } else if (codec == CODEC_HEVC) {
|
||||
+ return VAProfileHEVCMain;
|
||||
+#endif
|
||||
+ }
|
||||
+ return VAProfileNone;
|
||||
}
|
||||
|
||||
-static void vaapi_defaults_internal(obs_data_t *settings, bool hevc)
|
||||
+static inline const char *vaapi_default_device(enum codec_type codec)
|
||||
{
|
||||
-#ifdef ENABLE_HEVC
|
||||
- const char *device = hevc ? vaapi_get_hevc_default_device()
|
||||
- : vaapi_get_h264_default_device();
|
||||
-#else
|
||||
- const char *const device = vaapi_get_h264_default_device();
|
||||
+ if (codec == CODEC_H264) {
|
||||
+ return vaapi_get_h264_default_device();
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ return vaapi_get_av1_default_device();
|
||||
+#if ENABLE_HEVC
|
||||
+ } else if (codec == CODEC_HEVC) {
|
||||
+ return vaapi_get_hevc_default_device();
|
||||
#endif
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
|
||||
+static void vaapi_defaults_internal(obs_data_t *settings, enum codec_type codec)
|
||||
+{
|
||||
+ const char *const device = vaapi_default_device(codec);
|
||||
obs_data_set_default_string(settings, "vaapi_device", device);
|
||||
#ifdef ENABLE_HEVC
|
||||
- if (hevc) {
|
||||
+ if (codec == CODEC_HEVC) {
|
||||
obs_data_set_default_int(settings, "profile",
|
||||
FF_PROFILE_HEVC_MAIN);
|
||||
+ obs_data_set_default_int(settings, "level", 120);
|
||||
|
||||
} else
|
||||
#else
|
||||
UNUSED_PARAMETER(hevc);
|
||||
#endif
|
||||
- {
|
||||
+ if (codec == CODEC_H264) {
|
||||
obs_data_set_default_int(settings, "profile",
|
||||
FF_PROFILE_H264_CONSTRAINED_BASELINE);
|
||||
+ obs_data_set_default_int(settings, "level", 40);
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ obs_data_set_default_int(settings, "profile",
|
||||
+ FF_PROFILE_AV1_MAIN);
|
||||
+ obs_data_set_default_int(settings, "level", 8);
|
||||
}
|
||||
- obs_data_set_default_int(settings, "level", 40);
|
||||
obs_data_set_default_int(settings, "bitrate", 2500);
|
||||
obs_data_set_default_int(settings, "keyint_sec", 0);
|
||||
obs_data_set_default_int(settings, "bf", 0);
|
||||
@@ -683,12 +721,7 @@ static void vaapi_defaults_internal(obs_data_t *settings, bool hevc)
|
||||
if (!va_dpy)
|
||||
return;
|
||||
|
||||
-#ifdef ENABLE_HEVC
|
||||
- const VAProfile profile = hevc ? VAProfileHEVCMain
|
||||
- : VAProfileH264ConstrainedBaseline;
|
||||
-#else
|
||||
- const VAProfile profile = VAProfileH264ConstrainedBaseline;
|
||||
-#endif
|
||||
+ const VAProfile profile = vaapi_profile(codec);
|
||||
if (vaapi_device_rc_supported(profile, va_dpy, VA_RC_CBR, device))
|
||||
obs_data_set_default_string(settings, "rate_control", "CBR");
|
||||
else if (vaapi_device_rc_supported(profile, va_dpy, VA_RC_VBR, device))
|
||||
@@ -701,12 +734,17 @@ static void vaapi_defaults_internal(obs_data_t *settings, bool hevc)
|
||||
|
||||
static void h264_vaapi_defaults(obs_data_t *settings)
|
||||
{
|
||||
- vaapi_defaults_internal(settings, false);
|
||||
+ vaapi_defaults_internal(settings, CODEC_H264);
|
||||
+}
|
||||
+
|
||||
+static void av1_vaapi_defaults(obs_data_t *settings)
|
||||
+{
|
||||
+ vaapi_defaults_internal(settings, CODEC_AV1);
|
||||
}
|
||||
|
||||
static void hevc_vaapi_defaults(obs_data_t *settings)
|
||||
{
|
||||
- vaapi_defaults_internal(settings, true);
|
||||
+ vaapi_defaults_internal(settings, CODEC_HEVC);
|
||||
}
|
||||
|
||||
static bool vaapi_device_modified(obs_properties_t *ppts, obs_property_t *p,
|
||||
@@ -742,6 +780,13 @@ static bool vaapi_device_modified(obs_properties_t *ppts, obs_property_t *p,
|
||||
goto fail;
|
||||
profile = VAProfileH264High;
|
||||
break;
|
||||
+#if VA_CHECK_VERSION(1, 14, 0)
|
||||
+ case FF_PROFILE_AV1_MAIN:
|
||||
+ if (!vaapi_display_av1_supported(va_dpy, device))
|
||||
+ goto fail;
|
||||
+ profile = VAProfileAV1Profile0;
|
||||
+ break;
|
||||
+#endif
|
||||
#ifdef ENABLE_HEVC
|
||||
case FF_PROFILE_HEVC_MAIN:
|
||||
if (!vaapi_display_hevc_supported(va_dpy, device))
|
||||
@@ -813,7 +858,7 @@ static bool get_device_name_from_pci(struct pci_access *pacc, char *pci_slot,
|
||||
return false;
|
||||
}
|
||||
|
||||
-static obs_properties_t *vaapi_properties_internal(bool hevc)
|
||||
+static obs_properties_t *vaapi_properties_internal(enum codec_type codec)
|
||||
{
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
obs_property_t *list;
|
||||
@@ -904,16 +949,18 @@ static obs_properties_t *vaapi_properties_internal(bool hevc)
|
||||
obs_module_text("Profile"),
|
||||
OBS_COMBO_TYPE_LIST,
|
||||
OBS_COMBO_FORMAT_INT);
|
||||
- if (hevc) {
|
||||
+ if (codec == CODEC_HEVC) {
|
||||
obs_property_list_add_int(list, "Main", FF_PROFILE_HEVC_MAIN);
|
||||
obs_property_list_add_int(list, "Main10",
|
||||
FF_PROFILE_HEVC_MAIN_10);
|
||||
- } else {
|
||||
+ } else if (codec == CODEC_H264) {
|
||||
obs_property_list_add_int(list,
|
||||
"Constrained Baseline (default)",
|
||||
FF_PROFILE_H264_CONSTRAINED_BASELINE);
|
||||
obs_property_list_add_int(list, "Main", FF_PROFILE_H264_MAIN);
|
||||
obs_property_list_add_int(list, "High", FF_PROFILE_H264_HIGH);
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ obs_property_list_add_int(list, "Main", FF_PROFILE_AV1_MAIN);
|
||||
}
|
||||
|
||||
obs_property_set_modified_callback(list, vaapi_device_modified);
|
||||
@@ -922,15 +969,34 @@ static obs_properties_t *vaapi_properties_internal(bool hevc)
|
||||
OBS_COMBO_TYPE_LIST,
|
||||
OBS_COMBO_FORMAT_INT);
|
||||
obs_property_list_add_int(list, "Auto", FF_LEVEL_UNKNOWN);
|
||||
- obs_property_list_add_int(list, "3.0", 30);
|
||||
- obs_property_list_add_int(list, "3.1", 31);
|
||||
- obs_property_list_add_int(list, "4.0 (default) (Compatibility mode)",
|
||||
- 40);
|
||||
- obs_property_list_add_int(list, "4.1", 41);
|
||||
- obs_property_list_add_int(list, "4.2", 42);
|
||||
- obs_property_list_add_int(list, "5.0", 50);
|
||||
- obs_property_list_add_int(list, "5.1", 51);
|
||||
- obs_property_list_add_int(list, "5.2", 52);
|
||||
+ if (codec == CODEC_H264) {
|
||||
+ obs_property_list_add_int(list, "3.0", 30);
|
||||
+ obs_property_list_add_int(list, "3.1", 31);
|
||||
+ obs_property_list_add_int(
|
||||
+ list, "4.0 (default) (Compatibility mode)", 40);
|
||||
+ obs_property_list_add_int(list, "4.1", 41);
|
||||
+ obs_property_list_add_int(list, "4.2", 42);
|
||||
+ obs_property_list_add_int(list, "5.0", 50);
|
||||
+ obs_property_list_add_int(list, "5.1", 51);
|
||||
+ obs_property_list_add_int(list, "5.2", 52);
|
||||
+ } else if (codec == CODEC_HEVC) {
|
||||
+ obs_property_list_add_int(list, "3.0", 90);
|
||||
+ obs_property_list_add_int(list, "3.1", 93);
|
||||
+ obs_property_list_add_int(list, "4.0 (default)", 120);
|
||||
+ obs_property_list_add_int(list, "4.1", 123);
|
||||
+ obs_property_list_add_int(list, "5.0", 150);
|
||||
+ obs_property_list_add_int(list, "5.1", 153);
|
||||
+ obs_property_list_add_int(list, "5.2", 156);
|
||||
+ } else if (codec == CODEC_AV1) {
|
||||
+ obs_property_list_add_int(list, "3.0", 4);
|
||||
+ obs_property_list_add_int(list, "3.1", 5);
|
||||
+ obs_property_list_add_int(list, "4.0 (default)", 8);
|
||||
+ obs_property_list_add_int(list, "4.1", 9);
|
||||
+ obs_property_list_add_int(list, "5.0", 12);
|
||||
+ obs_property_list_add_int(list, "5.1", 13);
|
||||
+ obs_property_list_add_int(list, "5.2", 14);
|
||||
+ obs_property_list_add_int(list, "5.3", 15);
|
||||
+ }
|
||||
|
||||
list = obs_properties_add_list(props, "rate_control",
|
||||
obs_module_text("RateControl"),
|
||||
@@ -965,14 +1031,20 @@ static obs_properties_t *vaapi_properties_internal(bool hevc)
|
||||
static obs_properties_t *h264_vaapi_properties(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return vaapi_properties_internal(false);
|
||||
+ return vaapi_properties_internal(CODEC_H264);
|
||||
+}
|
||||
+
|
||||
+static obs_properties_t *av1_vaapi_properties(void *unused)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(unused);
|
||||
+ return vaapi_properties_internal(CODEC_AV1);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
static obs_properties_t *hevc_vaapi_properties(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return vaapi_properties_internal(true);
|
||||
+ return vaapi_properties_internal(CODEC_HEVC);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1001,12 +1073,27 @@ struct obs_encoder_info h264_vaapi_encoder_info = {
|
||||
.get_name = h264_vaapi_getname,
|
||||
.create = h264_vaapi_create,
|
||||
.destroy = vaapi_destroy,
|
||||
- .encode = h264_vaapi_encode,
|
||||
+ .encode = vaapi_encode,
|
||||
.get_defaults = h264_vaapi_defaults,
|
||||
.get_properties = h264_vaapi_properties,
|
||||
.get_extra_data = vaapi_extra_data,
|
||||
.get_sei_data = vaapi_sei_data,
|
||||
- .get_video_info = h264_vaapi_video_info,
|
||||
+ .get_video_info = vaapi_video_info,
|
||||
+};
|
||||
+
|
||||
+struct obs_encoder_info av1_vaapi_encoder_info = {
|
||||
+ .id = "av1_ffmpeg_vaapi",
|
||||
+ .type = OBS_ENCODER_VIDEO,
|
||||
+ .codec = "av1",
|
||||
+ .get_name = av1_vaapi_getname,
|
||||
+ .create = av1_vaapi_create,
|
||||
+ .destroy = vaapi_destroy,
|
||||
+ .encode = vaapi_encode,
|
||||
+ .get_defaults = av1_vaapi_defaults,
|
||||
+ .get_properties = av1_vaapi_properties,
|
||||
+ .get_extra_data = vaapi_extra_data,
|
||||
+ .get_sei_data = vaapi_sei_data,
|
||||
+ .get_video_info = vaapi_video_info,
|
||||
};
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
@@ -1017,12 +1104,12 @@ struct obs_encoder_info hevc_vaapi_encoder_info = {
|
||||
.get_name = hevc_vaapi_getname,
|
||||
.create = hevc_vaapi_create,
|
||||
.destroy = vaapi_destroy,
|
||||
- .encode = hevc_vaapi_encode,
|
||||
+ .encode = vaapi_encode,
|
||||
.get_defaults = hevc_vaapi_defaults,
|
||||
.get_properties = hevc_vaapi_properties,
|
||||
.get_extra_data = vaapi_extra_data,
|
||||
.get_sei_data = vaapi_sei_data,
|
||||
- .get_video_info = hevc_vaapi_video_info,
|
||||
+ .get_video_info = vaapi_video_info,
|
||||
};
|
||||
#endif
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
index c62d0d65fff7b..bd7e1cafea3d1 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg.c
|
||||
@@ -48,6 +48,7 @@ extern struct obs_encoder_info aom_av1_encoder_info;
|
||||
|
||||
#ifdef LIBAVUTIL_VAAPI_AVAILABLE
|
||||
extern struct obs_encoder_info h264_vaapi_encoder_info;
|
||||
+extern struct obs_encoder_info av1_vaapi_encoder_info;
|
||||
#ifdef ENABLE_HEVC
|
||||
extern struct obs_encoder_info hevc_vaapi_encoder_info;
|
||||
#endif
|
||||
@@ -342,6 +343,17 @@ static bool h264_vaapi_supported(void)
|
||||
* that support H264. */
|
||||
return vaapi_get_h264_default_device() != NULL;
|
||||
}
|
||||
+static bool av1_vaapi_supported(void)
|
||||
+{
|
||||
+ const AVCodec *vaenc = avcodec_find_encoder_by_name("av1_vaapi");
|
||||
+
|
||||
+ if (!vaenc)
|
||||
+ return false;
|
||||
+
|
||||
+ /* NOTE: If default device is NULL, it means there is no device
|
||||
+ * that support AV1. */
|
||||
+ return vaapi_get_av1_default_device() != NULL;
|
||||
+}
|
||||
#ifdef ENABLE_HEVC
|
||||
static bool hevc_vaapi_supported(void)
|
||||
{
|
||||
@@ -452,6 +464,13 @@ bool obs_module_load(void)
|
||||
blog(LOG_INFO, "FFmpeg VAAPI H264 encoding not supported");
|
||||
}
|
||||
|
||||
+ if (av1_vaapi_supported()) {
|
||||
+ blog(LOG_INFO, "FFmpeg VAAPI AV1 encoding supported");
|
||||
+ obs_register_encoder(&av1_vaapi_encoder_info);
|
||||
+ } else {
|
||||
+ blog(LOG_INFO, "FFmpeg VAAPI AV1 encoding not supported");
|
||||
+ }
|
||||
+
|
||||
#ifdef ENABLE_HEVC
|
||||
if (hevc_vaapi_supported()) {
|
||||
blog(LOG_INFO, "FFmpeg VAAPI HEVC encoding supported");
|
||||
diff --git a/plugins/obs-ffmpeg/vaapi-utils.c b/plugins/obs-ffmpeg/vaapi-utils.c
|
||||
index 4198ee59c6ab4..ad527ec525e0e 100644
|
||||
--- a/plugins/obs-ffmpeg/vaapi-utils.c
|
||||
+++ b/plugins/obs-ffmpeg/vaapi-utils.c
|
||||
@@ -261,6 +261,66 @@ const char *vaapi_get_h264_default_device()
|
||||
return default_h264_device;
|
||||
}
|
||||
|
||||
+bool vaapi_display_av1_supported(VADisplay dpy, const char *device_path)
|
||||
+{
|
||||
+ bool ret = false;
|
||||
+
|
||||
+#if VA_CHECK_VERSION(1, 14, 0)
|
||||
+ CHECK_PROFILE(ret, VAProfileAV1Profile0, dpy, device_path);
|
||||
+
|
||||
+ if (!ret) {
|
||||
+ CHECK_PROFILE_LP(ret, VAProfileAV1Profile0, dpy, device_path);
|
||||
+ }
|
||||
+#else
|
||||
+ UNUSED_PARAMETER(dpy);
|
||||
+ UNUSED_PARAMETER(device_path);
|
||||
+#endif
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+bool vaapi_device_av1_supported(const char *device_path)
|
||||
+{
|
||||
+ bool ret = false;
|
||||
+ VADisplay va_dpy;
|
||||
+
|
||||
+ int drm_fd = -1;
|
||||
+
|
||||
+ va_dpy = vaapi_open_device(&drm_fd, device_path,
|
||||
+ "vaapi_device_av1_supported");
|
||||
+ if (!va_dpy)
|
||||
+ return false;
|
||||
+
|
||||
+ ret = vaapi_display_av1_supported(va_dpy, device_path);
|
||||
+
|
||||
+ vaapi_close_device(&drm_fd, va_dpy);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+const char *vaapi_get_av1_default_device()
|
||||
+{
|
||||
+ static const char *default_av1_device = NULL;
|
||||
+
|
||||
+ if (!default_av1_device) {
|
||||
+ bool ret = false;
|
||||
+ char path[32] = "/dev/dri/renderD1";
|
||||
+ for (int i = 28;; i++) {
|
||||
+ sprintf(path, "/dev/dri/renderD1%d", i);
|
||||
+ if (access(path, F_OK) != 0)
|
||||
+ break;
|
||||
+
|
||||
+ ret = vaapi_device_av1_supported(path);
|
||||
+ if (ret) {
|
||||
+ default_av1_device = strdup(path);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return default_av1_device;
|
||||
+}
|
||||
+
|
||||
#ifdef ENABLE_HEVC
|
||||
|
||||
bool vaapi_display_hevc_supported(VADisplay dpy, const char *device_path)
|
||||
diff --git a/plugins/obs-ffmpeg/vaapi-utils.h b/plugins/obs-ffmpeg/vaapi-utils.h
|
||||
index b90b2394710b3..2d7ee29dc9ab9 100644
|
||||
--- a/plugins/obs-ffmpeg/vaapi-utils.h
|
||||
+++ b/plugins/obs-ffmpeg/vaapi-utils.h
|
||||
@@ -19,6 +19,10 @@ bool vaapi_display_h264_supported(VADisplay dpy, const char *device_path);
|
||||
bool vaapi_device_h264_supported(const char *device_path);
|
||||
const char *vaapi_get_h264_default_device(void);
|
||||
|
||||
+bool vaapi_display_av1_supported(VADisplay dpy, const char *device_path);
|
||||
+bool vaapi_device_av1_supported(const char *device_path);
|
||||
+const char *vaapi_get_av1_default_device(void);
|
||||
+
|
||||
#ifdef ENABLE_HEVC
|
||||
bool vaapi_display_hevc_supported(VADisplay dpy, const char *device_path);
|
||||
bool vaapi_device_hevc_supported(const char *device_path);
|
151
patches/0006-encoder-rename.patch
Normal file
151
patches/0006-encoder-rename.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 11dae1dd5a7600534807e254dfa30c9613779dd7 Mon Sep 17 00:00:00 2001
|
||||
From: GloriousEggroll <gloriouseggroll@gmail.com>
|
||||
Date: Sat, 29 Apr 2023 14:46:16 -0600
|
||||
Subject: [PATCH] encoder rename
|
||||
|
||||
---
|
||||
plugins/obs-ffmpeg/jim-nvenc.c | 4 ++--
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-av1.c | 4 ++--
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 4 ++--
|
||||
plugins/obs-ffmpeg/texture-amf.cpp | 6 +++---
|
||||
plugins/obs-x264/obs-x264.c | 2 +-
|
||||
5 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
index 10a7dd1..c912205 100644
|
||||
--- a/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
@@ -227,14 +227,14 @@ static void nv_texture_free(struct nvenc_data *enc, struct nv_texture *nvtex)
|
||||
static const char *h264_nvenc_get_name(void *type_data)
|
||||
{
|
||||
UNUSED_PARAMETER(type_data);
|
||||
- return "NVIDIA NVENC H.264";
|
||||
+ return "GPU: NVIDIA NVENC H.264 (FFmpeg)";
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
static const char *hevc_nvenc_get_name(void *type_data)
|
||||
{
|
||||
UNUSED_PARAMETER(type_data);
|
||||
- return "NVIDIA NVENC HEVC";
|
||||
+ return "GPU: NVIDIA NVENC H.265/HEVC (FFmpeg)";
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-av1.c b/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
index 0b671ae..681f728 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
@@ -41,13 +41,13 @@ struct av1_encoder {
|
||||
static const char *aom_av1_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "AOM AV1";
|
||||
+ return "CPU: AOM AV1 (FFmpeg)";
|
||||
}
|
||||
|
||||
static const char *svt_av1_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "SVT-AV1";
|
||||
+ return "CPU: SVT-AV1 (FFmpeg)";
|
||||
}
|
||||
|
||||
static void av1_video_info(void *data, struct video_scale_info *info)
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
index 8cd8138..add8e02 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
@@ -45,7 +45,7 @@ struct nvenc_encoder {
|
||||
extern bool ubuntu_20_04_nvenc_fallback;
|
||||
#endif
|
||||
|
||||
-#define ENCODER_NAME_H264 "NVIDIA NVENC H.264 (FFmpeg)"
|
||||
+#define ENCODER_NAME_H264 "GPU: NVIDIA NVENC H.264 (FFmpeg)"
|
||||
static const char *h264_nvenc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
@@ -53,7 +53,7 @@ static const char *h264_nvenc_getname(void *unused)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
-#define ENCODER_NAME_HEVC "NVIDIA NVENC HEVC (FFmpeg)"
|
||||
+#define ENCODER_NAME_HEVC "GPU: NVIDIA NVENC H.265/HEVC (FFmpeg)"
|
||||
static const char *hevc_nvenc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
index 0f5ee7b..e350257 100644
|
||||
--- a/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
+++ b/plugins/obs-ffmpeg/texture-amf.cpp
|
||||
@@ -2101,7 +2101,7 @@ static obs_properties_t *amf_av1_properties(void *unused)
|
||||
|
||||
static const char *amf_avc_get_name(void *)
|
||||
{
|
||||
- return "AMD HW H.264 (AVC)";
|
||||
+ return "GPU: AMD AMF H.264 (FFmpeg)";
|
||||
}
|
||||
|
||||
static inline int get_avc_preset(amf_base *enc, const char *preset)
|
||||
@@ -2443,7 +2443,7 @@ static void register_avc()
|
||||
|
||||
static const char *amf_hevc_get_name(void *)
|
||||
{
|
||||
- return "AMD HW H.265 (HEVC)";
|
||||
+ return "GPU: AMD AMF H.265/HEVC (FFmpeg)";
|
||||
}
|
||||
|
||||
static inline int get_hevc_preset(amf_base *enc, const char *preset)
|
||||
@@ -2788,7 +2788,7 @@ static void register_hevc()
|
||||
|
||||
static const char *amf_av1_get_name(void *)
|
||||
{
|
||||
- return "AMD HW AV1";
|
||||
+ return "GPU: AMD AMF AV1 (FFmpeg)";
|
||||
}
|
||||
|
||||
static inline int get_av1_preset(amf_base *enc, const char *preset)
|
||||
diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c
|
||||
index 1de88d3..d4c377d 100644
|
||||
--- a/plugins/obs-x264/obs-x264.c
|
||||
+++ b/plugins/obs-x264/obs-x264.c
|
||||
@@ -68,7 +68,7 @@ struct obs_x264 {
|
||||
static const char *obs_x264_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "x264";
|
||||
+ return "CPU: x264";
|
||||
}
|
||||
|
||||
static void obs_x264_stop(void *data);
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
index 370f9b7..e0bbd82 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
@@ -89,20 +89,20 @@ struct vaapi_encoder {
|
||||
static const char *h264_vaapi_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "FFmpeg VAAPI H.264";
|
||||
+ return "GPU: AMD/Intel VAAPI H.264 (FFmpeg)";
|
||||
}
|
||||
|
||||
static const char *av1_vaapi_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "FFmpeg VAAPI AV1";
|
||||
+ return "GPU: AMD/Intel VAAPI AV1 (FFmpeg)";
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
static const char *hevc_vaapi_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "FFmpeg VAAPI HEVC";
|
||||
+ return "GPU: AMD/Intel VAAPI H.265/HEVC (FFmpeg)";
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
27
patches/0007-5fdda179ed2768304a98d48f4074e54fe7cbf5b3.patch
Normal file
27
patches/0007-5fdda179ed2768304a98d48f4074e54fe7cbf5b3.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 5fdda179ed2768304a98d48f4074e54fe7cbf5b3 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
Date: Fri, 30 Jun 2023 07:23:41 +0200
|
||||
Subject: [PATCH] obs-ffmpeg: Increase initial buffer fullness for VAAPI
|
||||
|
||||
Default ffmpeg initial buffer fullness (75%) is too low
|
||||
and results in significantly lower video quality on AMD cards.
|
||||
|
||||
Changing it to 100% fixes the quality and also matches what
|
||||
AMF encoder is doing.
|
||||
---
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
index c5aa0128a54b9..1a6ecd63ae4d4 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
|
||||
@@ -300,6 +300,8 @@ static bool vaapi_update(void *data, obs_data_t *settings, bool hevc)
|
||||
enc->context->level = level;
|
||||
enc->context->bit_rate = bitrate * 1000;
|
||||
enc->context->rc_max_rate = maxrate * 1000;
|
||||
+ enc->context->rc_initial_buffer_occupancy =
|
||||
+ (maxrate ? maxrate : bitrate) * 1000;
|
||||
|
||||
enc->context->width = obs_encoder_get_width(enc->encoder);
|
||||
enc->context->height = obs_encoder_get_height(enc->encoder);
|
@ -1,101 +0,0 @@
|
||||
From 6b022ae4b58af7a069a422d346f102bf18684249 Mon Sep 17 00:00:00 2001
|
||||
From: columbarius <co1umbarius@protonmail.com>
|
||||
Date: Sat, 21 Jan 2023 08:45:38 +0100
|
||||
Subject: [PATCH] pipewire: calc spa buffer size
|
||||
|
||||
Modern GPUs might support a lot of modifiers. As such the hardcoded size
|
||||
for the ENUM_Formats PipeWire params are not enough and we should
|
||||
calculate the required size manually.
|
||||
|
||||
Added logs if a ENUM_Format can't be assembled, which happens when the
|
||||
buffer size was not large enough.
|
||||
---
|
||||
plugins/linux-pipewire/pipewire.c | 47 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 45 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/linux-pipewire/pipewire.c b/plugins/linux-pipewire/pipewire.c
|
||||
index d639e86df0f25..e7a941d778b04 100644
|
||||
--- a/plugins/linux-pipewire/pipewire.c
|
||||
+++ b/plugins/linux-pipewire/pipewire.c
|
||||
@@ -144,6 +144,41 @@ static void update_pw_versions(obs_pipewire *obs_pw, const char *version)
|
||||
blog(LOG_WARNING, "[pipewire] failed to parse server version");
|
||||
}
|
||||
|
||||
+static uint32_t calc_spa_enumformat_buffer_size(obs_pipewire *obs_pw)
|
||||
+{
|
||||
+ // from spa/pod/pod.h
|
||||
+ uint32_t spa_pod_object_size = sizeof(struct spa_pod_object);
|
||||
+ uint32_t spa_pod_prop_size = sizeof(struct spa_pod_prop);
|
||||
+ uint32_t spa_pod_value_size = 1 * sizeof(uint64_t);
|
||||
+ uint32_t spa_pod_choice_size = 2 * sizeof(uint64_t);
|
||||
+ // This is counted from the build_format function
|
||||
+ uint32_t n_objects = 0;
|
||||
+ uint32_t n_props = 0;
|
||||
+ uint32_t n_values = 0;
|
||||
+ uint32_t n_choices = 0;
|
||||
+ uint32_t size;
|
||||
+
|
||||
+ for (size_t i = 0; i < obs_pw->format_info.num; i++) {
|
||||
+ if (obs_pw->format_info.array[i].modifiers.num == 0)
|
||||
+ continue;
|
||||
+ n_objects += 1;
|
||||
+ n_props += 5 + 1;
|
||||
+ n_values += 9 + 2 + obs_pw->format_info.array[i].modifiers.num;
|
||||
+ n_choices += 2 + 1;
|
||||
+ }
|
||||
+ for (size_t i = 0; i < obs_pw->format_info.num; i++) {
|
||||
+ n_objects += 1;
|
||||
+ n_props += 5;
|
||||
+ n_values += 9;
|
||||
+ n_choices += 2;
|
||||
+ }
|
||||
+ size = n_objects * spa_pod_object_size + n_props * spa_pod_prop_size +
|
||||
+ n_values * spa_pod_value_size + n_choices * spa_pod_choice_size;
|
||||
+ blog(LOG_DEBUG, "[pipewire]: calculated spa enumFormat buffer size %u",
|
||||
+ size);
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
static void teardown_pipewire(obs_pipewire *obs_pw)
|
||||
{
|
||||
if (obs_pw->thread_loop) {
|
||||
@@ -408,6 +443,10 @@ static bool build_format_params(obs_pipewire *obs_pw,
|
||||
obs_pw->format_info.array[i].spa_format,
|
||||
obs_pw->format_info.array[i].modifiers.array,
|
||||
obs_pw->format_info.array[i].modifiers.num);
|
||||
+ if (!params[params_count - 1]) {
|
||||
+ blog(LOG_ERROR, "[pipewire] Failed to format param");
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
build_shm:
|
||||
@@ -415,6 +454,10 @@ static bool build_format_params(obs_pipewire *obs_pw,
|
||||
params[params_count++] = build_format(
|
||||
pod_builder, &obs_pw->video_info,
|
||||
obs_pw->format_info.array[i].spa_format, NULL, 0);
|
||||
+ if (!params[params_count - 1]) {
|
||||
+ blog(LOG_ERROR, "[pipewire] Failed to format param");
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
*param_list = params;
|
||||
*n_params = params_count;
|
||||
@@ -521,7 +564,7 @@ static void renegotiate_format(void *data, uint64_t expirations)
|
||||
|
||||
pw_thread_loop_lock(obs_pw->thread_loop);
|
||||
|
||||
- uint8_t params_buffer[2048];
|
||||
+ uint8_t params_buffer[calc_spa_enumformat_buffer_size(obs_pw)];
|
||||
struct spa_pod_builder pod_builder =
|
||||
SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
|
||||
uint32_t n_params;
|
||||
@@ -970,7 +1013,7 @@ void obs_pipewire_connect_stream(obs_pipewire *obs_pw, int pipewire_node,
|
||||
struct spa_pod_builder pod_builder;
|
||||
const struct spa_pod **params = NULL;
|
||||
uint32_t n_params;
|
||||
- uint8_t params_buffer[2048];
|
||||
+ uint8_t params_buffer[calc_spa_enumformat_buffer_size(obs_pw)];
|
||||
|
||||
pw_thread_loop_lock(obs_pw->thread_loop);
|
||||
|
@ -1,93 +0,0 @@
|
||||
From 323db1c9072aa1338a00dc0ddd35c655bf1e4918 Mon Sep 17 00:00:00 2001
|
||||
From: GloriousEggroll <gloriouseggroll@gmail.com>
|
||||
Date: Mon, 16 Jan 2023 11:30:15 -0700
|
||||
Subject: [PATCH] encoder rename
|
||||
|
||||
---
|
||||
plugins/obs-ffmpeg/jim-nvenc.c | 4 ++--
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-av1.c | 4 ++--
|
||||
plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 4 ++--
|
||||
plugins/obs-ffmpeg/texture-amf.cpp | 4 ++--
|
||||
plugins/obs-x264/obs-x264.c | 2 +-
|
||||
5 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
index 7b247c8..5c4be0f 100644
|
||||
--- a/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/jim-nvenc.c
|
||||
@@ -227,14 +227,14 @@ static void nv_texture_free(struct nvenc_data *enc, struct nv_texture *nvtex)
|
||||
static const char *h264_nvenc_get_name(void *type_data)
|
||||
{
|
||||
UNUSED_PARAMETER(type_data);
|
||||
- return "NVIDIA NVENC H.264";
|
||||
+ return "GPU: Nvidia NVENC H.264/AVC";
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
static const char *hevc_nvenc_get_name(void *type_data)
|
||||
{
|
||||
UNUSED_PARAMETER(type_data);
|
||||
- return "NVIDIA NVENC HEVC";
|
||||
+ return "GPU: Nvidia NVENC H.265/HEVC";
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-av1.c b/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
index de7e237..7ea3cf7 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-av1.c
|
||||
@@ -41,13 +41,13 @@ struct av1_encoder {
|
||||
static const char *aom_av1_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "AOM AV1";
|
||||
+ return "CPU: AOM AV1";
|
||||
}
|
||||
|
||||
static const char *svt_av1_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "SVT-AV1";
|
||||
+ return "CPU: SVT-AV1";
|
||||
}
|
||||
|
||||
static void av1_video_info(void *data, struct video_scale_info *info)
|
||||
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
index f0f7747..b5f5d0d 100644
|
||||
--- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
|
||||
@@ -43,7 +43,7 @@ struct nvenc_encoder {
|
||||
extern bool ubuntu_20_04_nvenc_fallback;
|
||||
#endif
|
||||
|
||||
-#define ENCODER_NAME_H264 "NVIDIA NVENC H.264 (FFmpeg)"
|
||||
+#define ENCODER_NAME_H264 "GPU: Nvidia NVENC H.264/AVC"
|
||||
static const char *h264_nvenc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
@@ -51,7 +51,7 @@ static const char *h264_nvenc_getname(void *unused)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HEVC
|
||||
-#define ENCODER_NAME_HEVC "NVIDIA NVENC HEVC (FFmpeg)"
|
||||
+#define ENCODER_NAME_HEVC "GPU: Nvidia NVENC H.265/HEVC"
|
||||
static const char *hevc_nvenc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
|
||||
diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c
|
||||
index 3955dff..b60e990 100644
|
||||
--- a/plugins/obs-x264/obs-x264.c
|
||||
+++ b/plugins/obs-x264/obs-x264.c
|
||||
@@ -68,7 +68,7 @@ struct obs_x264 {
|
||||
static const char *obs_x264_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
- return "x264";
|
||||
+ return "CPU: x264";
|
||||
}
|
||||
|
||||
static void obs_x264_stop(void *data);
|
||||
--
|
||||
2.39.0
|
||||
|
@ -2,7 +2,7 @@
|
||||
rsync -azP --include './' --include '*.deb' --exclude '*' ./output/ ferreo@direct.pika-os.com:/srv/www/incoming/
|
||||
|
||||
# add debs to repo
|
||||
ssh ferreo@direct.pika-os.com 'aptly repo add -force-replace -remove-files pika-main /srv/www/incoming/'
|
||||
ssh ferreo@direct.pika-os.com 'aptly repo add -force-replace -remove-files pikauwu-main /srv/www/incoming/'
|
||||
|
||||
# publish the repo
|
||||
ssh ferreo@direct.pika-os.com 'aptly publish update -batch -skip-contents -force-overwrite lunar filesystem:pikarepo:'
|
||||
ssh ferreo@direct.pika-os.com 'aptly publish update -batch -skip-contents -force-overwrite pikauwu filesystem:pikarepo:'
|
Loading…
Reference in New Issue
Block a user