New upstream version 23.2.1+dfsg1

This commit is contained in:
Simon Chopin 2019-07-27 14:47:10 +02:00
parent cdc9a9fc87
commit b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions

View file

@ -164,17 +164,42 @@ static bool obs_init_gpu_conversion(struct obs_video_info *ovi)
calc_gpu_conversion_sizes(ovi);
video->using_nv12_tex = ovi->output_format == VIDEO_FORMAT_NV12
? gs_nv12_available() : false;
if (!video->conversion_height) {
blog(LOG_INFO, "GPU conversion not available for format: %u",
(unsigned int)ovi->output_format);
video->gpu_conversion = false;
video->using_nv12_tex = false;
blog(LOG_INFO, "NV12 texture support not available");
return true;
}
if (video->using_nv12_tex)
blog(LOG_INFO, "NV12 texture support enabled");
else
blog(LOG_INFO, "NV12 texture support not available");
for (size_t i = 0; i < NUM_TEXTURES; i++) {
video->convert_textures[i] = gs_texture_create(
ovi->output_width, video->conversion_height,
GS_RGBA, 1, NULL, GS_RENDER_TARGET);
#ifdef _WIN32
if (video->using_nv12_tex) {
gs_texture_create_nv12(
&video->convert_textures[i],
&video->convert_uv_textures[i],
ovi->output_width, ovi->output_height,
GS_RENDER_TARGET | GS_SHARED_KM_TEX);
if (!video->convert_uv_textures[i])
return false;
} else {
#endif
video->convert_textures[i] = gs_texture_create(
ovi->output_width,
video->conversion_height,
GS_RGBA, 1, NULL, GS_RENDER_TARGET);
#ifdef _WIN32
}
#endif
if (!video->convert_textures[i])
return false;
@ -191,11 +216,23 @@ static bool obs_init_textures(struct obs_video_info *ovi)
size_t i;
for (i = 0; i < NUM_TEXTURES; i++) {
video->copy_surfaces[i] = gs_stagesurface_create(
ovi->output_width, output_height, GS_RGBA);
#ifdef _WIN32
if (video->using_nv12_tex) {
video->copy_surfaces[i] = gs_stagesurface_create_nv12(
ovi->output_width, ovi->output_height);
if (!video->copy_surfaces[i])
return false;
if (!video->copy_surfaces[i])
return false;
} else {
#endif
video->copy_surfaces[i] = gs_stagesurface_create(
ovi->output_width, output_height,
GS_RGBA);
if (!video->copy_surfaces[i])
return false;
#ifdef _WIN32
}
#endif
video->render_textures[i] = gs_texture_create(
ovi->base_width, ovi->base_height,
@ -272,6 +309,11 @@ static int obs_init_graphics(struct obs_video_info *ovi)
NULL);
bfree(filename);
filename = obs_find_data_file("repeat.effect");
video->repeat_effect = gs_effect_create_from_file(filename,
NULL);
bfree(filename);
filename = obs_find_data_file("format_conversion.effect");
video->conversion_effect = gs_effect_create_from_file(filename,
NULL);
@ -287,6 +329,11 @@ static int obs_init_graphics(struct obs_video_info *ovi)
NULL);
bfree(filename);
filename = obs_find_data_file("area.effect");
video->area_effect = gs_effect_create_from_file(filename,
NULL);
bfree(filename);
filename = obs_find_data_file("bilinear_lowres_scale.effect");
video->bilinear_lowres_effect = gs_effect_create_from_file(filename,
NULL);
@ -297,6 +344,7 @@ static int obs_init_graphics(struct obs_video_info *ovi)
NULL);
bfree(filename);
point_sampler.max_anisotropy = 1;
video->point_sampler = gs_samplerstate_create(&point_sampler);
obs->video.transparent_texture = gs_texture_create(2, 2, GS_RGBA, 1,
@ -351,6 +399,7 @@ static int obs_init_video(struct obs_video_info *ovi)
{
struct obs_core_video *video = &obs->video;
struct video_output_info vi;
pthread_mutexattr_t attr;
int errorcode;
make_video_info(&vi, ovi);
@ -384,6 +433,13 @@ static int obs_init_video(struct obs_video_info *ovi)
gs_leave_context();
if (pthread_mutexattr_init(&attr) != 0)
return OBS_VIDEO_FAIL;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
return OBS_VIDEO_FAIL;
if (pthread_mutex_init(&video->gpu_encoder_mutex, NULL) < 0)
return OBS_VIDEO_FAIL;
errorcode = pthread_create(&video->video_thread, NULL,
obs_graphics_thread, obs);
if (errorcode != 0)
@ -431,17 +487,20 @@ static void obs_free_video(void)
gs_stagesurface_destroy(video->copy_surfaces[i]);
gs_texture_destroy(video->render_textures[i]);
gs_texture_destroy(video->convert_textures[i]);
gs_texture_destroy(video->convert_uv_textures[i]);
gs_texture_destroy(video->output_textures[i]);
video->copy_surfaces[i] = NULL;
video->render_textures[i] = NULL;
video->convert_textures[i] = NULL;
video->output_textures[i] = NULL;
video->copy_surfaces[i] = NULL;
video->render_textures[i] = NULL;
video->convert_textures[i] = NULL;
video->convert_uv_textures[i] = NULL;
video->output_textures[i] = NULL;
}
gs_leave_context();
circlebuf_free(&video->vframe_info_buffer);
circlebuf_free(&video->vframe_info_buffer_gpu);
memset(&video->textures_rendered, 0,
sizeof(video->textures_rendered));
@ -452,6 +511,11 @@ static void obs_free_video(void)
memset(&video->textures_converted, 0,
sizeof(video->textures_converted));
pthread_mutex_destroy(&video->gpu_encoder_mutex);
pthread_mutex_init_value(&video->gpu_encoder_mutex);
da_free(video->gpu_encoders);
video->gpu_encoder_active = 0;
video->cur_texture = 0;
}
}
@ -473,7 +537,9 @@ static void obs_free_graphics(void)
gs_effect_destroy(video->solid_effect);
gs_effect_destroy(video->conversion_effect);
gs_effect_destroy(video->bicubic_effect);
gs_effect_destroy(video->repeat_effect);
gs_effect_destroy(video->lanczos_effect);
gs_effect_destroy(video->area_effect);
gs_effect_destroy(video->bilinear_lowres_effect);
video->default_effect = NULL;
@ -753,6 +819,7 @@ static bool obs_init(const char *locale, const char *module_config_path,
obs = bzalloc(sizeof(struct obs_core));
pthread_mutex_init_value(&obs->audio.monitoring_mutex);
pthread_mutex_init_value(&obs->video.gpu_encoder_mutex);
obs->name_store_owned = !store;
obs->name_store = store ? store : profiler_name_store_create();
@ -853,6 +920,42 @@ bool obs_startup(const char *locale, const char *module_config_path,
return success;
}
static struct obs_cmdline_args cmdline_args = {0, NULL};
void obs_set_cmdline_args(int argc, const char * const *argv)
{
char *data;
size_t len;
int i;
/* Once argc is set (non-zero) we shouldn't call again */
if (cmdline_args.argc)
return;
cmdline_args.argc = argc;
/* Safely copy over argv */
len = 0;
for (i = 0; i < argc; i++)
len += strlen(argv[i]) + 1;
cmdline_args.argv = bmalloc(sizeof(char *) * (argc + 1) + len);
data = (char *) cmdline_args.argv + sizeof(char *) * (argc + 1);
for (i = 0; i < argc; i++) {
cmdline_args.argv[i] = data;
len = strlen(argv[i]) + 1;
memcpy(data, argv[i], len);
data += len;
}
cmdline_args.argv[argc] = NULL;
}
struct obs_cmdline_args obs_get_cmdline_args(void)
{
return cmdline_args;
}
void obs_shutdown(void)
{
struct obs_module *module;
@ -918,6 +1021,7 @@ void obs_shutdown(void)
bfree(core->module_config_path);
bfree(core->locale);
bfree(core);
bfree(cmdline_args.argv);
#ifdef _WIN32
uninitialize_com();
@ -977,7 +1081,7 @@ int obs_reset_video(struct obs_video_info *ovi)
if (!obs) return OBS_VIDEO_FAIL;
/* don't allow changing of video settings if active. */
if (obs->video.video && video_output_active(obs->video.video))
if (obs->video.video && obs_video_active())
return OBS_VIDEO_CURRENTLY_ACTIVE;
if (!size_valid(ovi->output_width, ovi->output_height) ||
@ -1018,11 +1122,15 @@ int obs_reset_video(struct obs_video_info *ovi)
case OBS_SCALE_LANCZOS:
scale_type_name = "Lanczos";
break;
case OBS_SCALE_AREA:
scale_type_name = "Area";
break;
}
bool yuv = format_is_yuv(ovi->output_format);
const char *yuv_format = get_video_colorspace_name(ovi->colorspace);
const char *yuv_range = get_video_range_name(ovi->range);
const char *yuv_range = get_video_range_name(ovi->output_format,
ovi->range);
blog(LOG_INFO, "---------------------------------");
blog(LOG_INFO, "video settings reset:\n"
@ -1323,6 +1431,31 @@ void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), void *param)
pthread_mutex_unlock(&obs->data.sources_mutex);
}
void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), void *param)
{
obs_source_t *source;
if (!obs) return;
pthread_mutex_lock(&obs->data.sources_mutex);
source = obs->data.first_source;
while (source) {
obs_source_t *next_source =
(obs_source_t*)source->context.next;
if (source->info.type == OBS_SOURCE_TYPE_SCENE &&
!source->context.private &&
!enum_proc(param, source)) {
break;
}
source = next_source;
}
pthread_mutex_unlock(&obs->data.sources_mutex);
}
static inline void obs_enum(void *pstart, pthread_mutex_t *mutex, void *proc,
void *param)
{
@ -1454,10 +1587,14 @@ gs_effect_t *obs_get_base_effect(enum obs_base_effect effect)
return obs->video.opaque_effect;
case OBS_EFFECT_SOLID:
return obs->video.solid_effect;
case OBS_EFFECT_REPEAT:
return obs->video.repeat_effect;
case OBS_EFFECT_BICUBIC:
return obs->video.bicubic_effect;
case OBS_EFFECT_LANCZOS:
return obs->video.lanczos_effect;
case OBS_EFFECT_AREA:
return obs->video.area_effect;
case OBS_EFFECT_BILINEAR_LOWRES:
return obs->video.bilinear_lowres_effect;
case OBS_EFFECT_PREMULTIPLIED_ALPHA:
@ -1514,8 +1651,13 @@ void obs_render_main_texture(void)
param = gs_effect_get_param_by_name(effect, "image");
gs_effect_set_texture(param, tex);
gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
while (gs_effect_loop(effect, "Draw"))
gs_draw_sprite(tex, 0, 0, 0);
gs_blend_state_pop();
}
gs_texture_t *obs_get_main_texture(void)
@ -1563,6 +1705,7 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
obs_data_t *settings = obs_data_get_obj(source_data, "settings");
obs_data_t *hotkeys = obs_data_get_obj(source_data, "hotkeys");
double volume;
double balance;
int64_t sync;
uint32_t flags;
uint32_t mixers;
@ -1578,6 +1721,10 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data)
volume = obs_data_get_double(source_data, "volume");
obs_source_set_volume(source, (float)volume);
obs_data_set_default_double(source_data, "balance", 0.5);
balance = obs_data_get_double(source_data, "balance");
obs_source_set_balance_value(source, (float)balance);
sync = obs_data_get_int(source_data, "sync");
obs_source_set_sync_offset(source, sync);
@ -1694,6 +1841,11 @@ void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb,
if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
obs_transition_load(source, source_data);
obs_source_load(source);
for (size_t i = source->filters.num; i > 0; i--) {
obs_source_t *filter =
source->filters.array[i - 1];
obs_source_load(filter);
}
if (cb)
cb(private_data, source);
}
@ -1716,6 +1868,7 @@ obs_data_t *obs_save_source(obs_source_t *source)
obs_data_t *hotkey_data = source->context.hotkey_data;
obs_data_t *hotkeys;
float volume = obs_source_get_volume(source);
float balance = obs_source_get_balance_value(source);
uint32_t mixers = obs_source_get_audio_mixers(source);
int64_t sync = obs_source_get_sync_offset(source);
uint32_t flags = obs_source_get_flags(source);
@ -1748,6 +1901,7 @@ obs_data_t *obs_save_source(obs_source_t *source)
obs_data_set_int (source_data, "sync", sync);
obs_data_set_int (source_data, "flags", flags);
obs_data_set_double(source_data, "volume", volume);
obs_data_set_double(source_data, "balance", balance);
obs_data_set_bool (source_data, "enabled", enabled);
obs_data_set_bool (source_data, "muted", muted);
obs_data_set_bool (source_data, "push-to-mute", push_to_mute);
@ -2013,6 +2167,15 @@ bool obs_obj_invalid(void *obj)
return !context->data;
}
void *obs_obj_get_data(void *obj)
{
struct obs_context_data *context = obj;
if (!context)
return NULL;
return context->data;
}
bool obs_set_audio_monitoring_device(const char *name, const char *id)
{
if (!obs || !name || !id || !*name || !*id)
@ -2189,3 +2352,79 @@ obs_data_t *obs_get_private_data(void)
obs_data_addref(private_data);
return private_data;
}
extern bool init_gpu_encoding(struct obs_core_video *video);
extern void stop_gpu_encoding_thread(struct obs_core_video *video);
extern void free_gpu_encoding(struct obs_core_video *video);
bool start_gpu_encode(obs_encoder_t *encoder)
{
struct obs_core_video *video = &obs->video;
bool success = true;
obs_enter_graphics();
pthread_mutex_lock(&video->gpu_encoder_mutex);
if (!video->gpu_encoders.num)
success = init_gpu_encoding(video);
if (success)
da_push_back(video->gpu_encoders, &encoder);
else
free_gpu_encoding(video);
pthread_mutex_unlock(&video->gpu_encoder_mutex);
obs_leave_graphics();
if (success) {
os_atomic_inc_long(&video->gpu_encoder_active);
video_output_inc_texture_encoders(video->video);
}
return success;
}
void stop_gpu_encode(obs_encoder_t *encoder)
{
struct obs_core_video *video = &obs->video;
bool call_free = false;
os_atomic_dec_long(&video->gpu_encoder_active);
video_output_dec_texture_encoders(video->video);
pthread_mutex_lock(&video->gpu_encoder_mutex);
da_erase_item(video->gpu_encoders, &encoder);
if (!video->gpu_encoders.num)
call_free = true;
pthread_mutex_unlock(&video->gpu_encoder_mutex);
os_event_wait(video->gpu_encode_inactive);
if (call_free) {
stop_gpu_encoding_thread(video);
obs_enter_graphics();
pthread_mutex_lock(&video->gpu_encoder_mutex);
free_gpu_encoding(video);
pthread_mutex_unlock(&video->gpu_encoder_mutex);
obs_leave_graphics();
}
}
bool obs_video_active(void)
{
struct obs_core_video *video = &obs->video;
if (!obs)
return false;
return os_atomic_load_long(&video->raw_active) > 0 ||
os_atomic_load_long(&video->gpu_encoder_active) > 0;
}
bool obs_nv12_tex_active(void)
{
struct obs_core_video *video = &obs->video;
if (!obs)
return false;
return video->using_nv12_tex;
}