Skip to content

Commit

Permalink
Merge pull request #993 from haakonnessjoen/feat/disconnect-behavior
Browse files Browse the repository at this point in the history
Source: add support for auto-disconnecting NDI connection
  • Loading branch information
paulpv authored May 10, 2024
2 parents 98e309b + 96649d0 commit 4177d8b
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 3 deletions.
4 changes: 4 additions & 0 deletions data/locale/ca-ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Per defecte"
NDIPlugin.NDISourceName="Orígen NDI™"
NDIPlugin.SourceProps.SourceName="Nom de l'origen"
NDIPlugin.SourceProps.Bandwidth="Ample de banda"
NDIPlugin.SourceProps.Behavior="Comportament"
NDIPlugin.SourceProps.Behavior.Keep="Mantenir l'origen connectat"
NDIPlugin.SourceProps.Behavior.Disconnect="Desconnectar l'origen quan no estigui visible"
NDIPlugin.SourceProps.BehaviorLastFrame="Mantenir l'últim fotograma"
NDIPlugin.SourceProps.HWAccel="Permet l'acceleració del maquinari"
NDIPlugin.SourceProps.AlphaBlendingFix="Soluciona la barreja alfa (afegeix un filtre a aquesta font)"
NDIPlugin.SourceProps.ColorRange="Rang YUV"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/de-DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Standard"
NDIPlugin.NDISourceName="NDI™-Quelle"
NDIPlugin.SourceProps.SourceName="Quellname"
NDIPlugin.SourceProps.Bandwidth="Bandbreite"
NDIPlugin.SourceProps.Behavior="Verhalten"
NDIPlugin.SourceProps.Behavior.Keep="Quelle verbunden lassen"
NDIPlugin.SourceProps.Behavior.Disconnect="Quelle trennen, wenn nicht sichtbar"
NDIPlugin.SourceProps.BehaviorLastFrame="Letztes Frame beibehalten, wenn Quelle getrennt ist"
NDIPlugin.SourceProps.Sync="Audio-/Videosynchronisation"
NDIPlugin.NDIFrameSync="Framesync (Experimentell)"
NDIPlugin.SourceProps.HWAccel="Hardwarebeschleunigung zulassen"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Default"
NDIPlugin.NDISourceName="NDI™ Source"
NDIPlugin.SourceProps.SourceName="Source name"
NDIPlugin.SourceProps.Bandwidth="Bandwidth"
NDIPlugin.SourceProps.Behavior="Behavior"
NDIPlugin.SourceProps.Behavior.Keep="Keep source connected"
NDIPlugin.SourceProps.Behavior.Disconnect="Disconnect source when not visible"
NDIPlugin.SourceProps.BehaviorLastFrame="Keep last frame when disconnected"
NDIPlugin.SourceProps.Sync="Audio/Video Sync"
NDIPlugin.NDIFrameSync="Framesync (experimental)"
NDIPlugin.SourceProps.HWAccel="Allow hardware acceleration"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/es-ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Por defecto"
NDIPlugin.NDISourceName="Fuente NDI™"
NDIPlugin.SourceProps.SourceName="Nombre de la fuente"
NDIPlugin.SourceProps.Bandwidth="Ancho de banda"
NDIPlugin.SourceProps.Behavior="Comportamiento"
NDIPlugin.SourceProps.Behavior.Keep="Mantener fuente conectada"
NDIPlugin.SourceProps.Behavior.Disconnect="Desconectar fuente cuando no esté visible"
NDIPlugin.SourceProps.BehaviorLastFrame="Mantener último fotograma, cuando la fuente está desconectada"
NDIPlugin.SourceProps.HWAccel="Habilitar aceleración por hardware"
NDIPlugin.SourceProps.AlphaBlendingFix="Solucionar mezcla alfa (añade un filtro a esta fuente)"
NDIPlugin.SourceProps.ColorRange="Rango YUV"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/fr-FR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Par défaut"
NDIPlugin.NDISourceName="Source NDI™"
NDIPlugin.SourceProps.SourceName="Source"
NDIPlugin.SourceProps.Bandwidth="Bandwidth"
NDIPlugin.SourceProps.Behavior="Comportement"
NDIPlugin.SourceProps.Behavior.Keep="Conserver la source connectée"
NDIPlugin.SourceProps.Behavior.Disconnect="Déconnecter la source si non visible"
NDIPlugin.SourceProps.BehaviorLastFrame="Conserver le dernier cadre, si la source est déconnectée"
NDIPlugin.SourceProps.HWAccel="Autoriser l'accélération matérielle"
NDIPlugin.SourceProps.AlphaBlendingFix="Correction de simulation de transparence (ajoute un filtre à la source)"
NDIPlugin.SourceProps.ColorRange="Gamme de couleurs YUV"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/ko-KR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="기본값"
NDIPlugin.NDISourceName="NDI™ 소스"
NDIPlugin.SourceProps.SourceName="소스이름"
NDIPlugin.SourceProps.Bandwidth="대역폭"
NDIPlugin.SourceProps.Behavior="동작"
NDIPlugin.SourceProps.Behavior.Keep="소스 연결 유지"
NDIPlugin.SourceProps.Behavior.Disconnect="소스가 보이지 않을 때 연결 해제"
NDIPlugin.SourceProps.BehaviorLastFrame="소스 연결 해제 시 마지막 프레임 유지"
NDIPlugin.SourceProps.HWAccel="하드웨어 가속 사용"
NDIPlugin.SourceProps.AlphaBlendingFix="알파블랜딩 수정 (소스에 필터 추가)"
NDIPlugin.SourceProps.ColorRange="YUV 범위"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/ro-RO.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="Implicit"
NDIPlugin.NDISourceName="Sursă NDI™"
NDIPlugin.SourceProps.SourceName="Numele sursei"
NDIPlugin.SourceProps.Bandwidth="Lățimea de bandă"
NDIPlugin.SourceProps.Behavior="Comportament"
NDIPlugin.SourceProps.Behavior.Keep="Păstrează sursa conectată"
NDIPlugin.SourceProps.Behavior.Disconnect="Deconectează sursa când nu este vizibilă"
NDIPlugin.SourceProps.BehaviorLastFrame="Păstrează ultimul cadru când sursa este deconectată"
NDIPlugin.SourceProps.HWAccel="Permite accelerarea hardware"
NDIPlugin.SourceProps.AlphaBlendingFix="Corectează amestecul alfa (adaugă un filtru la această sursă)"
NDIPlugin.SourceProps.ColorRange="Gama YUV"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/ru-RU.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="По умолчанию"
NDIPlugin.NDISourceName="NDI™ источник"
NDIPlugin.SourceProps.SourceName="Названия источника"
NDIPlugin.SourceProps.Bandwidth="Пропускная способность"
NDIPlugin.SourceProps.Behavior="Поведение"
NDIPlugin.SourceProps.Behavior.Keep="Оставить источник подключенным"
NDIPlugin.SourceProps.Behavior.Disconnect="Отключить источник, когда он не виден"
NDIPlugin.SourceProps.BehaviorLastFrame="Сохранить последний кадр при отключении"
NDIPlugin.SourceProps.HWAccel="Разрешить аппаратное ускорение"
NDIPlugin.SourceProps.Latency="Режим задержки"
NDIPlugin.SourceProps.Latency.Normal="Обычный (безопасно)"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/uk-UA.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ NDIPlugin.Default="За замовчуванням"
NDIPlugin.NDISourceName="NDI™ джерело"
NDIPlugin.SourceProps.SourceName="Назва джерела"
NDIPlugin.SourceProps.Bandwidth="Пропускна здатність"
NDIPlugin.SourceProps.Behavior="Поведінка"
NDIPlugin.SourceProps.Behavior.Keep="Залишити джерело підключеним"
NDIPlugin.SourceProps.Behavior.Disconnect="Відключити джерело, коли воно не видно"
NDIPlugin.SourceProps.BehaviorLastFrame="Зберегти останню кадрову картинку при відключенні"
NDIPlugin.SourceProps.HWAccel="Дозволити апаратне прискорення"
NDIPlugin.SourceProps.AlphaBlendingFix="Виправлення альфа-змішування (додає фільтр до цього джерела)"
NDIPlugin.SourceProps.ColorRange="Діапазон YUV"
Expand Down
4 changes: 4 additions & 0 deletions data/locale/zh-CN.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
NDIPlugin.NDISourceName="NDI™ 来源"
NDIPlugin.SourceProps.SourceName="来源名称"
NDIPlugin.SourceProps.Bandwidth="带宽"
NDIPlugin.SourceProps.Behavior="行为"
NDIPlugin.SourceProps.Behavior.Keep="保持源连接"
NDIPlugin.SourceProps.Behavior.Disconnect="当源不可见时断开连接"
NDIPlugin.SourceProps.BehaviorLastFrame="断开连接时保留最后一帧"
NDIPlugin.SourceProps.HWAccel="允许硬件加速"
NDIPlugin.SourceProps.AlphaBlendingFix="修复 alpha 混合 (向此来源添加筛选器)"
NDIPlugin.SourceProps.ColorRange="YUV 范围"
Expand Down
67 changes: 64 additions & 3 deletions src/obs-ndi-source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>

