New upstream version 25.0.8+dfsg1

This commit is contained in:
Sebastian Ramacher 2020-05-27 22:57:19 +02:00
parent 8b2e5f2130
commit 8e020cdacb
115 changed files with 1767 additions and 10949 deletions

View file

@ -46,6 +46,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
add_subdirectory(linux-pulseaudio)
add_subdirectory(linux-v4l2)
add_subdirectory(linux-jack)
add_subdirectory(linux-alsa)
endif()
option(BUILD_BROWSER "Build browser plugin" OFF)

View file

@ -4,6 +4,10 @@ set(coreaudio-encoder_SOURCES
encoder.cpp)
if (WIN32)
set(MODULE_DESCRIPTION "OBS Core Audio encoder")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in coreaudio-encoder.rc)
list(APPEND coreaudio-encoder_SOURCES
coreaudio-encoder.rc)
set(coreaudio-encoder_HEADERS windows-imports.h)
set(coreaudio-encoder_LIBS )

View file

@ -60,6 +60,9 @@ static bool decklink_output_start(void *data)
device.Set(deviceEnum->FindByHash(decklink->deviceHash));
if (!device)
return false;
DeckLinkDeviceMode *mode = device->FindOutputMode(decklink->modeID);
decklink->SetSize(mode->GetWidth(), mode->GetHeight());

View file

