This commit is contained in:
Ward Nakchbandi (Cosmic Fusion) 2023-09-29 18:20:04 +03:00 committed by GitHub
parent f4d138b89a
commit 6f0ee9ff13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 2069 additions and 228 deletions

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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
View 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);
}

View File

@ -2269,3 +2269,4 @@ index 0000000000000..316276df75e54
+void pipewire_audio_capture_load(void);
+void pipewire_audio_capture_app_load(void);
+/* ------------------------------------------------- */

View File

@ -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
View 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
View 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
View 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);

View 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

View 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);

View File

@ -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);

View File

@ -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

View File

@ -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:'