Fix video reset and apply new video settings

This allows the changing of bideo settings without having to completely
reset all graphics data.  Will recreate internal output/conversion
buffers and such and reset the main preview.
This commit is contained in:
jp9000
2014-02-22 20:14:19 -07:00
parent 7fcec77351
commit 0ff0d32731
11 changed files with 105 additions and 43 deletions

View File

@@ -666,6 +666,12 @@ void audio_line_destroy(struct audio_line *line)
}
}
bool audio_output_active(audio_t audio)
{
if (!audio) return false;
return audio->inputs.num != 0;
}
size_t audio_output_blocksize(audio_t audio)
{
return audio->block_size;

View File

@@ -172,6 +172,8 @@ EXPORT void audio_output_disconnect(audio_t video,
void (*callback)(void *param, const struct audio_data *data),
void *param);
EXPORT bool audio_output_active(audio_t audio);
EXPORT size_t audio_output_blocksize(audio_t audio);
EXPORT size_t audio_output_planes(audio_t audio);
EXPORT size_t audio_output_channels(audio_t audio);

View File

@@ -308,6 +308,12 @@ void video_output_disconnect(video_t video,
pthread_mutex_unlock(&video->input_mutex);
}
bool video_output_active(video_t video)
{
if (!video) return false;
return video->inputs.num != 0;
}
const struct video_output_info *video_output_getinfo(video_t video)
{
return &video->info;

View File

@@ -118,6 +118,8 @@ EXPORT void video_output_disconnect(video_t video,
void (*callback)(void *param, const struct video_data *frame),
void *param);
EXPORT bool video_output_active(video_t video);
EXPORT const struct video_output_info *video_output_getinfo(video_t video);
EXPORT void video_output_swap_frame(video_t video, struct video_data *frame);
EXPORT bool video_output_wait(video_t video);

View File

@@ -1,5 +1,5 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -183,7 +183,7 @@ void source_frame_init(struct source_frame *frame, enum video_format format,
}
}
static void obs_source_destroy(obs_source_t source)
static void obs_source_destroy(struct obs_source *source)
{
size_t i;
@@ -950,7 +950,7 @@ static void process_audio(obs_source_t source, const struct source_audio *audio)
void obs_source_output_audio(obs_source_t source,
const struct source_audio *audio)
{
uint32_t flags = obs_source_get_output_flags(source);
uint32_t flags = source->info.output_flags;
struct filtered_audio *output;
process_audio(source, audio);
@@ -959,13 +959,13 @@ void obs_source_output_audio(obs_source_t source,
output = filter_async_audio(source, &source->audio_data);
if (output) {
bool async = (flags & OBS_SOURCE_ASYNC_VIDEO) == 0;
bool async = (flags & OBS_SOURCE_ASYNC_VIDEO) != 0;
pthread_mutex_lock(&source->audio_mutex);
/* wait for video to start before outputting any audio so we
* have a base for sync */
if (source->timing_set || async) {
if (source->timing_set || !async) {
struct audio_data data;
for (int i = 0; i < MAX_AV_PLANES; i++)
@@ -1143,8 +1143,8 @@ void obs_source_process_filter(obs_source_t filter, effect_t effect,
{
obs_source_t target = obs_filter_gettarget(filter);
obs_source_t parent = obs_filter_getparent(filter);
uint32_t target_flags = obs_source_get_output_flags(target);
uint32_t parent_flags = obs_source_get_output_flags(parent);
uint32_t target_flags = target->info.output_flags;
uint32_t parent_flags = parent->info.output_flags;
int cx = obs_source_getwidth(target);
int cy = obs_source_getheight(target);
bool use_matrix = !!(target_flags & OBS_SOURCE_COLOR_MATRIX);

View File

@@ -168,12 +168,6 @@ static bool obs_init_graphics(struct obs_video_info *ovi)
int errorcode;
make_gs_init_data(&graphics_data, ovi);
video->base_width = ovi->base_width;
video->base_height = ovi->base_height;
video->output_width = ovi->output_width;
video->output_height = ovi->output_height;
video->gpu_conversion = ovi->gpu_conversion;
errorcode = gs_create(&video->graphics, ovi->graphics_module,
&graphics_data);
@@ -186,11 +180,6 @@ static bool obs_init_graphics(struct obs_video_info *ovi)
gs_entercontext(video->graphics);
if (ovi->gpu_conversion && !obs_init_gpu_conversion(ovi))
success = false;
if (success && !obs_init_textures(ovi))
success = false;
if (success) {
char *filename = find_libobs_data_file("default.effect");
video->default_effect = gs_create_effect_from_file(filename,
@@ -219,6 +208,12 @@ static bool obs_init_video(struct obs_video_info *ovi)
int errorcode;
make_video_info(&vi, ovi);
video->base_width = ovi->base_width;
video->base_height = ovi->base_height;
video->output_width = ovi->output_width;
video->output_height = ovi->output_height;
video->gpu_conversion = ovi->gpu_conversion;
errorcode = video_output_open(&video->video, &vi);
if (errorcode != VIDEO_OUTPUT_SUCCESS) {
@@ -236,6 +231,15 @@ static bool obs_init_video(struct obs_video_info *ovi)
video->main_display.cx = ovi->window_width;
video->main_display.cy = ovi->window_height;
gs_entercontext(video->graphics);
if (ovi->gpu_conversion && !obs_init_gpu_conversion(ovi))
return false;
if (!obs_init_textures(ovi))
return false;
gs_leavecontext();
errorcode = pthread_create(&video->video_thread, NULL,
obs_video_thread, obs);
if (errorcode != 0)
@@ -268,21 +272,18 @@ static void obs_free_video(void)
obs_display_free(&video->main_display);
video_output_close(video->video);
video->video = NULL;
}
}
static void obs_free_graphics(void)
{
struct obs_core_video *video = &obs->video;
size_t i;
if (!video->graphics)
return;
if (video->graphics) {
gs_entercontext(video->graphics);
if (video->mapped_surface)
if (video->mapped_surface) {
stagesurface_unmap(video->mapped_surface);
video->mapped_surface = NULL;
}
for (i = 0; i < NUM_TEXTURES; i++) {
for (size_t i = 0; i < NUM_TEXTURES; i++) {
stagesurface_destroy(video->copy_surfaces[i]);
texture_destroy(video->render_textures[i]);
texture_destroy(video->convert_textures[i]);
@@ -295,6 +296,19 @@ static void obs_free_graphics(void)
video->output_textures[i] = NULL;
}
gs_leavecontext();
video->cur_texture = 0;
}
}
static void obs_free_graphics(void)
{
struct obs_core_video *video = &obs->video;
if (video->graphics) {
gs_entercontext(video->graphics);
effect_destroy(video->default_effect);
effect_destroy(video->conversion_effect);
video->default_effect = NULL;
@@ -303,7 +317,6 @@ static void obs_free_graphics(void)
gs_destroy(video->graphics);
video->graphics = NULL;
video->cur_texture = 0;
}
}
@@ -467,11 +480,19 @@ bool obs_initialized(void)
bool obs_reset_video(struct obs_video_info *ovi)
{
if (!obs) return false;
/* don't allow changing of video settings if active. */
if (obs->video.video && video_output_active(obs->video.video))
return false;
struct obs_core_video *video = &obs->video;
/* align to multiple-of-two and SSE alignment sizes */
ovi->output_width &= 0xFFFFFFFC;
ovi->output_height &= 0xFFFFFFFE;
stop_video();
obs_free_video();
if (!ovi) {
@@ -487,6 +508,12 @@ bool obs_reset_video(struct obs_video_info *ovi)
bool obs_reset_audio(struct audio_output_info *ai)
{
if (!obs) return false;
/* don't allow changing of audio settings if active. */
if (obs->audio.audio && audio_output_active(obs->audio.audio))
return false;
obs_free_audio();
if(!ai)
return true;