diff options
author | tytan652 | 2022-09-01 10:13:33 +0200 |
---|---|---|
committer | tytan652 | 2022-09-01 10:13:33 +0200 |
commit | 77a6e6754ae9da90d77ad6988e32ec2195c90b5d (patch) | |
tree | 9d64d4cad65505ecdc278beca3afd88fc1e036d1 | |
parent | 9a479dbb4f4904c309b60a52b802397d5c891dec (diff) | |
download | aur-77a6e6754ae9da90d77ad6988e32ec2195c90b5d.tar.gz |
build: Update to 28.0.0
-rw-r--r-- | .SRCINFO | 30 | ||||
-rw-r--r-- | PKGBUILD | 106 | ||||
-rw-r--r-- | bind_iface.patch | 381 | ||||
-rw-r--r-- | v4l2_by-path.patch | 273 |
4 files changed, 383 insertions, 407 deletions
@@ -1,9 +1,8 @@ pkgbase = obs-studio-tytan652 pkgdesc = Free and open source software for video recording and live streaming. With everything except service integrations. Plus V4L2 devices by paths, my bind interface PR, and sometimes backported fixes - pkgver = 27.2.4 - pkgrel = 6 + pkgver = 28.0.0 + pkgrel = 1 url = https://github.com/obsproject/obs-studio - arch = i686 arch = x86_64 arch = aarch64 license = GPL3 @@ -14,15 +13,18 @@ pkgbase = obs-studio-tytan652 makedepends = luajit makedepends = sndio makedepends = lsb-release + makedepends = asio + makedepends = nlohmann-json + makedepends = websocketpp makedepends = libajantv2 - makedepends = python - makedepends = cef-minimal-obs=95.0.0_MediaHandler.2462+g95e19b8+chromium_95.0.4638.69_3 + makedepends = python>=3.10 depends = jack depends = gtk-update-icon-cache depends = x264 depends = rnnoise depends = pciutils - depends = qt5-wayland + depends = qt6-svg + depends = qt6-wayland depends = libxcomposite depends = pipewire depends = xdg-desktop-portal @@ -45,23 +47,29 @@ pkgbase = obs-studio-tytan652 optdepends = libajantv2: AJA NTV 2 support optdepends = python: Python scripting optdepends = decklink: Blackmagic Design DeckLink support - provides = obs-studio=27.2.4 + provides = obs-studio=28.0.0 provides = obs-vst + provides = obs-websocket provides = obs-browser conflicts = obs-studio conflicts = obs-vst + conflicts = obs-websocket conflicts = obs-linuxbrowser conflicts = obs-browser options = debug - source = obs-studio::git+https://github.com/obsproject/obs-studio.git#tag=27.2.4 + source = obs-studio::git+https://github.com/obsproject/obs-studio.git#tag=28.0.0 source = obs-browser::git+https://github.com/obsproject/obs-browser.git - source = obs-vst::git+https://github.com/obsproject/obs-vst.git + source = obs-websocket::git+https://github.com/obsproject/obs-websocket.git + source = qr::git+https://github.com/nayuki/QR-Code-generator.git source = bind_iface.patch source = v4l2_by-path.patch + source = https://cdn-fastly.obsproject.com/downloads/cef_binary_5060_linux64.tar.bz2 sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP - sha256sums = 4dc22cc6a71f879486946032debef5789b144d1d108a678379910480601937ca - sha256sums = e0cfe383286ae1b7e9a4f88ea0e8f05e79470bf677b16ac18bd2a64826c2ae28 + sha256sums = SKIP + sha256sums = a244f5b594ed7f0b215a0c0fb0bee445cbb5726b12fdfe539e70f0d9d991dab9 + sha256sums = ee54b9c6f7e17fcc62c6afc094e65f18b2e97963c2fe92289b2b91972ac206e5 + sha256sums = ac4e2a8ebf20700e4e36353e314f876623633dd5b474778a2548bb66bdbea11d pkgname = obs-studio-tytan652 @@ -3,23 +3,23 @@ DISTRIB_ID=`lsb_release --id | cut -f2 -d$'\t'` pkgname=obs-studio-tytan652 -pkgver=27.2.4 -pkgrel=6 +pkgver=28.0.0 +pkgrel=1 pkgdesc="Free and open source software for video recording and live streaming. With everything except service integrations. Plus V4L2 devices by paths, my bind interface PR, and sometimes backported fixes" -arch=("i686" "x86_64" "aarch64") +arch=("x86_64" "aarch64") url="https://github.com/obsproject/obs-studio" license=("GPL3") _mbedtlsver=2.28 _pythonver=3.10 depends=( - "jack" "gtk-update-icon-cache" "x264" "rnnoise" "pciutils" + "jack" "gtk-update-icon-cache" "x264" "rnnoise" "pciutils" "qt6-svg" # "libxinerama" "qt5-svg" provided by "vlc-luajit" # "libxkbcommon-x11" provided by "qt5-base" # "jansson" "curl" provided by "ftl-sdk" # Needed to use Qt on Wayland platform - "qt5-wayland" + "qt6-wayland" # Both needed to load linux-capture, so those two are no longer optional "libxcomposite" "pipewire" @@ -52,6 +52,9 @@ fi makedepends=( "cmake" "git" "libfdk-aac" "swig" "luajit" "sndio" "lsb-release" + # Needed by obs-websocket + 'asio' 'nlohmann-json' 'websocketpp' + # AUR Packages "libajantv2" ) @@ -80,13 +83,14 @@ if [[ $DISTRIB_ID == 'ManjaroLinux' ]]; then else optdepends+=("python>=$_pythonver: Python scripting") fi -provides=("obs-studio=$pkgver" "obs-vst") -conflicts=("obs-studio" "obs-vst") +provides=("obs-studio=$pkgver" "obs-vst" "obs-websocket") +conflicts=("obs-studio" "obs-vst" "obs-websocket") options=('debug') source=( "obs-studio::git+https://github.com/obsproject/obs-studio.git#tag=$pkgver" "obs-browser::git+https://github.com/obsproject/obs-browser.git" - "obs-vst::git+https://github.com/obsproject/obs-vst.git" + "obs-websocket::git+https://github.com/obsproject/obs-websocket.git" + "qr::git+https://github.com/nayuki/QR-Code-generator.git" "bind_iface.patch" # Based on https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/4219.patch "v4l2_by-path.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/3437.patch ) @@ -94,8 +98,9 @@ sha256sums=( "SKIP" "SKIP" "SKIP" - "4dc22cc6a71f879486946032debef5789b144d1d108a678379910480601937ca" - "e0cfe383286ae1b7e9a4f88ea0e8f05e79470bf677b16ac18bd2a64826c2ae28" + "SKIP" + "a244f5b594ed7f0b215a0c0fb0bee445cbb5726b12fdfe539e70f0d9d991dab9" + "ee54b9c6f7e17fcc62c6afc094e65f18b2e97963c2fe92289b2b91972ac206e5" ) if [[ $DISTRIB_ID == 'ManjaroLinux' ]]; then @@ -109,81 +114,72 @@ sha256sums+=( ) fi -if [[ $CARCH == 'x86_64' ]] || [[ $CARCH == 'i686' ]]; then +if [[ $CARCH == 'x86_64' ]]; then optdepends+=("decklink: Blackmagic Design DeckLink support") fi if [[ $CARCH == 'x86_64' ]]; then - makedepends+=("cef-minimal-obs=95.0.0_MediaHandler.2462+g95e19b8+chromium_95.0.4638.69_3") + _cefbranch=5060 + source+=("https://cdn-fastly.obsproject.com/downloads/cef_binary_${_cefbranch}_linux64.tar.bz2") + sha256sums+=("ac4e2a8ebf20700e4e36353e314f876623633dd5b474778a2548bb66bdbea11d") provides+=("obs-browser") conflicts+=("obs-linuxbrowser" "obs-browser") _browser=ON + _arch=64 + _parch=x86_64 else _browser=OFF fi prepare() { cd "$srcdir/obs-studio" - git config submodule.plugins/obs-vst.url $srcdir/obs-vst git config submodule.plugins/obs-browser.url $srcdir/obs-browser + git config submodule.plugins/obs-websocket.url $srcdir/obs-websocket git submodule update - ## UI: Fix display affinity logic when re-applying (https://github.com/obsproject/obs-studio/commit/a8ecf3c8f2c2c28624a01249d3ec8b6435198009) - git cherry-pick -n a8ecf3c8f2c2c28624a01249d3ec8b6435198009 - - ## UI: Truncate displayed file paths in the middle in Remux window (https://github.com/obsproject/obs-studio/commit/2d75167e4c82207d0380512de4757521eeade0ba) - git cherry-pick -n 2d75167e4c82207d0380512de4757521eeade0ba - - ## libobs: Fix image source not loading upper case file extensions (https://github.com/obsproject/obs-studio/commit/9903d73f36809c20795d5a918f2898fa6b8b88f8) - git cherry-pick -n 9903d73f36809c20795d5a918f2898fa6b8b88f8 - - ## linux-capture: Don't initialize format info if init_obs_pipewire fails (https://github.com/obsproject/obs-studio/commit/9903d73f36809c20795d5a918f2898fa6b8b88f8) - sed -i '1438 a return NULL; }' plugins/linux-capture/pipewire.c - sed -i '1437 a {' plugins/linux-capture/pipewire.c - - ## linux-pipewire: Version check call to pw_deinit (https://github.com/obsproject/obs-studio/commit/bf660b1d8dc1905527bb5919b1034c7b43c55dac) - sed -i '74,77d' plugins/linux-capture/linux-capture.c - - ## libobs, UI: Fix --verbose logging for stdout (https://github.com/obsproject/obs-studio/commit/af67ef8e57fbf05e772f4cd6fcd3649e15689304) - git cherry-pick -n af67ef8e57fbf05e772f4cd6fcd3649e15689304 - - ## vlc-source: Fix surround sound not properly downmixed (https://github.com/obsproject/obs-studio/commit/5e4081e5637c7b6761ce54d5aef344fa85414e29) - git cherry-pick -n 5e4081e5637c7b6761ce54d5aef344fa85414e29 - - ## vlc-video: Fix video rotation and aspect ratio (https://github.com/obsproject/obs-studio/commit/59bdac1569304cd2112154b51fa5d25df61569cf) - git cherry-pick -n 59bdac1569304cd2112154b51fa5d25df61569cf - - ## libobs-opengl: Use gl helpers in create_dmabuf_image (https://github.com/obsproject/obs-studio/commit/f695b14edc59e7c778566820988f9998df5190ba) - git cherry-pick -n f695b14edc59e7c778566820988f9998df5190ba - - ## libobs,obs-outputs: Fix librtmp1 dependency interference on some linuxes (https://github.com/obsproject/obs-studio/pull/6377) - sed -i 's/#define EXPORT/#define EXPORT __attribute__((visibility("default")))/g' libobs/util/c99defs.h - - ## obs-ffmpeg: Several fixes allowing support of FFmpeg 5 (https://github.com/obsproject/obs-studio/pull/6423) - git cherry-pick -n e66542075d5d2cb51a14a0bdf3458ac10757de64 - git cherry-pick -n 5b6cc73c2475abe6a85647604b9ce937dec09000 - git cherry-pick -n 12d1f1c3358f7231244db0b971a333445e346f80 - - ## obs-ffmpeg: Change types to avoid unnecessary casts (https://github.com/obsproject/obs-studio/commit/8bd4ef61a02f6f574d4788f2bc25bb9fe2568c5c) - git cherry-pick -n 8bd4ef61a02f6f574d4788f2bc25bb9fe2568c5c + cd plugins/obs-websocket + sed -i 's|EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/json/CMakeLists.txt||' CMakeLists.txt + sed -i 's|AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp/CMakeLists.txt||' CMakeLists.txt + sed -i 's|AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include/asio.hpp||' CMakeLists.txt + sed -i "s|AND EXISTS|EXISTS|" CMakeLists.txt + sed -i "s|add_subdirectory(deps/json)|find_package(nlohmann_json 3.10.0 REQUIRED)|" CMakeLists.txt + git config submodule.deps/qr.url $srcdir/qr + git submodule update deps/qr + cd "$srcdir/obs-studio" ## Add network interface binding for RTMP on Linux (https://github.com/obsproject/obs-studio/pull/4219) patch -Np1 < "$srcdir/bind_iface.patch" - ## linux-v4l2: Save device by path (https://github.com/obsproject/obs-studio/pull/3437) + ## linux-v4l2: Save device by id or path (https://github.com/obsproject/obs-studio/pull/6493) patch -Np1 < "$srcdir/v4l2_by-path.patch" } build() { - cd obs-studio + if [[ $CARCH == 'x86_64' ]]; then + cd "$srcdir"/cef_binary_${_cefbranch}_linux${_arch} + + #The arm64 CEF set the wrong arch for the project + cmake \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DPROJECT_ARCH=$_parch . + + make libcef_dll_wrapper + fi + + cd "$srcdir"/obs-studio mkdir -p build; cd build cmake \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_INSTALL_LIBDIR=lib \ - -DBUILD_BROWSER=$_browser \ - -DCEF_ROOT_DIR=/opt/cef-obs \ + -DENABLE_RTMPS=ON \ + -DQT_VERSION=6 \ + -DENABLE_LIBFDK=ON \ + -DENABLE_JACK=ON \ + -DENABLE_SNDIO=ON \ + -DENABLE_BROWSER=$_browser \ + -DCEF_ROOT_DIR="$srcdir/cef_binary_${_cefbranch}_linux${_arch}" \ -DOBS_VERSION_OVERRIDE="$pkgver-tytan652-$pkgrel" .. make diff --git a/bind_iface.patch b/bind_iface.patch index 0b0abe7b7e3a..fac2205b0898 100644 --- a/bind_iface.patch +++ b/bind_iface.patch @@ -1,7 +1,7 @@ -From 8f8670c02e1df91343985b4ed59bb55135fae966 Mon Sep 17 00:00:00 2001 +From 187466a01a80cc0d4af9fe13888d0232b39ca999 Mon Sep 17 00:00:00 2001 From: tytan652 <tytan652@tytanium.xyz> Date: Thu, 11 Feb 2021 14:29:08 +0100 -Subject: [PATCH 1/5] librtmp: Add interface binding for Linux +Subject: [PATCH 1/3] librtmp: Add interface binding for Linux librtmp: Make log message more accurate --- @@ -10,10 +10,10 @@ librtmp: Make log message more accurate 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/plugins/obs-outputs/librtmp/rtmp.c b/plugins/obs-outputs/librtmp/rtmp.c -index 70e42f7ee636..7c5346c07a42 100644 +index 88c7cff7cfb18..d063d268820f8 100644 --- a/plugins/obs-outputs/librtmp/rtmp.c +++ b/plugins/obs-outputs/librtmp/rtmp.c -@@ -874,13 +874,30 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen) +@@ -877,13 +877,30 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen) #ifdef SO_NOSIGPIPE setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_NOSIGPIPE, &(int){ 1 }, sizeof(int)); #endif @@ -46,10 +46,10 @@ index 70e42f7ee636..7c5346c07a42 100644 r->last_error_code = err; RTMP_Close(r); diff --git a/plugins/obs-outputs/librtmp/rtmp.h b/plugins/obs-outputs/librtmp/rtmp.h -index 5020120ee3ee..8a6f64375ffb 100644 +index b1c48e2f3a9f6..a900efbe17a0d 100644 --- a/plugins/obs-outputs/librtmp/rtmp.h +++ b/plugins/obs-outputs/librtmp/rtmp.h -@@ -423,6 +423,7 @@ extern "C" +@@ -420,6 +420,7 @@ extern "C" void* m_customSendParam; CUSTOMSEND m_customSendFunc; @@ -58,23 +58,23 @@ index 5020120ee3ee..8a6f64375ffb 100644 uint8_t m_bSendChunkSizeInfo; -From 6326cc5bb4256556e545c1f7c6679a422883d364 Mon Sep 17 00:00:00 2001 +From 5da8a83216852445be763a2f06432b2cd07bdfbf Mon Sep 17 00:00:00 2001 From: tytan652 <tytan652@tytanium.xyz> Date: Thu, 11 Feb 2021 14:47:45 +0100 -Subject: [PATCH 2/5] obs-outputs: Add RTMP iface binding for Linux +Subject: [PATCH 2/3] obs-outputs: Add RTMP iface binding for Linux --- - plugins/obs-outputs/net-if.c | 32 +++++++++++++++++++++++++++ - plugins/obs-outputs/net-if.h | 15 +++++++++++++ - plugins/obs-outputs/rtmp-stream.c | 36 +++++++++++++++++++++++++++++++ + plugins/obs-outputs/net-if.c | 32 +++++++++++++++++++++++++++++ + plugins/obs-outputs/net-if.h | 15 ++++++++++++++ + plugins/obs-outputs/rtmp-stream.c | 34 +++++++++++++++++++++++++++++++ plugins/obs-outputs/rtmp-stream.h | 2 ++ - 4 files changed, 85 insertions(+) + 4 files changed, 83 insertions(+) diff --git a/plugins/obs-outputs/net-if.c b/plugins/obs-outputs/net-if.c -index 40891ef3d233..206394ff175c 100644 +index 29bb57d6a42bc..1587be47887b8 100644 --- a/plugins/obs-outputs/net-if.c +++ b/plugins/obs-outputs/net-if.c -@@ -134,6 +134,38 @@ static inline bool is_loopback(struct ifaddrs *ifa) +@@ -139,6 +139,38 @@ static inline bool is_loopback(struct ifaddrs *ifa) return n && (strcmp(n, "lo") == 0 || strcmp(n, "lo0") == 0); } @@ -114,7 +114,7 @@ index 40891ef3d233..206394ff175c 100644 { struct ifaddrs *ifaddr, *ifa; diff --git a/plugins/obs-outputs/net-if.h b/plugins/obs-outputs/net-if.h -index 757ee00e8278..6b045666cfba 100644 +index 757ee00e82781..6b045666cfba6 100644 --- a/plugins/obs-outputs/net-if.h +++ b/plugins/obs-outputs/net-if.h @@ -53,6 +53,21 @@ @@ -140,10 +140,10 @@ index 757ee00e8278..6b045666cfba 100644 char *name; char *addr; diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c -index e2223a8690fb..5e5235afe67d 100644 +index 5a3773974112c..7e6cc577d52d5 100644 --- a/plugins/obs-outputs/rtmp-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c -@@ -122,6 +122,7 @@ static void rtmp_stream_destroy(void *data) +@@ -125,6 +125,7 @@ static void rtmp_stream_destroy(void *data) dstr_free(&stream->username); dstr_free(&stream->password); dstr_free(&stream->encoder_name); @@ -151,7 +151,7 @@ index e2223a8690fb..5e5235afe67d 100644 dstr_free(&stream->bind_ip); os_event_destroy(stream->stop_event); os_sem_destroy(stream->send_sem); -@@ -1039,6 +1040,17 @@ static int try_connect(struct rtmp_stream *stream) +@@ -1067,6 +1068,17 @@ static int try_connect(struct rtmp_stream *stream) stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl; stream->rtmp.Link.customConnectEncode = add_connect_data; @@ -169,7 +169,7 @@ index e2223a8690fb..5e5235afe67d 100644 if (dstr_is_empty(&stream->bind_ip) || dstr_cmp(&stream->bind_ip, "default") == 0) { memset(&stream->rtmp.m_bindIP, 0, -@@ -1081,6 +1093,7 @@ static bool init_connect(struct rtmp_stream *stream) +@@ -1109,6 +1121,7 @@ static bool init_connect(struct rtmp_stream *stream) { obs_service_t *service; obs_data_t *settings; @@ -177,7 +177,7 @@ index e2223a8690fb..5e5235afe67d 100644 const char *bind_ip; int64_t drop_p; int64_t drop_b; -@@ -1152,6 +1165,9 @@ static bool init_connect(struct rtmp_stream *stream) +@@ -1180,6 +1193,9 @@ static bool init_connect(struct rtmp_stream *stream) stream->drop_threshold_usec = 1000 * drop_b; stream->pframe_drop_threshold_usec = 1000 * drop_p; @@ -187,33 +187,32 @@ index e2223a8690fb..5e5235afe67d 100644 bind_ip = obs_data_get_string(settings, OPT_BIND_IP); dstr_copy(&stream->bind_ip, bind_ip); -@@ -1540,12 +1556,32 @@ static obs_properties_t *rtmp_stream_properties(void *unused) +@@ -1568,6 +1584,9 @@ static obs_properties_t *rtmp_stream_properties(void *unused) UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); +#ifdef __linux__ + struct netif_siface_data ifaces = {0}; -+ obs_property_t *p_iface; +#endif struct netif_saddr_data addrs = {0}; obs_property_t *p; - obs_properties_add_int(props, OPT_DROP_THRESHOLD, - obs_module_text("RTMPStream.DropThreshold"), 200, - 10000, 100); +@@ -1575,6 +1594,21 @@ static obs_properties_t *rtmp_stream_properties(void *unused) + obs_module_text("RTMPStream.DropThreshold"), + 200, 10000, 100); + obs_property_int_set_suffix(p, " ms"); +#ifdef __linux__ -+ p_iface = obs_properties_add_list( -+ props, OPT_BIND_INTERFACE, -+ obs_module_text("RTMPStream.BindInterface"), -+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); ++ p = obs_properties_add_list(props, OPT_BIND_INTERFACE, ++ obs_module_text("RTMPStream.BindInterface"), ++ OBS_COMBO_TYPE_LIST, ++ OBS_COMBO_FORMAT_STRING); + -+ obs_property_list_add_string(p_iface, obs_module_text("Default"), -+ "default"); ++ obs_property_list_add_string(p, obs_module_text("Default"), "default"); + + netif_get_ifaces(&ifaces); + for (size_t i = 0; i < ifaces.ifaces.num; i++) { + char *item = ifaces.ifaces.array[i]; -+ obs_property_list_add_string(p_iface, item, item); ++ obs_property_list_add_string(p, item, item); + } + netif_siface_data_free(&ifaces); +#endif @@ -221,7 +220,7 @@ index e2223a8690fb..5e5235afe67d 100644 p = obs_properties_add_list(props, OPT_BIND_IP, obs_module_text("RTMPStream.BindIP"), diff --git a/plugins/obs-outputs/rtmp-stream.h b/plugins/obs-outputs/rtmp-stream.h -index bca991909d42..474faab3ee7a 100644 +index bca991909d42a..474faab3ee7a0 100644 --- a/plugins/obs-outputs/rtmp-stream.h +++ b/plugins/obs-outputs/rtmp-stream.h @@ -28,6 +28,7 @@ @@ -241,40 +240,41 @@ index bca991909d42..474faab3ee7a 100644 /* frame drop variables */ -From a6631eaf77dfa5be1bbab8dee0005504f81f53d4 Mon Sep 17 00:00:00 2001 +From 7b0cf93f6b518701daac9484cbd24be0cbf7e76e Mon Sep 17 00:00:00 2001 From: tytan652 <tytan652@tytanium.xyz> Date: Thu, 11 Feb 2021 14:51:42 +0100 -Subject: [PATCH 3/5] UI: Add interface binding property for Linux +Subject: [PATCH 3/3] UI: Add interface binding property for Linux --- UI/data/locale/en-US.ini | 1 + - UI/forms/OBSBasicSettings.ui | 24 ++++++++++++---- - UI/window-basic-auto-config-test.cpp | 3 ++ - UI/window-basic-main-outputs.cpp | 6 ++++ - UI/window-basic-main.cpp | 2 ++ - UI/window-basic-settings.cpp | 42 ++++++++++++++++++++++++++++ - 6 files changed, 73 insertions(+), 5 deletions(-) + UI/forms/OBSBasicSettings.ui | 16 ++++- + UI/window-basic-auto-config-test.cpp | 3 + + UI/window-basic-main-outputs.cpp | 6 ++ + UI/window-basic-main.cpp | 2 + + UI/window-basic-settings.cpp | 91 +++++++++++++++++++++++++++- + UI/window-basic-settings.hpp | 3 + + 7 files changed, 119 insertions(+), 3 deletions(-) diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini -index 8a2413c65c99..3cba5cbfcb27 100644 +index 06361584c96cb..8104e3bf47548 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini -@@ -1039,6 +1039,7 @@ Basic.Settings.Advanced.StreamDelay.Duration="Duration" - Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting" +@@ -1154,6 +1154,7 @@ Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase de Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimated Memory Usage: %1 MB" Basic.Settings.Advanced.Network="Network" + Basic.Settings.Advanced.Network.Disabled="The currently selected streaming protocol does not support changing network settings." +Basic.Settings.Advanced.Network.BindToInterface="Bind to interface" Basic.Settings.Advanced.Network.BindToIP="Bind to IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Enable network optimizations" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Enable TCP pacing" diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui -index 87da1c95bb01..cad29dc04283 100644 +index 4552856e7a88c..e998830deddc4 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui -@@ -5443,6 +5443,19 @@ - <number>2</number> - </property> - <item row="0" column="0"> +@@ -7267,6 +7267,19 @@ + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="bindToIfaceLabel"> + <property name="text"> + <string>Basic.Settings.Advanced.Network.BindToInterface</string> @@ -284,53 +284,23 @@ index 87da1c95bb01..cad29dc04283 100644 + </property> + </widget> + </item> -+ <item row="0" column="1"> ++ <item row="1" column="1"> + <widget class="QComboBox" name="bindToInterface"/> + </item> -+ <item row="1" column="0"> - <widget class="QLabel" name="label_27"> ++ <item row="2" column="0"> + <widget class="QLabel" name="bindToIPLabel"> <property name="text"> <string>Basic.Settings.Advanced.Network.BindToIP</string> -@@ -5452,17 +5465,17 @@ +@@ -7276,7 +7289,7 @@ </property> </widget> </item> -- <item row="0" column="1"> -+ <item row="1" column="1"> - <widget class="QComboBox" name="bindToIP"/> - </item> -- <item row="2" column="1"> -+ <item row="3" column="1"> - <widget class="QCheckBox" name="enableNewSocketLoop"> - <property name="text"> - <string>Basic.Settings.Advanced.Network.EnableNewSocketLoop</string> - </property> - </widget> - </item> -- <item row="3" column="1"> -+ <item row="4" column="1"> - <widget class="QCheckBox" name="enableLowLatencyMode"> - <property name="enabled"> - <bool>false</bool> -@@ -5472,7 +5485,7 @@ - </property> - </widget> - </item> -- <item row="2" column="0"> -+ <item row="3" column="0"> - <spacer name="horizontalSpacer_7"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> -@@ -5485,7 +5498,7 @@ - </property> - </spacer> - </item> - <item row="1" column="1"> + <item row="2" column="1"> - <widget class="QCheckBox" name="dynBitrate"> - <property name="toolTip"> - <string>Basic.Settings.Output.DynamicBitrate.TT</string> -@@ -5827,6 +5840,7 @@ + <widget class="QComboBox" name="bindToIP"/> + </item> + <item row="3" column="1"> +@@ -7620,6 +7633,7 @@ <tabstop>reconnectRetryDelay</tabstop> <tabstop>reconnectMaxRetries</tabstop> <tabstop>bindToIP</tabstop> @@ -339,7 +309,7 @@ index 87da1c95bb01..cad29dc04283 100644 <tabstop>enableNewSocketLoop</tabstop> <tabstop>enableLowLatencyMode</tabstop> diff --git a/UI/window-basic-auto-config-test.cpp b/UI/window-basic-auto-config-test.cpp -index 4208efe67940..1ac13e60209e 100644 +index 17b15e33b6f7a..8757a11fff40e 100644 --- a/UI/window-basic-auto-config-test.cpp +++ b/UI/window-basic-auto-config-test.cpp @@ -228,6 +228,9 @@ void AutoConfigTestPage::TestBandwidthThread() @@ -353,10 +323,10 @@ index 4208efe67940..1ac13e60209e 100644 config_get_string(main->Config(), "Output", "BindIP"); obs_data_set_string(output_settings, "bind_ip", bind_ip); diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp -index d4351f7f6e55..9ad3a294aa63 100644 +index 39e2ff84f0765..60b66818222bd 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp -@@ -882,6 +882,8 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) +@@ -928,6 +928,8 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) int delaySec = config_get_int(main->Config(), "Output", "DelaySec"); bool preserveDelay = config_get_bool(main->Config(), "Output", "DelayPreserve"); @@ -365,7 +335,7 @@ index d4351f7f6e55..9ad3a294aa63 100644 const char *bindIP = config_get_string(main->Config(), "Output", "BindIP"); bool enableNewSocketLoop = config_get_bool(main->Config(), "Output", -@@ -892,6 +894,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) +@@ -938,6 +940,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) config_get_bool(main->Config(), "Output", "DynamicBitrate"); OBSDataAutoRelease settings = obs_data_create(); @@ -373,7 +343,7 @@ index d4351f7f6e55..9ad3a294aa63 100644 obs_data_set_string(settings, "bind_ip", bindIP); obs_data_set_bool(settings, "new_socket_loop_enabled", enableNewSocketLoop); -@@ -1771,6 +1774,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) +@@ -1827,6 +1830,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) int delaySec = config_get_int(main->Config(), "Output", "DelaySec"); bool preserveDelay = config_get_bool(main->Config(), "Output", "DelayPreserve"); @@ -382,7 +352,7 @@ index d4351f7f6e55..9ad3a294aa63 100644 const char *bindIP = config_get_string(main->Config(), "Output", "BindIP"); bool enableNewSocketLoop = config_get_bool(main->Config(), "Output", -@@ -1781,6 +1786,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) +@@ -1837,6 +1842,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) config_get_bool(main->Config(), "Output", "DynamicBitrate"); OBSDataAutoRelease settings = obs_data_create(); @@ -391,12 +361,12 @@ index d4351f7f6e55..9ad3a294aa63 100644 obs_data_set_bool(settings, "new_socket_loop_enabled", enableNewSocketLoop); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp -index fa172ce5ef41..ed8fead412c6 100644 +index a726316957259..3354feda8bd01 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp -@@ -1436,6 +1436,8 @@ bool OBSBasic::InitBasicConfigDefaults() - config_set_default_uint(basicConfig, "Output", "RetryDelay", 10); - config_set_default_uint(basicConfig, "Output", "MaxRetries", 20); +@@ -1464,6 +1464,8 @@ bool OBSBasic::InitBasicConfigDefaults() + config_set_default_uint(basicConfig, "Output", "RetryDelay", 2); + config_set_default_uint(basicConfig, "Output", "MaxRetries", 25); + config_set_default_string(basicConfig, "Output", "BindInterface", + "default"); @@ -404,10 +374,10 @@ index fa172ce5ef41..ed8fead412c6 100644 config_set_default_bool(basicConfig, "Output", "NewSocketLoopEnable", false); diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp -index 02eb3ca071b6..c01497a1f8c6 100644 +index 2c4c8a8592191..145f64cbfb0dc 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp -@@ -552,6 +552,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) +@@ -560,6 +560,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->reconnectMaxRetries, SCROLL_CHANGED, ADV_CHANGED); HookWidget(ui->processPriority, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->confirmOnExit, CHECK_CHANGED, ADV_CHANGED); @@ -417,7 +387,7 @@ index 02eb3ca071b6..c01497a1f8c6 100644 HookWidget(ui->bindToIP, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->enableNewSocketLoop, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->enableLowLatencyMode, CHECK_CHANGED, ADV_CHANGED); -@@ -667,6 +670,13 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) +@@ -674,6 +677,13 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) ui->resetOSXVSync = nullptr; #endif @@ -431,20 +401,27 @@ index 02eb3ca071b6..c01497a1f8c6 100644 connect(ui->streamDelaySec, SIGNAL(valueChanged(int)), this, SLOT(UpdateStreamDelayEstimate())); connect(ui->outputMode, SIGNAL(currentIndexChanged(int)), this, -@@ -813,10 +823,29 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) +@@ -825,9 +835,37 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) + SLOT(AdvReplayBufferChanged())); connect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(SimpleRecordingEncoderChanged())); ++#ifdef __linux__ ++ connect(ui->bindToInterface, SIGNAL(currentIndexChanged(int)), this, ++ SLOT(UpdateAddrList())); +- // Get Bind to IP Addresses ++ ui->bindToIP->setEnabled(false); ++#endif ++ + // Get Bind to interfaces Interfaces (Linux only) - // Get Bind to IP Addresses ++ // Get Bind to IP Addresses (Others) obs_properties_t *ppts = obs_get_output_properties("rtmp_output"); +#ifdef __linux__ + obs_property_t *p_iface = obs_properties_get(ppts, "bind_interface"); + QStringList dedup_iface = {}; -+#endif - obs_property_t *p = obs_properties_get(ppts, "bind_ip"); - -+#ifdef __linux__ ++ ++ ui->bindToInterface->blockSignals(true); ++ + size_t count_iface = obs_property_list_item_count(p_iface); + for (size_t i = 0; i < count_iface; i++) { + const char *name = obs_property_list_item_name(p_iface, i); @@ -456,12 +433,23 @@ index 02eb3ca071b6..c01497a1f8c6 100644 + ui->bindToInterface->addItem(QT_UTF8(name), val); + } + } -+#endif + ++ UpdateAddrList(); ++ ui->bindToInterface->blockSignals(false); ++#else + obs_property_t *p = obs_properties_get(ppts, "bind_ip"); + size_t count = obs_property_list_item_count(p); - for (size_t i = 0; i < count; i++) { - const char *name = obs_property_list_item_name(p, i); -@@ -2517,6 +2546,10 @@ void OBSBasicSettings::LoadAdvancedSettings() +@@ -837,7 +875,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) + + ui->bindToIP->addItem(QT_UTF8(name), val); + } +- ++#endif + obs_properties_destroy(ppts); + + InitStreamPage(); +@@ -2609,6 +2647,10 @@ void OBSBasicSettings::LoadAdvancedSettings() "FilenameFormatting"); bool overwriteIfExists = config_get_bool(main->Config(), "Output", "OverwriteIfExists"); @@ -472,9 +460,9 @@ index 02eb3ca071b6..c01497a1f8c6 100644 const char *bindIP = config_get_string(main->Config(), "Output", "BindIP"); const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput", -@@ -2568,6 +2601,12 @@ void OBSBasicSettings::LoadAdvancedSettings() - SetComboByName(ui->colorSpace, videoColorSpace); - SetComboByValue(ui->colorRange, videoColorRange); +@@ -2662,6 +2704,12 @@ void OBSBasicSettings::LoadAdvancedSettings() + ui->sdrWhiteLevel->setValue(sdrWhiteLevel); + ui->hdrNominalPeakLevel->setValue(hdrNominalPeakLevel); +#ifdef __linux__ + if (!SetComboByValue(ui->bindToInterface, bindInterface)) @@ -485,7 +473,7 @@ index 02eb3ca071b6..c01497a1f8c6 100644 if (!SetComboByValue(ui->bindToIP, bindIP)) SetInvalidValue(ui->bindToIP, bindIP, bindIP); -@@ -3299,6 +3338,9 @@ void OBSBasicSettings::SaveAdvancedSettings() +@@ -3383,6 +3431,9 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveCheckBox(ui->reconnectEnable, "Output", "Reconnect"); SaveSpinBox(ui->reconnectRetryDelay, "Output", "RetryDelay"); SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries"); @@ -495,150 +483,14 @@ index 02eb3ca071b6..c01497a1f8c6 100644 SaveComboData(ui->bindToIP, "Output", "BindIP"); SaveCheckBox(ui->autoRemux, "Video", "AutoRemux"); SaveCheckBox(ui->dynBitrate, "Output", "DynamicBitrate"); - -From 8dae0ab3bedcd9ac5f843ff2ef8c9a0a37f1e20b Mon Sep 17 00:00:00 2001 -From: tytan652 <tytan652@tytanium.xyz> -Date: Thu, 11 Feb 2021 14:53:55 +0100 -Subject: [PATCH 4/5] UI,obs-outputs: Rename bind IP property variables - ---- - UI/window-basic-settings.cpp | 10 +++++----- - plugins/obs-outputs/rtmp-stream.c | 15 ++++++++------- - 2 files changed, 13 insertions(+), 12 deletions(-) - -diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp -index c01497a1f8c6..c8712e6cb627 100644 ---- a/UI/window-basic-settings.cpp -+++ b/UI/window-basic-settings.cpp -@@ -830,7 +830,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - obs_property_t *p_iface = obs_properties_get(ppts, "bind_interface"); - QStringList dedup_iface = {}; - #endif -- obs_property_t *p = obs_properties_get(ppts, "bind_ip"); -+ obs_property_t *p_addr = obs_properties_get(ppts, "bind_ip"); - - #ifdef __linux__ - size_t count_iface = obs_property_list_item_count(p_iface); -@@ -846,10 +846,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - } +@@ -5429,5 +5480,41 @@ void OBSBasicSettings::UpdateAdvNetworkGroup() + #ifdef _WIN32 + ui->enableNewSocketLoop->setVisible(enabled); + ui->enableLowLatencyMode->setVisible(enabled); ++#elif defined(__linux__) ++ ui->bindToIfaceLabel->setVisible(enabled); ++ ui->bindToInterface->setVisible(enabled); #endif - -- size_t count = obs_property_list_item_count(p); -- for (size_t i = 0; i < count; i++) { -- const char *name = obs_property_list_item_name(p, i); -- const char *val = obs_property_list_item_string(p, i); -+ size_t count_addr = obs_property_list_item_count(p_addr); -+ for (size_t i = 0; i < count_addr; i++) { -+ const char *name = obs_property_list_item_name(p_addr, i); -+ const char *val = obs_property_list_item_string(p_addr, i); - - ui->bindToIP->addItem(QT_UTF8(name), val); - } -diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c -index 5e5235afe67d..834af5e0c02c 100644 ---- a/plugins/obs-outputs/rtmp-stream.c -+++ b/plugins/obs-outputs/rtmp-stream.c -@@ -1561,7 +1561,7 @@ static obs_properties_t *rtmp_stream_properties(void *unused) - obs_property_t *p_iface; - #endif - struct netif_saddr_data addrs = {0}; -- obs_property_t *p; -+ obs_property_t *p_addr; - - obs_properties_add_int(props, OPT_DROP_THRESHOLD, - obs_module_text("RTMPStream.DropThreshold"), 200, -@@ -1583,17 +1583,18 @@ static obs_properties_t *rtmp_stream_properties(void *unused) - netif_siface_data_free(&ifaces); - #endif - -- p = obs_properties_add_list(props, OPT_BIND_IP, -- obs_module_text("RTMPStream.BindIP"), -- OBS_COMBO_TYPE_LIST, -- OBS_COMBO_FORMAT_STRING); -+ p_addr = obs_properties_add_list(props, OPT_BIND_IP, -+ obs_module_text("RTMPStream.BindIP"), -+ OBS_COMBO_TYPE_LIST, -+ OBS_COMBO_FORMAT_STRING); - -- obs_property_list_add_string(p, obs_module_text("Default"), "default"); -+ obs_property_list_add_string(p_addr, obs_module_text("Default"), -+ "default"); - - netif_get_addrs(&addrs); - for (size_t i = 0; i < addrs.addrs.num; i++) { - struct netif_saddr_item item = addrs.addrs.array[i]; -- obs_property_list_add_string(p, item.name, item.addr); -+ obs_property_list_add_string(p_addr, item.name, item.addr); - } - netif_saddr_data_free(&addrs); - - -From bbbafbe6ccc0b0add51dceeb7afceca6447b653a Mon Sep 17 00:00:00 2001 -From: tytan652 <tytan652@tytanium.xyz> -Date: Mon, 15 Feb 2021 11:37:56 +0100 -Subject: [PATCH 5/5] UI: Disable bind IP if no iface selected on Linux - ---- - UI/window-basic-settings.cpp | 54 ++++++++++++++++++++++++++++++++---- - UI/window-basic-settings.hpp | 3 ++ - 2 files changed, 51 insertions(+), 6 deletions(-) - -diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp -index c8712e6cb627..0509f1af00d9 100644 ---- a/UI/window-basic-settings.cpp -+++ b/UI/window-basic-settings.cpp -@@ -822,17 +822,22 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - SLOT(AdvReplayBufferChanged())); - connect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, - SLOT(SimpleRecordingEncoderChanged())); -+#ifdef __linux__ -+ connect(ui->bindToInterface, SIGNAL(currentIndexChanged(int)), this, -+ SLOT(UpdateAddrList())); -+ -+ ui->bindToIP->setEnabled(false); -+#endif - - // Get Bind to interfaces Interfaces (Linux only) -- // Get Bind to IP Addresses -+ // Get Bind to IP Addresses (Others) - obs_properties_t *ppts = obs_get_output_properties("rtmp_output"); - #ifdef __linux__ - obs_property_t *p_iface = obs_properties_get(ppts, "bind_interface"); - QStringList dedup_iface = {}; --#endif -- obs_property_t *p_addr = obs_properties_get(ppts, "bind_ip"); - --#ifdef __linux__ -+ ui->bindToInterface->blockSignals(true); -+ - size_t count_iface = obs_property_list_item_count(p_iface); - for (size_t i = 0; i < count_iface; i++) { - const char *name = obs_property_list_item_name(p_iface, i); -@@ -844,7 +849,11 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - ui->bindToInterface->addItem(QT_UTF8(name), val); - } - } --#endif -+ -+ UpdateAddrList(); -+ ui->bindToInterface->blockSignals(false); -+#else -+ obs_property_t *p_addr = obs_properties_get(ppts, "bind_ip"); - - size_t count_addr = obs_property_list_item_count(p_addr); - for (size_t i = 0; i < count_addr; i++) { -@@ -853,7 +862,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - - ui->bindToIP->addItem(QT_UTF8(name), val); - } -- -+#endif - obs_properties_destroy(ppts); - - InitStreamPage(); -@@ -5217,3 +5226,36 @@ void OBSBasicSettings::RecreateOutputResolutionWidget() - ui->outputResolution->lineEdit()->setValidator( - ui->baseResolution->lineEdit()->validator()); } + +#ifdef __linux__ @@ -648,12 +500,12 @@ index c8712e6cb627..0509f1af00d9 100644 + + // Get Bind to IP Addresses (Linux only) + obs_properties_t *ppts = obs_get_output_properties("rtmp_output"); -+ obs_property_t *p_addr = obs_properties_get(ppts, "bind_ip"); ++ obs_property_t *p = obs_properties_get(ppts, "bind_ip"); + -+ size_t count_addr = obs_property_list_item_count(p_addr); ++ size_t count_addr = obs_property_list_item_count(p); + for (size_t i = 0; i < count_addr; i++) { -+ const char *name = obs_property_list_item_name(p_addr, i); -+ const char *val = obs_property_list_item_string(p_addr, i); ++ const char *name = obs_property_list_item_name(p, i); ++ const char *val = obs_property_list_item_string(p, i); + + //Put only the addresses from the selected interface + if (QT_UTF8(name).contains( @@ -674,12 +526,12 @@ index c8712e6cb627..0509f1af00d9 100644 +} +#endif diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp -index 4c66bc210d8c..6bc445d9306e 100644 +index 2431cb056241f..da6ed56ac369d 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp -@@ -409,6 +409,9 @@ private slots: - void SetVideoIcon(const QIcon &icon); +@@ -464,6 +464,9 @@ private slots: void SetHotkeysIcon(const QIcon &icon); + void SetAccessibilityIcon(const QIcon &icon); void SetAdvancedIcon(const QIcon &icon); +#ifdef __linux__ + void UpdateAddrList(); @@ -687,4 +539,3 @@ index 4c66bc210d8c..6bc445d9306e 100644 void UseStreamKeyAdvClicked(); - diff --git a/v4l2_by-path.patch b/v4l2_by-path.patch index 4fb112f13b8b..26fd180f2986 100644 --- a/v4l2_by-path.patch +++ b/v4l2_by-path.patch @@ -1,27 +1,75 @@ -From 57cc18a73a05e00338f2ece4adb88ef3c3b87db8 Mon Sep 17 00:00:00 2001 +From f19d4c3f3cd630f676d07e889e25e7c9250cfddc Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski <gg@gitgis.com> Date: Mon, 16 May 2022 18:29:16 +0200 Subject: [PATCH] linux-v4l2: Save device by id or path --- - plugins/linux-v4l2/v4l2-input.c | 127 ++++++++++++++++++++++---------- - 1 file changed, 90 insertions(+), 37 deletions(-) + plugins/linux-v4l2/v4l2-input.c | 208 +++++++++++++++++++++++--------- + 1 file changed, 151 insertions(+), 57 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c -index e9d6f1712bbb..95387ff0c11d 100644 +index 9b931ea88113..8e98ea469b46 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c -@@ -341,32 +341,27 @@ static void v4l2_props_set_enabled(obs_properties_t *props, - } +@@ -69,6 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. + struct v4l2_data { + /* settings */ + char *device_id; ++ char *real_path; + int input; + int pixfmt; + int standard; +@@ -344,37 +345,71 @@ static void v4l2_props_set_enabled(obs_properties_t *props, } --/* + /* - * List available devices -- */ ++ * Get capabilities of device + */ -static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) -+static void v4l2_device_list_directory(obs_property_t *prop, -+ const char *basedir, -+ bool allow_duplicates) ++static bool get_device_capabilities(char *dev_name, ++ struct v4l2_capability *video_cap) ++{ ++ int fd; ++ uint32_t caps; ++ if ((fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK)) == -1) { ++ const char *errstr = strerror(errno); ++ blog(LOG_WARNING, "Unable to open %s: %s", dev_name, errstr); ++ return false; ++ } ++ ++ if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, video_cap) == -1) { ++ blog(LOG_WARNING, "Failed to query capabilities for %s", ++ dev_name); ++ v4l2_close(fd); ++ return false; ++ } ++ v4l2_close(fd); ++ ++#ifndef V4L2_CAP_DEVICE_CAPS ++ caps = video_cap->capabilities; ++#else ++ /* ... since Linux 3.3 */ ++ caps = (video_cap->capabilities & V4L2_CAP_DEVICE_CAPS) ++ ? video_cap->device_caps ++ : video_cap->capabilities; ++#endif ++ ++ if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { ++ blog(LOG_WARNING, "%s seems to not support video capture", ++ dev_name); ++ return false; ++ } ++ ++ return true; ++} ++ ++/* ++ * Build list of video devices available at path ++ */ ++static void v4l2_device_add_devices_from(obs_property_t *prop, ++ const char *basedir, ++ bool allow_duplicates) { DIR *dirp; struct dirent *dp; @@ -53,66 +101,33 @@ index e9d6f1712bbb..95387ff0c11d 100644 + dstr_init(&device); while ((dp = readdir(dirp)) != NULL) { - int fd; -@@ -381,20 +376,30 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) +- int fd; +- uint32_t caps; +- struct v4l2_capability video_cap; +- + #ifdef __FreeBSD__ + if (strstr(dp->d_name, "video") == NULL) + continue; +@@ -383,51 +418,87 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) if (dp->d_type == DT_DIR) continue; - dstr_resize(&device, 5); -- dstr_cat(&device, dp->d_name); -+ char *dev_path = dp->d_name; -+ char buf[1024]; -+ ssize_t len; -+ if ((len = readlink(dp->d_name, buf, sizeof(buf) - 1)) != -1) { -+ buf[len] = '\0'; -+ dev_path = &buf[0]; -+ } + dstr_copy(&device, basedir); -+ dstr_cat(&device, dev_path); + dstr_cat(&device, dp->d_name); - if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) { +- if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) { - blog(LOG_INFO, "Unable to open %s", device.array); -+ const char *errstr = strerror(errno); -+ blog(LOG_WARNING, "Unable to open %s: %s", device.array, -+ errstr); ++ struct v4l2_capability video_cap; ++ if (!get_device_capabilities(device.array, &video_cap)) { continue; } - if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { +- if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { - blog(LOG_INFO, "Failed to query capabilities for %s", -+ blog(LOG_WARNING, "Failed to query capabilities for %s", - device.array); - v4l2_close(fd); - continue; - } -+ v4l2_close(fd); - - #ifndef V4L2_CAP_DEVICE_CAPS - caps = video_cap.capabilities; -@@ -406,26 +411,77 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) - #endif - - if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { -- blog(LOG_INFO, "%s seems to not support video capture", -+ blog(LOG_WARNING, -+ "%s seems to not support video capture", - device.array); +- device.array); - v4l2_close(fd); - continue; - } - -- /* make sure device names are unique */ -- char unique_device_name[68]; -- sprintf(unique_device_name, "%s (%s)", video_cap.card, -- video_cap.bus_info); -- obs_property_list_add_string(prop, unique_device_name, -- device.array); -- blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, -- device.array); -- -- /* check if this is the currently used device */ -- if (cur_device_name && !strcmp(cur_device_name, device.array)) -- cur_device_found = true; +- continue; + bool device_already_added = false; + + if (!allow_duplicates) { @@ -126,17 +141,20 @@ index e9d6f1712bbb..95387ff0c11d 100644 + break; + } + } -+ } + } -- v4l2_close(fd); +-#ifndef V4L2_CAP_DEVICE_CAPS +- caps = video_cap.capabilities; + if (!device_already_added) { -+ char unique_device_name[68]; ++ char unique_device_name[PATH_MAX]; + if (0 == strcmp("/dev/v4l/by-path/", basedir)) { -+ sprintf(unique_device_name, "%s (%s)", -+ video_cap.bus_info, video_cap.card); ++ snprintf(unique_device_name, PATH_MAX, ++ "Bus: %s (%s)", video_cap.bus_info, ++ video_cap.card); + } else { -+ sprintf(unique_device_name, "%s (%s)", -+ video_cap.card, video_cap.bus_info); ++ snprintf(unique_device_name, PATH_MAX, ++ "%s (%s)", video_cap.card, ++ video_cap.bus_info); + } + obs_property_list_add_string(prop, unique_device_name, + device.array); @@ -161,28 +179,57 @@ index e9d6f1712bbb..95387ff0c11d 100644 + obs_property_list_clear(prop); + +#ifdef __FreeBSD__ -+ v4l2_device_list_directory(prop, "/dev/", false); -+#else -+ v4l2_device_list_directory(prop, "/dev/v4l/by-id/", true); -+ v4l2_device_list_directory(prop, "/dev/v4l/by-path/", true); -+ v4l2_device_list_directory(prop, "/dev/", false); -+#endif -+ ++ v4l2_device_add_devices_from(prop, "/dev/", false); + #else +- /* ... since Linux 3.3 */ +- caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) +- ? video_cap.device_caps +- : video_cap.capabilities; ++ v4l2_device_add_devices_from(prop, "/dev/v4l/by-id/", true); ++ obs_property_list_item_disable( ++ prop, ++ obs_property_list_add_string( ++ prop, ++ "Advanced. Select device by connection:", "by_path"), ++ true); ++ v4l2_device_add_devices_from(prop, "/dev/v4l/by-path/", true); ++ v4l2_device_add_devices_from(prop, "/dev/", false); + #endif + +- if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { +- blog(LOG_INFO, "%s seems to not support video capture", +- device.array); +- v4l2_close(fd); +- continue; +- } + cur_device_found = false; + cur_device_name = obs_data_get_string(settings, "device_id"); -+ + +- /* make sure device names are unique */ +- char unique_device_name[68]; +- sprintf(unique_device_name, "%s (%s)", video_cap.card, +- video_cap.bus_info); +- obs_property_list_add_string(prop, unique_device_name, +- device.array); +- blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, +- device.array); +- +- /* check if this is the currently used device */ +- if (cur_device_name && !strcmp(cur_device_name, device.array)) + size_t listidx = 0; + const char *item_name; + while (NULL != + (item_name = obs_property_list_item_string(prop, listidx++))) { + if (0 == strcmp(item_name, cur_device_name)) { -+ cur_device_found = true; + cur_device_found = true; +- +- v4l2_close(fd); + break; + } } /* add currently selected device if not present, but disable it ... */ -@@ -434,9 +490,6 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) +@@ -436,9 +507,6 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) prop, cur_device_name, cur_device_name); obs_property_list_item_disable(prop, cur_device_index, true); } @@ -192,3 +239,77 @@ index e9d6f1712bbb..95387ff0c11d 100644 } /* +@@ -795,12 +863,19 @@ static void device_added(void *vptr, calldata_t *calldata) + const char *dev; + calldata_get_string(calldata, "device", &dev); + +- if (strcmp(data->device_id, dev)) ++ char *real_path = realpath(data->device_id, NULL); ++ ++ if (real_path == NULL) + return; ++ if (strcmp(real_path, dev)) ++ goto fail; + +- blog(LOG_INFO, "Device %s reconnected", dev); ++ blog(LOG_INFO, "Device %s reconnected, is opened as %s", dev, ++ data->device_id); + + v4l2_init(data); ++fail: ++ free(real_path); + } + /** + * Device removed callback +@@ -816,10 +891,13 @@ static void device_removed(void *vptr, calldata_t *calldata) + const char *dev; + calldata_get_string(calldata, "device", &dev); + +- if (strcmp(data->device_id, dev)) ++ if (data->real_path == NULL) ++ return; ++ if (strcmp(data->real_path, dev)) + return; + +- blog(LOG_INFO, "Device %s disconnected", dev); ++ blog(LOG_INFO, "Device %s disconnected, was opened as %s", dev, ++ data->device_id); + + v4l2_terminate(data); + } +@@ -965,12 +1043,23 @@ static void v4l2_init(struct v4l2_data *data) + int fps_num, fps_denom; + + blog(LOG_INFO, "Start capture from %s", data->device_id); ++ if (data->real_path) { ++ bfree(data->real_path); ++ data->real_path = NULL; ++ } + data->dev = v4l2_open(data->device_id, O_RDWR | O_NONBLOCK); + if (data->dev == -1) { + blog(LOG_ERROR, "Unable to open device"); + goto fail; + } + ++ char *real_path = realpath(data->device_id, NULL); ++ if (NULL != real_path) { ++ data->real_path = real_path; ++ } else { ++ data->real_path = bstrdup(data->device_id); ++ } ++ + /* set input */ + if (v4l2_set_input(data->dev, &data->input) < 0) { + blog(LOG_ERROR, "Unable to set input %d", data->input); +@@ -1135,6 +1224,11 @@ static void v4l2_update(void *vptr, obs_data_t *settings) + if (data->device_id) + bfree(data->device_id); + ++ if (data->real_path) { ++ bfree(data->real_path); ++ data->real_path = NULL; ++ } ++ + data->device_id = bstrdup(obs_data_get_string(settings, "device_id")); + data->input = obs_data_get_int(settings, "input"); + data->pixfmt = obs_data_get_int(settings, "pixelformat"); |