@ -31,6 +31,8 @@ set(win-decklink_HEADERS
../util.hpp
)
set(MODULE_DESCRIPTION "OBS DeckLink Windows module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in win-decklink.rc)
set(win-decklink_SOURCES
../plugin-main.cpp
../decklink-devices.cpp
@ -46,7 +48,7 @@ set(win-decklink_SOURCES
../audio-repack.c
platform.cpp
../util.cpp
)
win-decklink.rc)
add_idl_files(win-decklink-sdk_GENERATED_FILES
${win-decklink-sdk_IDLS}

View file

@ -10,6 +10,13 @@ set(image-source_SOURCES
color-source.c
obs-slideshow.c)
if(WIN32)
set(MODULE_DESCRIPTION "OBS image module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in image-source.rc)
list(APPEND image-source_SOURCES
image-source.rc)
endif()
add_library(image-source MODULE
${image-source_SOURCES})
target_link_libraries(image-source

View file

@ -43,6 +43,8 @@ static enum speaker_layout jack_channels_to_obs_speakers(uint_fast32_t channels)
return SPEAKERS_STEREO;
case 3:
return SPEAKERS_2POINT1;
case 4:
return SPEAKERS_4POINT0;
case 5:
return SPEAKERS_4POINT1;
case 6:

View file

@ -95,7 +95,7 @@ static inline bool valid_control(struct v4l2_queryctrl *qctrl)
return (qctrl->flags & INVALID_CONTROL_FLAGS) == 0;
}
static inline bool add_control_property(obs_properties_t *props,
static inline void add_control_property(obs_properties_t *props,
obs_data_t *settings, int_fast32_t dev,
struct v4l2_queryctrl *qctrl)
{

View file

@ -6,6 +6,7 @@
struct cocoa_window {
CGWindowID window_id;
int owner_pid;
pthread_mutex_t name_lock;
NSString *owner_name;

View file

@ -60,8 +60,11 @@ bool find_window(cocoa_window_t cw, obs_data_t *settings, bool force)
NSNumber *window_id = (NSNumber *)dict[WINDOW_NUMBER];
cw->window_id = window_id.intValue;
NSNumber *owner_pid = (NSNumber *)dict[OWNER_PID];
cw->owner_pid = owner_pid.intValue;
obs_data_set_int(settings, "window", cw->window_id);
obs_data_set_int(settings, "owner_pid", cw->owner_pid);
return true;
}
@ -78,7 +81,41 @@ void init_window(cocoa_window_t cw, obs_data_t *settings)
cw->window_name = @(obs_data_get_string(settings, "window_name"));
[cw->owner_name retain];
[cw->window_name retain];
find_window(cw, settings, true);
// Find initial window.
pthread_mutex_lock(&cw->name_lock);
if (!cw->window_name.length && !cw->owner_name.length)
goto invalid_name;
NSNumber *owner_pid = @(obs_data_get_int(settings, "owner_pid"));
NSNumber *window_id = @(obs_data_get_int(settings, "window"));
for (NSDictionary *dict in enumerate_windows()) {
bool owner_names_match =
[cw->owner_name isEqualToString:dict[OWNER_NAME]];
bool ids_match =
[owner_pid isEqualToNumber:dict[OWNER_PID]] &&
[window_id isEqualToNumber:dict[WINDOW_NUMBER]];
bool window_names_match =
[cw->window_name isEqualToString:dict[WINDOW_NAME]];
if (owner_names_match && (ids_match || window_names_match)) {
pthread_mutex_unlock(&cw->name_lock);
NSNumber *window_id = (NSNumber *)dict[WINDOW_NUMBER];
cw->window_id = window_id.intValue;
NSNumber *owner_pid = (NSNumber *)dict[OWNER_PID];
cw->owner_pid = owner_pid.intValue;
obs_data_set_int(settings, "window", cw->window_id);
obs_data_set_int(settings, "owner_pid", cw->owner_pid);
return;
}
}
invalid_name:
pthread_mutex_unlock(&cw->name_lock);
return;
}
void destroy_window(cocoa_window_t cw)
@ -99,6 +136,7 @@ void update_window(cocoa_window_t cw, obs_data_t *settings)
[cw->window_name retain];
pthread_mutex_unlock(&cw->name_lock);
cw->owner_pid = obs_data_get_int(settings, "owner_pid");
cw->window_id = obs_data_get_int(settings, "window");
}

View file

@ -55,6 +55,9 @@ set(syphon_SOURCES
syphon-framework/SyphonServerDirectory.m
)
add_library(syphon-framework ${syphon_HEADERS}
${syphon_SOURCES})
set(mac-syphon_HEADERS
)
@ -70,15 +73,17 @@ add_definitions(-DSYPHON_UNIQUE_CLASS_NAME_PREFIX=OBS_ -include
add_library(mac-syphon MODULE
${mac-syphon_SOURCES}
${mac-syphon_HEADERS}
${syphon_HEADERS}
${syphon_SOURCES})
${mac-syphon_HEADERS})
target_link_libraries(mac-syphon
libobs
syphon-framework
${COCOA}
${IOSURF}
${SCRIPTINGBRIDGE}
${OPENGL_gl_LIBRARY})
set_property (TARGET mac-syphon APPEND_STRING PROPERTY
COMPILE_FLAGS "-fobjc-arc")
install_obs_plugin_with_data(mac-syphon data)

View file

@ -41,12 +41,6 @@ struct syphon {
};
typedef struct syphon *syphon_t;
static inline void objc_release(NSObject **obj)
{
[*obj release];
*obj = nil;
}
static inline void update_properties(syphon_t s)
{
obs_source_update_properties(s->source);
@ -101,10 +95,7 @@ static void stop_client(syphon_t s)
obs_enter_graphics();
if (s->client) {
@autoreleasepool {
[s->client stop];
objc_release(&s->client);
}
[s->client stop];
}
if (s->tex) {
@ -178,16 +169,6 @@ static inline void check_description(syphon_t s, NSDictionary *desc)
surfaces_string.UTF8String);
}
static inline bool update_string(NSString **str, NSString *new)
{
if (!new)
return false;
[*str release];
*str = [new retain];
return true;
}
static inline void handle_new_frame(syphon_t s,
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client)
{
@ -233,35 +214,26 @@ static void create_client(syphon_t s)
NSDictionary *desc = find_by_uuid(servers, s->uuid);
if (!desc) {
desc = servers[0];
if (update_string(&s->uuid,
desc[SyphonServerDescriptionUUIDKey]))
if (![s->uuid isEqualToString:
desc[SyphonServerDescriptionUUIDKey]]) {
s->uuid_changed = true;
}
}
check_version(s, desc);
check_description(s, desc);
@autoreleasepool {
s->client = [[SYPHON_CLIENT_UNIQUE_CLASS_NAME alloc]
initWithServerDescription:desc
options:nil
newFrameHandler:^(
SYPHON_CLIENT_UNIQUE_CLASS_NAME
*client) {
handle_new_frame(s, client);
}];
}
s->client = [[SYPHON_CLIENT_UNIQUE_CLASS_NAME alloc]
initWithServerDescription:desc
options:nil
newFrameHandler:^(
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) {
handle_new_frame(s, client);
}];
s->active = true;
}
static inline void release_settings(syphon_t s)
{
[s->app_name release];
[s->name release];
[s->uuid release];
}
static inline bool load_syphon_settings(syphon_t s, obs_data_t *settings)
{
NSString *app_name = @(obs_data_get_string(settings, "app_name"));
@ -275,10 +247,9 @@ static inline bool load_syphon_settings(syphon_t s, obs_data_t *settings)
if ([uuid isEqual:s->uuid] && equal_names)
return false;
release_settings(s);
s->app_name = [app_name retain];
s->name = [name retain];
s->uuid = [uuid retain];
s->app_name = app_name;
s->name = name;
s->uuid = uuid;
s->uuid_changed = false;
return true;
}
@ -299,10 +270,12 @@ static inline void update_from_announce(syphon_t s, NSDictionary *info)
!([app_name isEqual:s->app_name] && [name isEqual:s->name]))
return;
update_string(&s->app_name, app_name);
update_string(&s->name, name);
if (update_string(&s->uuid, uuid))
s->app_name = app_name;
s->name = name;
if (![s->uuid isEqualToString:uuid]) {
s->uuid = uuid;
s->uuid_changed = true;
}
create_client(s);
}
@ -324,8 +297,6 @@ static inline void update_inject_state(syphon_t s, NSDictionary *info,
if (!(s->inject_server_found = announce)) {
s->inject_wait_time = 0.f;
objc_release(&s->inject_uuid);
LOG(LOG_INFO,
"Injected server retired: "
"[%s] InjectedSyphon (%s)",
@ -336,7 +307,7 @@ static inline void update_inject_state(syphon_t s, NSDictionary *info,
if (s->inject_uuid) //TODO: track multiple injected instances?
return;
s->inject_uuid = [uuid retain];
s->inject_uuid = uuid;
LOG(LOG_INFO, "Injected server found: [%s] %s (%s)",
app_name.UTF8String, name.UTF8String, uuid.UTF8String);
}
@ -487,26 +458,31 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source)
s->source = source;
if (!init_obs_graphics_objects(s))
goto fail;
if (!init_obs_graphics_objects(s)) {
syphon_destroy_internal(s);
return NULL;
}
if (!load_syphon_settings(s, settings))
goto fail;
if (!load_syphon_settings(s, settings)) {
syphon_destroy_internal(s);
return NULL;
}
const char *inject_info = obs_data_get_string(settings, "application");
s->inject_info = obs_data_create_from_json(inject_info);
s->inject_active = obs_data_get_bool(settings, "inject");
s->inject_app = @(obs_data_get_string(s->inject_info, "name"));
if (s->inject_app)
[s->inject_app retain];
if (!create_syphon_listeners(s))
goto fail;
if (!create_syphon_listeners(s)) {
syphon_destroy_internal(s);
return NULL;
}
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
if (!create_applications_observer(s, ws))
goto fail;
if (!create_applications_observer(s, ws)) {
syphon_destroy_internal(s);
return NULL;
}
if (s->inject_active)
find_and_inject_target(s, ws.runningApplications, false);
@ -519,10 +495,6 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source)
obs_data_get_bool(settings, "allow_transparency");
return s;
fail:
syphon_destroy_internal(s);
return NULL;
}
static void *syphon_create(obs_data_t *settings, obs_source_t *source)
@ -550,15 +522,9 @@ static inline void syphon_destroy_internal(syphon_t s)
[ws removeObserver:s->launch_listener
forKeyPath:NSStringFromSelector(@selector
(runningApplications))];
objc_release(&s->launch_listener);
objc_release(&s->inject_app);
objc_release(&s->inject_uuid);
obs_data_release(s->inject_info);
release_settings(s);
obs_enter_graphics();
stop_client(s);
@ -1198,11 +1164,7 @@ static inline void update_inject(syphon_t s, obs_data_t *settings)
obs_data_t *prev = s->inject_info;
s->inject_info = obs_data_create_from_json(inject_str);
NSString *prev_app = s->inject_app;
s->inject_app = [@(obs_data_get_string(s->inject_info, "name")) retain];
[prev_app release];
objc_release(&s->inject_uuid);
s->inject_app = @(obs_data_get_string(s->inject_info, "name"));
SyphonServerDirectory *ssd = [SyphonServerDirectory sharedDirectory];
NSArray *servers = [ssd serversMatchingName:@"InjectedSyphon"

View file

@ -46,9 +46,12 @@ if(ENABLE_FFMPEG_LOGGING)
endif()
if(WIN32)
set(MODULE_DESCRIPTION "OBS FFmpeg module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-ffmpeg.rc)
list(APPEND obs-ffmpeg_SOURCES
jim-nvenc.c
jim-nvenc-helpers.c)
jim-nvenc-helpers.c
obs-ffmpeg.rc)
list(APPEND obs-ffmpeg_HEADERS
jim-nvenc.h)
endif()

View file

@ -58,3 +58,11 @@ ReplayBuffer.Save="Save Replay"
HelperProcessFailed="Unable to start the recording helper process. Check that OBS files have not been blocked or removed by any 3rd party antivirus / security software."
UnableToWritePath="Unable to write to %1. Make sure you're using a recording path which your user account is allowed to write to and that there is sufficient disk space."
WarnWindowsDefender="If Windows 10 Ransomware Protection is enabled it can also cause this error. Try turning off controlled folder access in Windows Security / Virus & threat protection settings."
NVENC.Error="Failed to open NVENC codec: %1"
NVENC.GenericError="Check your video drivers are up to date. Try closing other recording software which might be using NVENC such as NVIDIA Shadowplay or Windows 10 Game DVR."
NVENC.BadGPUIndex="You have selected GPU %1 in your output encoder settings. Set this back to 0 and try again."
NVENC.OutdatedDriver="Your current video card driver does not support this NVENC version, please update your drivers."
NVENC.UnsupportedDevice="NVENC Error: Unsupported device. Check your video card supports NVENC and that the drivers are up to date."
NVENC.TooManySessions="NVENC Error: Too many concurrent sessions. Try closing other recording software which might be using NVENC such as NVIDIA Shadowplay or Windows 10 Game DVR."
NVENC.CheckDrivers="Please check your video drivers are up to date."

View file

@ -1,6 +1,7 @@
#include "jim-nvenc.h"
#include <util/platform.h>
#include <util/threading.h>
#include <util/dstr.h>
static void *nvenc_lib = NULL;
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -9,18 +10,40 @@ NV_CREATE_INSTANCE_FUNC nv_create_instance = NULL;
#define error(format, ...) blog(LOG_ERROR, "[jim-nvenc] " format, ##__VA_ARGS__)
static inline bool nv_failed(NVENCSTATUS err, const char *func,
const char *call)
bool nv_failed(obs_encoder_t *encoder, NVENCSTATUS err, const char *func,
const char *call)
{
if (err == NV_ENC_SUCCESS)
struct dstr error_message = {0};
switch (err) {
case NV_ENC_SUCCESS:
return false;
case NV_ENC_ERR_OUT_OF_MEMORY:
obs_encoder_set_last_error(
encoder, obs_module_text("NVENC.TooManySessions"));
break;
case NV_ENC_ERR_UNSUPPORTED_DEVICE:
obs_encoder_set_last_error(
encoder, obs_module_text("NVENC.UnsupportedDevice"));
break;
default:
dstr_printf(&error_message,
"NVENC Error: %s: %s failed: %d (%s)", func, call,
(int)err, nv_error_name(err));
obs_encoder_set_last_error(encoder, error_message.array);
dstr_free(&error_message);
break;
}
error("%s: %s failed: %d (%s)", func, call, (int)err,
nv_error_name(err));
return true;
}
#define NV_FAILED(x) nv_failed(x, __FUNCTION__, #x)
#define NV_FAILED(e, x) nv_failed(e, x, __FUNCTION__, #x)
bool load_nvenc_lib(void)
{
@ -83,7 +106,7 @@ const char *nv_error_name(NVENCSTATUS err)
return "Unknown Error";
}
static inline bool init_nvenc_internal(void)
static inline bool init_nvenc_internal(obs_encoder_t *encoder)
{
static bool initialized = false;
static bool success = false;
@ -95,17 +118,24 @@ static inline bool init_nvenc_internal(void)
NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC)load_nv_func(
"NvEncodeAPIGetMaxSupportedVersion");
if (!nv_max_ver) {
obs_encoder_set_last_error(
encoder,
"Missing NvEncodeAPIGetMaxSupportedVersion, check "
"your video card drivers are up to date.");
return false;
}
uint32_t ver = 0;
if (NV_FAILED(nv_max_ver(&ver))) {
if (NV_FAILED(encoder, nv_max_ver(&ver))) {
return false;
}
uint32_t cur_ver = (NVENCAPI_MAJOR_VERSION << 4) |
NVENCAPI_MINOR_VERSION;
if (cur_ver > ver) {
obs_encoder_set_last_error(
encoder, obs_module_text("NVENC.OutdatedDriver"));
error("Current driver version does not support this NVENC "
"version, please upgrade your driver");
return false;
@ -114,10 +144,13 @@ static inline bool init_nvenc_internal(void)
nv_create_instance = (NV_CREATE_INSTANCE_FUNC)load_nv_func(
"NvEncodeAPICreateInstance");
if (!nv_create_instance) {
obs_encoder_set_last_error(
encoder, "Missing NvEncodeAPICreateInstance, check "
"your video card drivers are up to date.");
return false;
}
if (NV_FAILED(nv_create_instance(&nv))) {
if (NV_FAILED(encoder, nv_create_instance(&nv))) {
return false;
}
@ -125,12 +158,12 @@ static inline bool init_nvenc_internal(void)
return true;
}
bool init_nvenc(void)
bool init_nvenc(obs_encoder_t *encoder)
{
bool success;
pthread_mutex_lock(&init_mutex);
success = init_nvenc_internal();
success = init_nvenc_internal(encoder);
pthread_mutex_unlock(&init_mutex);
return success;

View file

@ -81,18 +81,7 @@ struct nv_bitstream {
HANDLE event;
};
static inline bool nv_failed(struct nvenc_data *enc, NVENCSTATUS err,
const char *func, const char *call)
{
if (err == NV_ENC_SUCCESS)
return false;
error("%s: %s failed: %d (%s)", func, call, (int)err,
nv_error_name(err));
return true;
}
#define NV_FAILED(x) nv_failed(enc, x, __FUNCTION__, #x)
#define NV_FAILED(x) nv_failed(enc->encoder, x, __FUNCTION__, #x)
static bool nv_bitstream_init(struct nvenc_data *enc, struct nv_bitstream *bs)
{
@ -400,7 +389,8 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings)
err = nv.nvEncGetEncodePresetConfig(enc->session,
NV_ENC_CODEC_H264_GUID, nv_preset,
&preset_config);
if (nv_failed(enc, err, __FUNCTION__, "nvEncGetEncodePresetConfig")) {
if (nv_failed(enc->encoder, err, __FUNCTION__,
"nvEncGetEncodePresetConfig")) {
return false;
}
@ -578,16 +568,19 @@ static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
* gpu other than the one OBS is currently running on. */
int gpu = (int)obs_data_get_int(settings, "gpu");
if (gpu != 0) {
info("different GPU selected by user, falling back to ffmpeg");
goto fail;
}
if (obs_encoder_scaling_enabled(encoder)) {
info("scaling enabled, falling back to ffmpeg");
goto fail;
}
if (!obs_nv12_tex_active()) {
info("nv12 not active, falling back to ffmpeg");
goto fail;
}
if (!init_nvenc()) {
if (!init_nvenc(encoder)) {
goto fail;
}
if (NV_FAILED(nv_create_instance(&init))) {
@ -766,7 +759,8 @@ static bool get_encoded_packet(struct nvenc_data *enc, bool finalize)
if (nvtex->mapped_res) {
NVENCSTATUS err;
err = nv.nvEncUnmapInputResource(s, nvtex->mapped_res);
if (nv_failed(enc, err, __FUNCTION__, "unmap")) {
if (nv_failed(enc->encoder, err, __FUNCTION__,
"unmap")) {
return false;
}
nvtex->mapped_res = NULL;
@ -859,7 +853,8 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts,
err = nv.nvEncEncodePicture(enc->session, &params);
if (err != NV_ENC_SUCCESS && err != NV_ENC_ERR_NEED_MORE_INPUT) {
nv_failed(enc, err, __FUNCTION__, "nvEncEncodePicture");
nv_failed(enc->encoder, err, __FUNCTION__,
"nvEncEncodePicture");
return false;
}

View file

@ -12,4 +12,6 @@ typedef NVENCSTATUS(NVENCAPI *NV_CREATE_INSTANCE_FUNC)(
extern const char *nv_error_name(NVENCSTATUS err);
extern NV_ENCODE_API_FUNCTION_LIST nv;
extern NV_CREATE_INSTANCE_FUNC nv_create_instance;
extern bool init_nvenc(void);
extern bool init_nvenc(obs_encoder_t *encoder);
bool nv_failed(obs_encoder_t *encoder, NVENCSTATUS err, const char *func,
const char *call);

View file

@ -18,6 +18,7 @@
#include <util/base.h>
#include <util/circlebuf.h>
#include <util/darray.h>
#include <util/dstr.h>
#include <obs-module.h>
#include <libavutil/opt.h>
@ -143,6 +144,11 @@ static bool initialize_codec(struct enc_encoder *enc)
ret = avcodec_open2(enc->context, enc->codec, NULL);
if (ret < 0) {
struct dstr error_message = {0};
dstr_printf(&error_message, "Failed to open AAC codec: %s",
av_err2str(ret));
obs_encoder_set_last_error(enc->encoder, error_message.array);
dstr_free(&error_message);
warn("Failed to open AAC codec: %s", av_err2str(ret));
return false;
}

View file

@ -88,8 +88,50 @@ static bool nvenc_init_codec(struct nvenc_encoder *enc)
{
int ret;
// avcodec_open2 will overwrite priv_data, we call this to get a
// local copy of the "gpu" setting for improved error messages.
int64_t gpu;
if (av_opt_get_int(enc->context->priv_data, "gpu", 0, &gpu) < 0) {
gpu = -1;
}
ret = avcodec_open2(enc->context, enc->nvenc, NULL);
if (ret < 0) {
// if we were a fallback from jim-nvenc, there may already be a
// more useful error returned from that, so don't overwrite.
// this can be removed if / when ffmpeg fallback is removed.
if (!obs_encoder_get_last_error(enc->encoder)) {
struct dstr error_message = {0};
dstr_copy(&error_message,
obs_module_text("NVENC.Error"));
dstr_replace(&error_message, "%1", av_err2str(ret));
dstr_cat(&error_message, "\r\n\r\n");
if (gpu > 0) {
// if a non-zero GPU failed, almost always
// user error. tell then to fix it.
char gpu_str[16];
snprintf(gpu_str, sizeof(gpu_str) - 1, "%d",
(int)gpu);
gpu_str[sizeof(gpu_str) - 1] = 0;
dstr_cat(&error_message,
obs_module_text("NVENC.BadGPUIndex"));
dstr_replace(&error_message, "%1", gpu_str);
} else if (ret == AVERROR_EXTERNAL) {
// special case for common NVENC error
dstr_cat(&error_message,
obs_module_text("NVENC.GenericError"));
} else {
dstr_cat(&error_message,
obs_module_text("NVENC.CheckDrivers"));
}
obs_encoder_set_last_error(enc->encoder,
error_message.array);
dstr_free(&error_message);
}
warn("Failed to open NVENC codec: %s", av_err2str(ret));
return false;
}
@ -296,6 +338,8 @@ static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
blog(LOG_INFO, "---------------------------------");
if (!enc->nvenc) {
obs_encoder_set_last_error(encoder,
"Couldn't find NVENC encoder");
warn("Couldn't find encoder");
goto fail;
}

View file

@ -258,10 +258,11 @@ static void media_stopped(void *opaque)
struct ffmpeg_source *s = opaque;
if (s->is_clear_on_media_end) {
obs_source_output_video(s->source, NULL);
if (s->close_when_inactive && s->media_valid)
s->destroy_media = true;
}
if (s->close_when_inactive && s->media_valid)
s->destroy_media = true;
set_media_state(s, OBS_MEDIA_STATE_ENDED);
obs_source_media_ended(s->source);
}

View file

@ -240,6 +240,11 @@ bool obs_module_load(void)
#ifdef _WIN32
if (get_win_ver_int() > 0x0601) {
jim_nvenc_load();
} else {
// if on Win 7, new nvenc isn't available so there's
// no nvenc encoder for the user to select, expose
// the old encoder directly
nvenc_encoder_info.caps &= ~OBS_ENCODER_CAP_INTERNAL;
}
#endif
obs_register_encoder(&nvenc_encoder_info);

View file

@ -54,6 +54,13 @@ set(obs-filters_SOURCES
expander-filter.c
luma-key-filter.c)
if(WIN32)
set(MODULE_DESCRIPTION "OBS A/V Filters")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-filters.rc)
list(APPEND obs-filters_SOURCES
obs-filters.rc)
endif()
add_library(obs-filters MODULE
${obs-filters_SOURCES}
${obs-filters_config_HEADERS}

View file

@ -329,7 +329,7 @@ static obs_properties_t *color_grade_filter_properties(void *data)
obs_properties_t *props = obs_properties_create();
struct dstr filter_str = {0};
dstr_cat(&filter_str, "(*.cube *.png)");
dstr_cat(&filter_str, "PNG/Cube (*.cube *.png)");
if (s && s->file && *s->file) {
dstr_copy(&path, s->file);

View file

@ -156,6 +156,13 @@ set(obs-outputs_SOURCES
flv-mux.c
net-if.c)
if(WIN32)
set(MODULE_DESCRIPTION "OBS output module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-outputs.rc)
list(APPEND obs-outputs_SOURCES
obs-outputs.rc)
endif()
add_library(obs-outputs MODULE
${ftl_SOURCES}
${ftl_HEADERS}

View file

@ -360,6 +360,8 @@ error:
mbedtls_x509_crt_free(chain);
free(chain);
r->RTMP_TLS_ctx->cacert = NULL;
#else /* USE_MBEDTLS */
UNUSED_PARAMETER(r);
#endif /* USE_MBEDTLS */
}
@ -407,6 +409,7 @@ RTMP_TLS_Init(RTMP *r)
SSL_CTX_set_default_verify_paths(RTMP_TLS_ctx);
#endif
#else
UNUSED_PARAMETER(r);
#endif
}
@ -429,6 +432,8 @@ RTMP_TLS_Free(RTMP *r) {
// NO mbedtls_net_free() BECAUSE WE SET IT UP BY HAND!
free(r->RTMP_TLS_ctx);
r->RTMP_TLS_ctx = NULL;
#else
UNUSED_PARAMETER(r);
#endif
}

View file

@ -5,8 +5,11 @@ endif()
project(obs-text)
if(WIN32)
set(MODULE_DESCRIPTION "OBS GDI+ text module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-text.rc)
set(obs-text_PLATFORM_SOURCES
gdiplus/obs-text.cpp)
gdiplus/obs-text.cpp
obs-text.rc)
set(obs-text_PLATFORM_DEPS
gdiplus)
endif()

View file

@ -11,6 +11,13 @@ set(obs-transitions_SOURCES
transition-stinger.c
)
if(WIN32)
set(MODULE_DESCRIPTION "OBS Transitions module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-transitions.rc)
list(APPEND obs-transitions_SOURCES
obs-transitions.rc)
endif()
add_library(obs-transitions MODULE
${obs-transitions_SOURCES})
target_link_libraries(obs-transitions

View file

@ -8,6 +8,13 @@ set(obs-x264_SOURCES
obs-x264.c
obs-x264-plugin-main.c)
if(WIN32)
set(MODULE_DESCRIPTION "OBS x264 encoder")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in obs-x264.rc)
list(APPEND obs-x264_SOURCES
obs-x264.rc)
endif()
add_library(obs-x264 MODULE
${obs-x264_SOURCES})
target_link_libraries(obs-x264

View file

@ -13,6 +13,13 @@ set(rtmp-services_SOURCES
rtmp-custom.c
rtmp-services-main.c)
if(WIN32)
set(MODULE_DESCRIPTION "OBS RTMP Services")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in rtmp-services.rc)
list(APPEND rtmp-services_SOURCES
rtmp-services.rc)
endif()
set(rtmp-services_HEADERS
twitch.h
younow.h

4
plugins/rtmp-services/data/package.json Executable file → Normal file
View file

@ -1,10 +1,10 @@
{
"url": "https://obsproject.com/obs2_update/rtmp-services",
"version": 125,
"version": 131,
"files": [
{
"name": "services.json",
"version": 125
"version": 131
}
]
}

175
plugins/rtmp-services/data/services.json Executable file → Normal file
View file

@ -893,57 +893,61 @@
"name": "Castr.io",
"servers": [
{
"name": "Chicago US",
"name": "US-East (Chicago, IL)",
"url": "rtmp://cg.castr.io/static"
},
{
"name": "Los Angeles US",
"url": "rtmp://la.castr.io/static"
},
{
"name": "New York US",
"name": "US-East (New York, NY)",
"url": "rtmp://ny.castr.io/static"
},
{
"name": "Miami US",
"name": "US-East (Miami, FL)",
"url": "rtmp://mi.castr.io/static"
},
{
"name": "Montreal CA",
"name": "US-West (Seattle, WA)",
"url": "rtmp://se.castr.io/static"
},
{
"name": "US-West (Los Angeles, CA)",
"url": "rtmp://la.castr.io/static"
},
{
"name": "US-Central (Dallas, TX)",
"url": "rtmp://da.castr.io/static"
},
{
"name": "NA-East (Toronto, CA)",
"url": "rtmp://qc.castr.io/static"
},
{
"name": "London UK",
"url": "rtmp://uk.castr.io/static"
},
{
"name": "Frankfurt DE",
"url": "rtmp://de.castr.io/static"
},
{
"name": "Frankfurt DE 2",
"url": "rtmp://fr.castr.io/static"
},
{
"name": "Moscow RU",
"url": "rtmp://ru.castr.io/static"
},
{
"name": "Singapore",
"url": "rtmp://sg.castr.io/static"
},
{
"name": "Sydney AU",
"url": "rtmp://au.castr.io/static"
},
{
"name": "Brazil",
"name": "SA (Sao Paulo, BR)",
"url": "rtmp://br.castr.io/static"
},
{
"name": "India",
"name": "EU-West (London, UK)",
"url": "rtmp://uk.castr.io/static"
},
{
"name": "EU-Central (Frankfurt, DE)",
"url": "rtmp://fr.castr.io/static"
},
{
"name": "Russia (Moscow)",
"url": "rtmp://ru.castr.io/static"
},
{
"name": "Asia (Singapore)",
"url": "rtmp://sg.castr.io/static"
},
{
"name": "Asia (India)",
"url": "rtmp://in.castr.io/static"
},
{
"name": "Australia (Sydney)",
"url": "rtmp://au.castr.io/static"
},
{
"name": "US Central",
"url": "rtmp://us-central.castr.io/static"
@ -975,10 +979,6 @@
{
"name": "Singapore",
"url": "rtmp://sg-central.castr.io/static"
},
{
"name": "India",
"url": "rtmp://in.castr.io/static"
}
],
"recommended": {
@ -1128,7 +1128,7 @@
"servers": [
{
"name": "Auto",
"url": "rtmp://s-sd.stripcdn.com/ext"
"url": "rtmp://s-sd.stripst.com/ext"
}
],
"recommended": {
@ -1494,14 +1494,28 @@
"name": "Bongacams",
"servers": [
{
"name": "Default",
"url": "rtmp://origin.bcrncdn.com:1934/live"
"name": "Automatic / Default",
"url": "rtmp://auto.origin.gnsbc.com:1934/live"
},
{
"name": "Automatic / Backup",
"url": "rtmp://origin.bcvidorigin.com:1934/live"
},
{
"name": "Europe",
"url": "rtmp://z-eu.origin.gnsbc.com:1934/live"
},
{
"name": "North America",
"url": "rtmp://z-us.origin.gnsbc.com:1934/live"
}
],
"recommend": {
"keyint": 2,
"max video bitrate": 6000,
"max audio bitrate": 192
"max audio bitrate": 192,
"bframes": 0,
"x264opts": "tune=zerolatency"
}
},
{
@ -1518,16 +1532,20 @@
}
},
{
"name": "ChathostessModels",
"name": "Chathostess",
"servers": [
{
"name": "ChathostessModels - Default",
"name": "Chathostess - Default",
"url": "rtmp://wowza01.foobarweb.com/cmschatsys_video"
},
{
"name": "Chathostess - Backup",
"url": "rtmp://wowza05.foobarweb.com/cmschatsys_video"
}
],
"recommended": {
"keyint": 2,
"max video bitrate": 3000,
"max video bitrate": 3600,
"max audio bitrate": 128
}
},
@ -1733,6 +1751,73 @@
"recommended": {
"keyint": 2
}
},
{
"name": "niconico, premium member (ニコニコ生放送 プレミアム会員)",
"servers": [
{
"name": "Default",
"url": "rtmp://aliveorigin.dmc.nico/named_input"
}
],
"recommended": {
"keyint": 2,
"profile": "high",
"max audio bitrate": 192,
"max video bitrate": 5808,
"x264opts": "tune=zerolatency"
}
},
{
"name": "niconico, free member (ニコニコ生放送 一般会員)",
"servers": [
{
"name": "Default",
"url": "rtmp://aliveorigin.dmc.nico/named_input"
}
],
"recommended": {
"keyint": 2,
"profile": "high",
"max audio bitrate": 96,
"max video bitrate": 904,
"x264opts": "tune=zerolatency"
}
},
{
"name": "WASD.TV",
"servers": [
{
"name": "Automatic",
"url": "rtmp://push.rtmp.wasd.tv/live"
},
{
"name": "Russia, Moscow",
"url": "rtmp://ru-moscow.rtmp.wasd.tv/live"
},
{
"name": "Germany, Frankfurt",
"url": "rtmp://de-frankfurt.rtmp.wasd.tv/live"
},
{
"name": "Finland, Helsinki",
"url": "rtmp://fi-helsinki.rtmp.wasd.tv/live"
}
],
"recommended": {
"keyint": 2,
"max video bitrate": 10000,
"max audio bitrate": 192
}
},
{
"name": "VirtWish",
"servers": [
{
"name": "Default",
"url": "rtmp://rtmp.virtwish.com/live"
}
]
}
]
}

View file

@ -18,6 +18,8 @@ static void rtmp_custom_update(void *data, obs_data_t *settings)
bfree(service->server);
bfree(service->key);
bfree(service->username);
bfree(service->password);
service->server = bstrdup(obs_data_get_string(settings, "server"));
service->key = bstrdup(obs_data_get_string(settings, "key"));

View file

@ -14,9 +14,12 @@ elseif(NOT FREETYPE_FOUND)
endif()
if(WIN32)
set(MODULE_DESCRIPTION "OBS Freetype text module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in text-freetype2.rc)
set(text-freetype2_PLATFORM_SOURCES
find-font.c
find-font-windows.c)
find-font-windows.c
text-freetype2.rc)
elseif(APPLE)
find_package(Iconv QUIET)
if(NOT ICONV_FOUND AND ENABLE_FREETYPE)

View file

@ -31,6 +31,13 @@ set(vlc-video_SOURCES
vlc-video-source.c
)
if(WIN32)
set(MODULE_DESCRIPTION "OBS VLC module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/winrc/obs-module.rc.in vlc-video.rc)
list(APPEND vlc-video_SOURCES
vlc-video.rc)
endif()
add_library(vlc-video MODULE
${vlc-video_SOURCES}
${vlc-video_HEADERS})