#define PROP_SOURCE "ndi_source_name"
#define PROP_BANDWIDTH "ndi_bw_mode"
#define PROP_BEHAVIOR "ndi_behavior"
#define PROP_BEHAVIOR_LASTFRAME "ndi_behavior_lastframe"
#define PROP_SYNC "ndi_sync"
#define PROP_FRAMESYNC "ndi_framesync"
#define PROP_HW_ACCEL "ndi_recv_hw_accel"
Expand All @@ -51,6 +53,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#define PROP_BW_LOWEST 1
#define PROP_BW_AUDIO_ONLY 2

#define PROP_BEHAVIOR_DISCONNECT "disconnect"
#define PROP_BEHAVIOR_KEEP "keep"

// sync mode "Internal" got removed
#define PROP_SYNC_INTERNAL 0
#define PROP_SYNC_NDI_TIMESTAMP 1
Expand All @@ -67,6 +72,11 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#define PROP_LATENCY_LOW 1
#define PROP_LATENCY_LOWEST 2

enum behavior_type {
BEHAVIOR_DISCONNECT,
BEHAVIOR_KEEP,
};

extern NDIlib_find_instance_t ndi_finder;

typedef struct {
Expand All @@ -80,6 +90,8 @@ typedef struct {
QByteArray ndi_receiver_name;
QByteArray ndi_source_name;
int bandwidth;
enum behavior_type behavior;
bool remember_last_frame;
int sync_mode;
bool framesync_enabled;
bool hw_accel_enabled;
Expand All @@ -89,6 +101,7 @@ typedef struct {
bool audio_enabled;
ptz_t ptz;
NDIlib_tally_t tally;
obs_source_frame *blank_frame;
} ndi_source_config_t;

typedef struct {
Expand Down Expand Up @@ -213,6 +226,22 @@ obs_properties_t *ndi_source_getproperties(void *)
sources[i].p_ndi_name);
}

obs_property_t *p = obs_properties_add_list(
props, PROP_BEHAVIOR,
obs_module_text("NDIPlugin.SourceProps.Behavior"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);

obs_property_list_add_string(
p, obs_module_text("NDIPlugin.SourceProps.Behavior.Keep"),
PROP_BEHAVIOR_KEEP);
obs_property_list_add_string(
p, obs_module_text("NDIPlugin.SourceProps.Behavior.Disconnect"),
PROP_BEHAVIOR_DISCONNECT);

obs_properties_add_bool(
props, PROP_BEHAVIOR_LASTFRAME,
obs_module_text("NDIPlugin.SourceProps.BehaviorLastFrame"));

obs_property_t *bw_modes = obs_properties_add_list(
props, PROP_BANDWIDTH,
obs_module_text("NDIPlugin.SourceProps.Bandwidth"),
Expand Down Expand Up @@ -361,6 +390,9 @@ obs_properties_t *ndi_source_getproperties(void *)
void ndi_source_getdefaults(obs_data_t *settings)
{
obs_data_set_default_int(settings, PROP_BANDWIDTH, PROP_BW_HIGHEST);
obs_data_set_default_string(settings, PROP_BEHAVIOR,
PROP_BEHAVIOR_KEEP);
obs_data_set_default_bool(settings, PROP_BEHAVIOR_LASTFRAME, true);
obs_data_set_default_int(settings, PROP_SYNC,
PROP_SYNC_NDI_SOURCE_TIMECODE);
obs_data_set_default_int(settings, PROP_YUV_RANGE,
Expand Down Expand Up @@ -479,8 +511,9 @@ void *ndi_source_thread(void *data)
case PROP_BW_AUDIO_ONLY:
recv_desc.bandwidth =
NDIlib_recv_bandwidth_audio_only;
obs_source_output_video(obs_source,
blank_video_frame());
obs_source_output_video(
obs_source,
config_most_recent.blank_frame);
break;
}
blog(LOG_INFO,
Expand Down Expand Up @@ -897,6 +930,10 @@ void ndi_source_thread_stop(ndi_source_t *s)
if (s->running) {
s->running = false;
pthread_join(s->av_thread, NULL);
if (!s->config.remember_last_frame) {
obs_source_output_video(s->obs_source,
s->config.blank_frame);
}
}
}

Expand All @@ -912,6 +949,16 @@ void ndi_source_update(void *data, obs_data_t *settings)
config.ndi_source_name = obs_data_get_string(settings, PROP_SOURCE);
config.bandwidth = (int)obs_data_get_int(settings, PROP_BANDWIDTH);

const char *behavior = obs_data_get_string(settings, PROP_BEHAVIOR);
if (strcmp(behavior, PROP_BEHAVIOR_DISCONNECT) == 0) {
config.behavior = BEHAVIOR_DISCONNECT;
} else {
config.behavior = BEHAVIOR_KEEP;
}

config.remember_last_frame =
obs_data_get_bool(settings, PROP_BEHAVIOR_LASTFRAME);

config.sync_mode = (int)obs_data_get_int(settings, PROP_SYNC);
// if sync mode is set to the unsupported "Internal" mode, set it
// to "Source Timing" mode and apply that change to the settings data
Expand Down Expand Up @@ -971,7 +1018,8 @@ void ndi_source_update(void *data, obs_data_t *settings)
s->config = config;

if (!config.ndi_source_name.isEmpty()) {
if (!s->running) {
if (!s->running && (config.behavior == BEHAVIOR_KEEP ||
obs_source_active(obs_source))) {
ndi_source_thread_start(s);
}
} else {
Expand Down Expand Up @@ -1003,6 +1051,10 @@ void ndi_source_activated(void *data)
auto name = obs_source_get_name(s->obs_source);
blog(LOG_INFO, "[obs-ndi] ndi_source_activated('%s'...)", name);
s->config.tally.on_program = (Config::Current())->TallyProgramEnabled;

if (!s->running) {
ndi_source_thread_start(s);
}
}

void ndi_source_deactivated(void *data)
Expand All @@ -1011,6 +1063,10 @@ void ndi_source_deactivated(void *data)
auto name = obs_source_get_name(s->obs_source);
blog(LOG_INFO, "[obs-ndi] ndi_source_deactivated('%s'...)", name);
s->config.tally.on_program = false;

if (s->config.behavior == BEHAVIOR_DISCONNECT && s->running) {
ndi_source_thread_stop(s);
}
}

void ndi_source_renamed(void *data, calldata_t *)
Expand All @@ -1032,6 +1088,9 @@ void *ndi_source_create(obs_data_t *settings, obs_source_t *obs_source)
s->config.ndi_receiver_name =
QString("OBS-NDI '%1'").arg(name).toUtf8();

// Allocate blank video frame
s->config.blank_frame = blank_video_frame();

auto sh = obs_source_get_signal_handler(s->obs_source);
signal_handler_connect(sh, "rename", ndi_source_renamed, s);

Expand All @@ -1053,6 +1112,8 @@ void ndi_source_destroy(void *data)

ndi_source_thread_stop(s);

obs_source_frame_destroy(s->config.blank_frame);

bfree(s);

blog(LOG_INFO, "[obs-ndi] -ndi_source_destroy('%s'...)", name);
Expand Down

0 comments on commit 4177d8b

Please sign in to comment.