summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authortytan6522022-05-17 08:07:29 +0200
committertytan6522022-05-17 08:07:29 +0200
commitc100418efd1e43c98a7bba494aea23e8ef2b9040 (patch)
tree2ee65e4e73ac27074e0654828698cb403353789b
parent0bb678407428ef8e563591185299fe30313c0281 (diff)
downloadaur-c100418efd1e43c98a7bba494aea23e8ef2b9040.tar.gz
build: Update backports and v4l2 by path patch
-rw-r--r--.SRCINFO6
-rw-r--r--PKGBUILD13
-rw-r--r--ffmpeg_5_master_fixes.patch285
-rw-r--r--v4l2_by-path.patch185
4 files changed, 168 insertions, 321 deletions
diff --git a/.SRCINFO b/.SRCINFO
index c9600c33f758..d7edead50293 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,7 +1,7 @@
pkgbase = obs-studio-tytan652
pkgdesc = Free and open source software for video recording and live streaming. With Browser dock and sources, VST 2 filter, FTL protocol, VLC sources, V4L2 devices by paths, my bind interface PR, and sometimes backported fixes.
pkgver = 27.2.4
- pkgrel = 4
+ pkgrel = 5
url = https://github.com/obsproject/obs-studio
arch = i686
arch = x86_64
@@ -58,12 +58,10 @@ pkgbase = obs-studio-tytan652
source = v4l2_by-path.patch
source = obs-browser::git+https://github.com/obsproject/obs-browser.git
source = obs-vst::git+https://github.com/obsproject/obs-vst.git#commit=cca219fa3613dbc65de676ab7ba29e76865fa6f8
- source = ffmpeg_5_master_fixes.patch
sha256sums = SKIP
sha256sums = 4dc22cc6a71f879486946032debef5789b144d1d108a678379910480601937ca
- sha256sums = fb55dffcb177fd89c2cbffeb14aaf920dae2ae60dcfa934cff252315f268470e
+ sha256sums = e0cfe383286ae1b7e9a4f88ea0e8f05e79470bf677b16ac18bd2a64826c2ae28
sha256sums = SKIP
sha256sums = SKIP
- sha256sums = 91a08c02b397c49e84400f36559059f03c629b4d0df5b6689ce8eb6923c805f6
pkgname = obs-studio-tytan652
diff --git a/PKGBUILD b/PKGBUILD
index e24b41446fe5..7b7d5e440f19 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -4,7 +4,7 @@ DISTRIB_ID=`lsb_release --id | cut -f2 -d$'\t'`
pkgname=obs-studio-tytan652
pkgver=27.2.4
-pkgrel=4
+pkgrel=5
pkgdesc="Free and open source software for video recording and live streaming. With Browser dock and sources, VST 2 filter, FTL protocol, VLC sources, V4L2 devices by paths, my bind interface PR, and sometimes backported fixes."
arch=("i686" "x86_64" "aarch64")
url="https://github.com/obsproject/obs-studio"
@@ -89,15 +89,13 @@ source=(
"v4l2_by-path.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/3437.patch
"obs-browser::git+https://github.com/obsproject/obs-browser.git"
"obs-vst::git+https://github.com/obsproject/obs-vst.git#commit=cca219fa3613dbc65de676ab7ba29e76865fa6f8"
- "ffmpeg_5_master_fixes.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/6423.patch
)
sha256sums=(
"SKIP"
"4dc22cc6a71f879486946032debef5789b144d1d108a678379910480601937ca"
- "fb55dffcb177fd89c2cbffeb14aaf920dae2ae60dcfa934cff252315f268470e"
+ "e0cfe383286ae1b7e9a4f88ea0e8f05e79470bf677b16ac18bd2a64826c2ae28"
"SKIP"
"SKIP"
- "91a08c02b397c49e84400f36559059f03c629b4d0df5b6689ce8eb6923c805f6"
)
if [[ $DISTRIB_ID == 'ManjaroLinux' ]]; then
@@ -162,7 +160,12 @@ prepare() {
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)
- patch -Np1 < "$srcdir/ffmpeg_5_master_fixes.patch"
+ 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
## Add network interface binding for RTMP on Linux (https://github.com/obsproject/obs-studio/pull/4219)
patch -Np1 < "$srcdir/bind_iface.patch"
diff --git a/ffmpeg_5_master_fixes.patch b/ffmpeg_5_master_fixes.patch
deleted file mode 100644
index 90d089973a2f..000000000000
--- a/ffmpeg_5_master_fixes.patch
+++ /dev/null
@@ -1,285 +0,0 @@
-From 97bab7276c0ee14f797a171e34fb0913d680113c Mon Sep 17 00:00:00 2001
-From: pkv <pkv@obsproject.com>
-Date: Thu, 5 May 2022 14:56:21 +0200
-Subject: [PATCH 1/3] libobs: Fix missing include due toffmpeg 5 changes
-
-Since [1], avcodec/version.h is not included anymore in codec.h and
-therefore is not included any more in avformat.h.
-As a result, LIBAVCODEC_VERSION_INT is no longer defined. This commit
-fixes the include.
-Since obviously we can't ifdef the avcodec include by referring to an
-avcodec version, we ifdef it with the avformat version which was bumped
-at the same time [2].
-
-[1] libavcodec: Split version.h
-https://github.com/FFmpeg/FFmpeg/commit/f2da2e1458b76a1d6c068673430b46cf2850bc51
-[2] doc: Add an entry to APIchanges about changes to version.h and version_major.h
-https://github.com/FFmpeg/FFmpeg/commit/f3a0e2ee2b97e2d46b351c29853c056d126884e2
-
-Signed-off-by: pkv <pkv@obsproject.com>
----
- libobs/media-io/media-remux.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/libobs/media-io/media-remux.c b/libobs/media-io/media-remux.c
-index 2b39a74e2376..20eaea238f8b 100644
---- a/libobs/media-io/media-remux.c
-+++ b/libobs/media-io/media-remux.c
-@@ -22,7 +22,9 @@
- #include "../util/platform.h"
-
- #include <libavformat/avformat.h>
--
-+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(59, 20, 100)
-+#include <libavcodec/version.h>
-+#endif
- #include <sys/types.h>
- #include <sys/stat.h>
-
-
-From edc09d87f4c8de1d27eda2a06874c8ea1ebb00c4 Mon Sep 17 00:00:00 2001
-From: pkv <pkv@obsproject.com>
-Date: Thu, 5 May 2022 15:24:35 +0200
-Subject: [PATCH 2/3] obs-ffmpeg: Fix for channel layout API change in FFmpeg 5
-
-The channel_layout API was overhauled by FFmpeg [1-4]. The previous
-bitmask channel_layout is replaced by a struct ch_layout which combines
-the number of channels, a bitmask and other infos. This struct must now
-be supplied to AVframes since avutil >= 57.24.100 and to
-AVCodecContext since avcodec 59.24.100 per (1].
-This commit provides the required info to ffmpeg-mux,
-obs-ffmpeg-output & to obs-ffmpeg-audio-encoders.
-
-[1] Bump minor versions after the channel layout changes
-https://github.com/FFmpeg/FFmpeg/commit/cdba98bb80e2ab73d34659c610771b020afc6a77
-[2] lavc: switch to the new channel layout API
-https://github.com/FFmpeg/FFmpeg/commit/548aeb93834b8425c86d1ce60fddc1d41805724d
-[3] avutil/channel_layout: Add a new channel layout API
-https://github.com/FFmpeg/FFmpeg/commit/086a8048061bf9fb4c63943f6962db48175f655c
-[4] avframe: switch to the new channel layout API db6efa18
-https://github.com/FFmpeg/FFmpeg/commit/db6efa1815e217ed76f39aee8b15ee5c64698537
-
-Signed-off-by: pkv <pkv@obsproject.com>
----
- plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c | 7 +++
- .../obs-ffmpeg/obs-ffmpeg-audio-encoders.c | 58 +++++++++++++------
- plugins/obs-ffmpeg/obs-ffmpeg-output.c | 12 +++-
- 3 files changed, 56 insertions(+), 21 deletions(-)
-
-diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-index 5f569d6a94a3..211fc2070469 100644
---- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-+++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-@@ -495,6 +495,7 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx)
- context->time_base = stream->time_base;
- context->extradata = extradata;
- context->extradata_size = ffm->audio_header[idx].size;
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- context->channel_layout =
- av_get_default_channel_layout(context->channels);
- //avutil default channel layout for 4 channels is 4.0 ; fix for quad
-@@ -503,6 +504,12 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx)
- //avutil default channel layout for 5 channels is 5.0 ; fix for 4.1
- if (context->channels == 5)
- context->channel_layout = av_get_channel_layout("4.1");
-+#else
-+ av_channel_layout_default(&context->ch_layout, context->channels);
-+ //avutil default channel layout for 5 channels is 5.0 ; fix for 4.1
-+ if (context->channels == 5)
-+ context->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1;
-+#endif
- if (ffm->output->oformat->flags & AVFMT_GLOBALHEADER)
- context->flags |= CODEC_FLAG_GLOBAL_H;
-
-diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
-index fc9fe6bfb72b..e1e17147f451 100644
---- a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
-+++ b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
-@@ -57,6 +57,7 @@ struct enc_encoder {
- int frame_size_bytes;
- };
-
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- static inline uint64_t convert_speaker_layout(enum speaker_layout layout)
- {
- switch (layout) {
-@@ -81,29 +82,29 @@ static inline uint64_t convert_speaker_layout(enum speaker_layout layout)
- /* shouldn't get here */
- return 0;
- }
--
--static inline enum speaker_layout
--convert_ff_channel_layout(uint64_t channel_layout)
-+#endif
-+static inline enum speaker_layout convert_to_speaker_layout(uint8_t channels)
- {
-- switch (channel_layout) {
-- case AV_CH_LAYOUT_MONO:
-+ switch (channels) {
-+ case 0:
-+ return SPEAKERS_UNKNOWN;
-+ case 1:
- return SPEAKERS_MONO;
-- case AV_CH_LAYOUT_STEREO:
-+ case 2:
- return SPEAKERS_STEREO;
-- case AV_CH_LAYOUT_SURROUND:
-+ case 3:
- return SPEAKERS_2POINT1;
-- case AV_CH_LAYOUT_4POINT0:
-+ case 4:
- return SPEAKERS_4POINT0;
-- case AV_CH_LAYOUT_4POINT1:
-+ case 5:
- return SPEAKERS_4POINT1;
-- case AV_CH_LAYOUT_5POINT1_BACK:
-+ case 6:
- return SPEAKERS_5POINT1;
-- case AV_CH_LAYOUT_7POINT1:
-+ case 8:
- return SPEAKERS_7POINT1;
-+ default:
-+ return SPEAKERS_UNKNOWN;
- }
--
-- /* shouldn't get here */
-- return SPEAKERS_UNKNOWN;
- }
-
- static const char *aac_getname(void *unused)
-@@ -157,7 +158,11 @@ static bool initialize_codec(struct enc_encoder *enc)
- }
- enc->aframe->format = enc->context->sample_fmt;
- enc->aframe->channels = enc->context->channels;
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- enc->aframe->channel_layout = enc->context->channel_layout;
-+#else
-+ enc->aframe->ch_layout = enc->context->ch_layout;
-+#endif
- enc->aframe->sample_rate = enc->context->sample_rate;
-
- enc->frame_size = enc->context->frame_size;
-@@ -235,7 +240,15 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder,
- const struct audio_output_info *aoi;
- aoi = audio_output_get_info(audio);
- enc->context->channels = (int)audio_output_get_channels(audio);
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- enc->context->channel_layout = convert_speaker_layout(aoi->speakers);
-+#else
-+ av_channel_layout_default(&enc->context->ch_layout,
-+ enc->context->channels);
-+ if (aoi->speakers == SPEAKERS_4POINT1)
-+ enc->context->ch_layout =
-+ (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1;
-+#endif
- enc->context->sample_rate = audio_output_get_sample_rate(audio);
- enc->context->sample_fmt = enc->codec->sample_fmts
- ? enc->codec->sample_fmts[0]
-@@ -263,12 +276,18 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder,
- if (strcmp(enc->codec->name, "aac") == 0) {
- av_opt_set(enc->context->priv_data, "aac_coder", "fast", 0);
- }
--
-+ char buf[256];
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- info("bitrate: %" PRId64 ", channels: %d, channel_layout: %x\n",
- (int64_t)enc->context->bit_rate / 1000,
- (int)enc->context->channels,
- (unsigned int)enc->context->channel_layout);
--
-+#else
-+ av_channel_layout_describe(&enc->context->ch_layout, buf, 256);
-+ info("bitrate: %" PRId64 ", channels: %d, channel_layout: %s\n",
-+ (int64_t)enc->context->bit_rate / 1000,
-+ (int)enc->context->channels, buf);
-+#endif
- init_sizes(enc, audio);
-
- /* enable experimental FFmpeg encoder if the only one available */
-@@ -306,7 +325,9 @@ static bool do_encode(struct enc_encoder *enc, struct encoder_packet *packet,
- enc->aframe->pts = av_rescale_q(
- enc->total_samples, (AVRational){1, enc->context->sample_rate},
- enc->context->time_base);
--
-+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
-+ enc->aframe->ch_layout = enc->context->ch_layout;
-+#endif
- ret = avcodec_fill_audio_frame(
- enc->aframe, enc->context->channels, enc->context->sample_fmt,
- enc->samples[0], enc->frame_size_bytes * enc->context->channels,
-@@ -394,8 +415,7 @@ static void enc_audio_info(void *data, struct audio_convert_info *info)
- struct enc_encoder *enc = data;
- info->format = convert_ffmpeg_sample_format(enc->context->sample_fmt);
- info->samples_per_sec = (uint32_t)enc->context->sample_rate;
-- info->speakers =
-- convert_ff_channel_layout(enc->context->channel_layout);
-+ info->speakers = convert_to_speaker_layout(enc->context->channels);
- }
-
- static size_t enc_frame_size(void *data)
-diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
-index e0cc169d5e3c..61fe6e2b777d 100644
---- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c
-+++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
-@@ -321,9 +321,12 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx)
-
- data->aframe[idx]->format = context->sample_fmt;
- data->aframe[idx]->channels = context->channels;
-+#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 24, 100)
- data->aframe[idx]->channel_layout = context->channel_layout;
-+#else
-+ data->aframe[idx]->ch_layout = context->ch_layout;
-+#endif
- data->aframe[idx]->sample_rate = context->sample_rate;
--
- context->strict_std_compliance = -2;
-
- ret = avcodec_open2(context, data->acodec, NULL);
-@@ -378,13 +381,18 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
- context->time_base = (AVRational){1, aoi.samples_per_sec};
- context->channels = get_audio_channels(aoi.speakers);
- context->sample_rate = aoi.samples_per_sec;
-+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- context->channel_layout =
- av_get_default_channel_layout(context->channels);
-
- //avutil default channel layout for 5 channels is 5.0 ; fix for 4.1
- if (aoi.speakers == SPEAKERS_4POINT1)
- context->channel_layout = av_get_channel_layout("4.1");
--
-+#else
-+ av_channel_layout_default(&context->ch_layout, context->channels);
-+ if (aoi.speakers == SPEAKERS_4POINT1)
-+ context->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1;
-+#endif
- context->sample_fmt = data->acodec->sample_fmts
- ? data->acodec->sample_fmts[0]
- : AV_SAMPLE_FMT_FLTP;
-
-From 25b0d2f410597f54111a65276ba05b855a4e1b6f Mon Sep 17 00:00:00 2001
-From: pkv <pkv@obsproject.com>
-Date: Thu, 5 May 2022 20:12:44 +0200
-Subject: [PATCH 3/3] obs-ffmpeg: Fix 4 channel layout in ffmpeg-mux
-
-Previously SPEAKER_4POINT0 was assigned to AV_CH_LAYOUT_QUAD, but later was changed to AV_CH_LAYOUT_4POINT0 [1]. The change was forgotten in obs-ffmpeg-mux. This is remedied here.
-[1] https://github.com/obsproject/obs-studio/commit/67e48ecc2ca033020210f3aae05617195d37e248
-
-Signed-off-by: pkv <pkv@obsproject.com>
----
- plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c | 3 ---
- 1 file changed, 3 deletions(-)
-
-diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-index 211fc2070469..359582d6436e 100644
---- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-+++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
-@@ -498,9 +498,6 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx)
- #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
- context->channel_layout =
- av_get_default_channel_layout(context->channels);
-- //avutil default channel layout for 4 channels is 4.0 ; fix for quad
-- if (context->channels == 4)
-- context->channel_layout = av_get_channel_layout("quad");
- //avutil default channel layout for 5 channels is 5.0 ; fix for 4.1
- if (context->channels == 5)
- context->channel_layout = av_get_channel_layout("4.1");
diff --git a/v4l2_by-path.patch b/v4l2_by-path.patch
index b98225e95a14..4fb112f13b8b 100644
--- a/v4l2_by-path.patch
+++ b/v4l2_by-path.patch
@@ -1,55 +1,66 @@
-From 0f3bd8ba93673f8888fdf12b155a9a022de222cc Mon Sep 17 00:00:00 2001
-From: Kurt Kartaltepe <kkartaltepe@gmail.com>
-Date: Tue, 8 Sep 2020 18:52:27 -0700
-Subject: [PATCH] linux-v4l2: Save device by path
+From 57cc18a73a05e00338f2ece4adb88ef3c3b87db8 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
-This adjusts device listing to be by /dev/v4l/by-path which is based
-on where the device is plugged in instead of when it is initialized.
-This should help people with multiple devices across restarts.
-
-Old plugin data will still work unchanged, when users modify settings
-the new options will be transparently backed by the new keys but names
-presented remain consistent.
---
- plugins/linux-v4l2/v4l2-input.c | 20 +++++++++++++++-----
- 1 file changed, 15 insertions(+), 5 deletions(-)
+ plugins/linux-v4l2/v4l2-input.c | 127 ++++++++++++++++++++++----------
+ 1 file changed, 90 insertions(+), 37 deletions(-)
diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c
-index fe98a8bf8eb..1baab424be4 100644
+index e9d6f1712bbb..95387ff0c11d 100644
--- a/plugins/linux-v4l2/v4l2-input.c
+++ b/plugins/linux-v4l2/v4l2-input.c
-@@ -276,10 +276,12 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings)
- const char *cur_device_name;
+@@ -341,32 +341,27 @@ static void v4l2_props_set_enabled(obs_properties_t *props,
+ }
+ }
+
+-/*
+- * List available devices
+- */
+-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)
+ {
+ DIR *dirp;
+ struct dirent *dp;
+ struct dstr device;
+- bool cur_device_found;
+- size_t cur_device_index;
+- const char *cur_device_name;
#ifdef __FreeBSD__
- dirp = opendir("/dev");
-+ const char *basedir = "/dev/";
++ dirp = opendir(basedir);
#else
- dirp = opendir("/sys/class/video4linux");
-+ const char *basedir = "/dev/v4l/by-path/";
++ if (0 == strcmp("/dev/", basedir)) {
++ dirp = opendir("/sys/class/video4linux");
++ } else {
++ dirp = opendir(basedir);
++ }
#endif
-+
-+ dirp = opendir(basedir);
if (!dirp)
return;
-@@ -288,7 +290,7 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings)
-
- obs_property_list_clear(prop);
-
+- cur_device_found = false;
+- cur_device_name = obs_data_get_string(settings, "device_id");
+-
+- obs_property_list_clear(prop);
+-
- dstr_init_copy(&device, "/dev/");
+ dstr_init(&device);
while ((dp = readdir(dirp)) != NULL) {
int fd;
-@@ -303,8 +305,16 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings)
+@@ -381,20 +376,30 @@ 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) {
@@ -60,4 +71,124 @@ index fe98a8bf8eb..1baab424be4 100644
+ dstr_cat(&device, dev_path);
if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) {
- blog(LOG_INFO, "Unable to open %s", device.array);
+- 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);
+ continue;
+ }
+
+ 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);
+- 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;
++ bool device_already_added = false;
++
++ if (!allow_duplicates) {
++ size_t listidx = 0;
++ const char *item_name;
++ while (NULL != (item_name = obs_property_list_item_name(
++ prop, listidx++))) {
++ if (NULL !=
++ strstr(item_name, video_cap.bus_info)) {
++ device_already_added = true;
++ break;
++ }
++ }
++ }
+
+- v4l2_close(fd);
++ if (!device_already_added) {
++ char unique_device_name[68];
++ if (0 == strcmp("/dev/v4l/by-path/", basedir)) {
++ sprintf(unique_device_name, "%s (%s)",
++ video_cap.bus_info, video_cap.card);
++ } else {
++ 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);
++ }
++ }
++
++ closedir(dirp);
++ dstr_free(&device);
++}
++
++/*
++ * List available devices
++ */
++static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings)
++{
++ bool cur_device_found;
++ size_t cur_device_index;
++ const char *cur_device_name;
++
++ 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
++
++ cur_device_found = false;
++ cur_device_name = obs_data_get_string(settings, "device_id");
++
++ 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;
++ 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)
+ prop, cur_device_name, cur_device_name);
+ obs_property_list_item_disable(prop, cur_device_index, true);
+ }
+-
+- closedir(dirp);
+- dstr_free(&device);
+ }
+
+ /*