mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-19 17:49:14 +00:00
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:
parent
7fcec77351
commit
0ff0d32731
|
@ -56,6 +56,7 @@ Settings.Video.FPS.Numerator="Numerator:"
|
|||
Settings.Video.FPS.Denominator="Denominator:"
|
||||
Settings.Video.Renderer="Renderer:"
|
||||
Settings.Video.InvalidResolution="Invalid resolution value. Must be [width]x[height] (i.e. 1920x1080)"
|
||||
Settings.Video.CurrentlyActive="Video output is currently active. Please turn off any outputs to change video settings."
|
||||
|
||||
Settings.Audio="Audio"
|
||||
Settings.Audio.DesktopAudioDevice1="Desktop Audio Device 1:"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
69
libobs/obs.c
69
libobs/obs.c
|
@ -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;
|
||||
|
|
|
@ -495,7 +495,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="errorText">
|
||||
<widget class="QLabel" name="videoMsg">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -508,6 +508,9 @@
|
|||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -51,13 +51,11 @@ void OBSBasic::OBSInit()
|
|||
|
||||
if (!obs_startup())
|
||||
throw "Failed to initialize libobs";
|
||||
if (!InitGraphics())
|
||||
throw "Failed to initialize graphics";
|
||||
if (!InitAudio())
|
||||
if (!ResetVideo())
|
||||
throw "Failed to initialize video";
|
||||
if (!ResetAudio())
|
||||
throw "Failed to initialize audio";
|
||||
|
||||
obs_add_draw_callback(OBSBasic::RenderMain, this);
|
||||
|
||||
signal_handler_connect(obs_signalhandler(), "source-add",
|
||||
OBSBasic::SourceAdded, this);
|
||||
signal_handler_connect(obs_signalhandler(), "source-remove",
|
||||
|
@ -278,7 +276,7 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
/* Main class functions */
|
||||
|
||||
bool OBSBasic::InitGraphics()
|
||||
bool OBSBasic::ResetVideo()
|
||||
{
|
||||
struct obs_video_info ovi;
|
||||
|
||||
|
@ -306,10 +304,14 @@ bool OBSBasic::InitGraphics()
|
|||
ovi.window_width = size.width();
|
||||
ovi.window_height = size.height();
|
||||
|
||||
return obs_reset_video(&ovi);
|
||||
if (!obs_reset_video(&ovi))
|
||||
return false;
|
||||
|
||||
obs_add_draw_callback(OBSBasic::RenderMain, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OBSBasic::InitAudio()
|
||||
bool OBSBasic::ResetAudio()
|
||||
{
|
||||
/* TODO: load audio settings from config */
|
||||
struct audio_output_info ai;
|
||||
|
|
|
@ -60,8 +60,9 @@ private:
|
|||
void AddSource(obs_scene_t scene, const char *id);
|
||||
void AddSourcePopupMenu(const QPoint &pos);
|
||||
|
||||
bool InitGraphics();
|
||||
bool InitAudio();
|
||||
public:
|
||||
bool ResetVideo();
|
||||
bool ResetAudio();
|
||||
|
||||
void NewProject();
|
||||
void SaveProject();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include <obs.hpp>
|
||||
#include <util/util.hpp>
|
||||
#include <util/lexer.h>
|
||||
#include <sstream>
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include "obs-app.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "qt-wrappers.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
#include "window-basic-settings.hpp"
|
||||
|
||||
#include <util/platform.h>
|
||||
|
@ -205,6 +207,8 @@ void OBSBasicSettings::LoadResolutionLists()
|
|||
|
||||
ResetDownscales(cx, cy);
|
||||
|
||||
ui->baseResolution->lineEdit()->setText(ResString(cx, cy).c_str());
|
||||
|
||||
cx = config_get_uint(GetGlobalConfig(), "Video", "OutputCX");
|
||||
cy = config_get_uint(GetGlobalConfig(), "Video", "OutputCY");
|
||||
|
||||
|
@ -254,6 +258,11 @@ void OBSBasicSettings::LoadVideoSettings()
|
|||
{
|
||||
loading = true;
|
||||
|
||||
if (video_output_active(obs_video())) {
|
||||
ui->videoPage->setEnabled(false);
|
||||
ui->videoMsg->setText(QTStr("Settings.Video.CurrentlyActive"));
|
||||
}
|
||||
|
||||
LoadRendererList();
|
||||
LoadResolutionLists();
|
||||
LoadFPSData();
|
||||
|
@ -316,6 +325,10 @@ void OBSBasicSettings::SaveVideoSettings()
|
|||
config_set_uint(GetGlobalConfig(), "Video", "FPSInt", fpsInteger);
|
||||
config_set_uint(GetGlobalConfig(), "Video", "FPSNum", fpsNumerator);
|
||||
config_set_uint(GetGlobalConfig(), "Video", "FPSDen", fpsDenominator);
|
||||
|
||||
OBSBasic *window = qobject_cast<OBSBasic*>(parent());
|
||||
if (window)
|
||||
window->ResetVideo();
|
||||
}
|
||||
|
||||
void OBSBasicSettings::SaveSettings()
|
||||
|
@ -400,12 +413,12 @@ static bool ValidResolutions(Ui::OBSBasicSettings *ui)
|
|||
if (!ConvertResText(QT_TO_UTF8(baseRes), cx, cy) ||
|
||||
!ConvertResText(QT_TO_UTF8(outputRes), cx, cy)) {
|
||||
|
||||
ui->errorText->setText(
|
||||
ui->videoMsg->setText(
|
||||
QTStr("Settings.Video.InvalidResolution"));
|
||||
return false;
|
||||
}
|
||||
|
||||
ui->errorText->setText("");
|
||||
ui->videoMsg->setText("");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -421,8 +434,7 @@ void OBSBasicSettings::on_renderer_currentIndexChanged(int index)
|
|||
{
|
||||
if (!loading) {
|
||||
videoChanged = true;
|
||||
ui->errorText->setText(
|
||||
QTStr("Settings.ProgramRestart"));
|
||||
ui->videoMsg->setText(QTStr("Settings.ProgramRestart"));
|
||||
}
|
||||
|
||||
UNUSED_PARAMETER(index);
|
||||
|
|
Loading…
Reference in a new issue