소스 검색

Merge pull request #5580 from VodBox/add-cpp-templates

libobs: Add AutoRelease OBSRef wrappers for OBS types
Jim 3 년 전
부모
커밋
83f08725e4
36개의 변경된 파일560개의 추가작업 그리고 941개의 파일을 삭제
  1. 14 14
      UI/adv-audio-control.cpp
  2. 4 4
      UI/api-interface.cpp
  3. 1 3
      UI/auth-oauth.cpp
  4. 25 50
      UI/context-bar-controls.cpp
  5. 1 1
      UI/context-bar-controls.hpp
  6. 16 32
      UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp
  7. 4 6
      UI/frontend-plugins/frontend-tools/captions.cpp
  8. 3 6
      UI/frontend-plugins/frontend-tools/output-timer.cpp
  9. 13 24
      UI/frontend-plugins/frontend-tools/scripts.cpp
  10. 4 8
      UI/obs-app.cpp
  11. 6 15
      UI/properties-view.cpp
  12. 3 5
      UI/qt-wrappers.cpp
  13. 21 28
      UI/source-tree.cpp
  14. 4 4
      UI/volume-control.cpp
  15. 22 40
      UI/window-basic-auto-config-test.cpp
  16. 15 28
      UI/window-basic-auto-config.cpp
  17. 54 100
      UI/window-basic-filters.cpp
  18. 4 9
      UI/window-basic-main-dropfiles.cpp
  19. 29 71
      UI/window-basic-main-outputs.cpp
  20. 4 4
      UI/window-basic-main-outputs.hpp
  21. 1 3
      UI/window-basic-main-scene-collections.cpp
  22. 31 60
      UI/window-basic-main-transitions.cpp
  23. 143 245
      UI/window-basic-main.cpp
  24. 1 1
      UI/window-basic-main.hpp
  25. 6 18
      UI/window-basic-preview.cpp
  26. 1 1
      UI/window-basic-preview.hpp
  27. 25 50
      UI/window-basic-properties.cpp
  28. 3 3
      UI/window-basic-properties.hpp
  29. 12 24
      UI/window-basic-settings-stream.cpp
  30. 12 24
      UI/window-basic-settings.cpp
  31. 16 28
      UI/window-basic-source-select.cpp
  32. 4 8
      UI/window-basic-stats.cpp
  33. 6 11
      UI/window-basic-transform.cpp
  34. 1 3
      UI/window-missing-files.cpp
  35. 5 10
      UI/window-projector.cpp
  36. 46 0
      libobs/obs.hpp

+ 14 - 14
UI/adv-audio-control.cpp

@@ -445,9 +445,9 @@ void OBSAdvAudioCtrl::volumeChanged(double db)
 	obs_source_set_volume(source, val);
 	obs_source_set_volume(source, val);
 
 
 	auto undo_redo = [](const std::string &name, float val) {
 	auto undo_redo = [](const std::string &name, float val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_volume(source, val);
 		obs_source_set_volume(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);
@@ -468,9 +468,9 @@ void OBSAdvAudioCtrl::percentChanged(int percent)
 	obs_source_set_volume(source, val);
 	obs_source_set_volume(source, val);
 
 
 	auto undo_redo = [](const std::string &name, float val) {
 	auto undo_redo = [](const std::string &name, float val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_volume(source, val);
 		obs_source_set_volume(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);
@@ -507,9 +507,9 @@ void OBSAdvAudioCtrl::downmixMonoChanged(bool val)
 	obs_source_set_flags(source, flags);
 	obs_source_set_flags(source, flags);
 
 
 	auto undo_redo = [](const std::string &name, bool val) {
 	auto undo_redo = [](const std::string &name, bool val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		set_mono(source, val);
 		set_mono(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	QString text = QTStr(val ? "Undo.ForceMono.On" : "Undo.ForceMono.Off");
 	QString text = QTStr(val ? "Undo.ForceMono.On" : "Undo.ForceMono.Off");
@@ -536,9 +536,9 @@ void OBSAdvAudioCtrl::balanceChanged(int val)
 	obs_source_set_balance_value(source, bal);
 	obs_source_set_balance_value(source, bal);
 
 
 	auto undo_redo = [](const std::string &name, float val) {
 	auto undo_redo = [](const std::string &name, float val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_balance_value(source, val);
 		obs_source_set_balance_value(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);
@@ -565,9 +565,9 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
 	obs_source_set_sync_offset(source, val);
 	obs_source_set_sync_offset(source, val);
 
 
 	auto undo_redo = [](const std::string &name, int64_t val) {
 	auto undo_redo = [](const std::string &name, int64_t val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_sync_offset(source, val);
 		obs_source_set_sync_offset(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);
@@ -605,9 +605,9 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
 	     name ? name : "(null)", type);
 	     name ? name : "(null)", type);
 
 
 	auto undo_redo = [](const std::string &name, obs_monitoring_type val) {
 	auto undo_redo = [](const std::string &name, obs_monitoring_type val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_monitoring_type(source, val);
 		obs_source_set_monitoring_type(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	OBSBasic::Get()->undo_s.add_action(
 	OBSBasic::Get()->undo_s.add_action(
@@ -630,9 +630,9 @@ static inline void setMixer(obs_source_t *source, const int mixerIdx,
 	obs_source_set_audio_mixers(source, new_mixers);
 	obs_source_set_audio_mixers(source, new_mixers);
 
 
 	auto undo_redo = [](const std::string &name, uint32_t mixers) {
 	auto undo_redo = [](const std::string &name, uint32_t mixers) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_audio_mixers(source, mixers);
 		obs_source_set_audio_mixers(source, mixers);
-		obs_source_release(source);
 	};
 	};
 
 
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);

+ 4 - 4
UI/api-interface.cpp

@@ -390,21 +390,21 @@ struct OBSStudioAPI : obs_frontend_callbacks {
 
 
 	obs_output_t *obs_frontend_get_streaming_output(void) override
 	obs_output_t *obs_frontend_get_streaming_output(void) override
 	{
 	{
-		OBSOutput output = main->outputHandler->streamOutput;
+		OBSOutput output = main->outputHandler->streamOutput.Get();
 		obs_output_addref(output);
 		obs_output_addref(output);
 		return output;
 		return output;
 	}
 	}
 
 
 	obs_output_t *obs_frontend_get_recording_output(void) override
 	obs_output_t *obs_frontend_get_recording_output(void) override
 	{
 	{
-		OBSOutput out = main->outputHandler->fileOutput;
+		OBSOutput out = main->outputHandler->fileOutput.Get();
 		obs_output_addref(out);
 		obs_output_addref(out);
 		return out;
 		return out;
 	}
 	}
 
 
 	obs_output_t *obs_frontend_get_replay_buffer_output(void) override
 	obs_output_t *obs_frontend_get_replay_buffer_output(void) override
 	{
 	{
-		OBSOutput out = main->outputHandler->replayBuffer;
+		OBSOutput out = main->outputHandler->replayBuffer.Get();
 		obs_output_addref(out);
 		obs_output_addref(out);
 		return out;
 		return out;
 	}
 	}
@@ -584,7 +584,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
 
 
 	obs_output_t *obs_frontend_get_virtualcam_output(void) override
 	obs_output_t *obs_frontend_get_virtualcam_output(void) override
 	{
 	{
-		OBSOutput output = main->outputHandler->virtualCam;
+		OBSOutput output = main->outputHandler->virtualCam.Get();
 		obs_output_addref(output);
 		obs_output_addref(output);
 		return output;
 		return output;
 	}
 	}

+ 1 - 3
UI/auth-oauth.cpp

@@ -314,7 +314,7 @@ void OAuthStreamKey::OnStreamConfig()
 	OBSBasic *main = OBSBasic::Get();
 	OBSBasic *main = OBSBasic::Get();
 	obs_service_t *service = main->GetService();
 	obs_service_t *service = main->GetService();
 
 
-	obs_data_t *settings = obs_service_get_settings(service);
+	OBSDataAutoRelease settings = obs_service_get_settings(service);
 
 
 	bool bwtest = obs_data_get_bool(settings, "bwtest");
 	bool bwtest = obs_data_get_bool(settings, "bwtest");
 
 
@@ -325,6 +325,4 @@ void OAuthStreamKey::OnStreamConfig()
 		obs_data_set_string(settings, "key", key_.c_str());
 		obs_data_set_string(settings, "key", key_.c_str());
 
 
 	obs_service_update(service, settings);
 	obs_service_update(service, settings);
-
-	obs_data_release(settings);
 }
 }

+ 25 - 50
UI/context-bar-controls.cpp

@@ -37,12 +37,10 @@ SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
 void SourceToolbar::SaveOldProperties(obs_source_t *source)
 void SourceToolbar::SaveOldProperties(obs_source_t *source)
 {
 {
 	oldData = obs_data_create();
 	oldData = obs_data_create();
-	obs_data_release(oldData);
 
 
-	obs_data_t *oldSettings = obs_source_get_settings(source);
+	OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
 	obs_data_apply(oldData, oldSettings);
 	obs_data_apply(oldData, oldSettings);
 	obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source));
 	obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source));
-	obs_data_release(oldSettings);
 }
 }
 
 
 void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
 void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
@@ -60,24 +58,21 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
 	std::string scene_name = obs_source_get_name(currentSceneSource);
 	std::string scene_name = obs_source_get_name(currentSceneSource);
 	auto undo_redo = [scene_name,
 	auto undo_redo = [scene_name,
 			  main = std::move(main)](const std::string &data) {
 			  main = std::move(main)](const std::string &data) {
-		obs_data_t *settings = obs_data_create_from_json(data.c_str());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSDataAutoRelease settings =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			obs_data_get_string(settings, "undo_sname"));
 			obs_data_get_string(settings, "undo_sname"));
 		obs_source_reset_settings(source, settings);
 		obs_source_reset_settings(source, settings);
 
 
-		obs_source_t *scene_source =
+		OBSSourceAutoRelease scene_source =
 			obs_get_source_by_name(scene_name.c_str());
 			obs_get_source_by_name(scene_name.c_str());
-		main->SetCurrentScene(scene_source, true);
-		obs_source_release(scene_source);
-
-		obs_data_release(settings);
-		obs_source_release(source);
+		main->SetCurrentScene(scene_source.Get(), true);
 
 
 		main->UpdateContextBar();
 		main->UpdateContextBar();
 	};
 	};
 
 
-	OBSData new_settings = obs_data_create();
-	OBSData curr_settings = obs_source_get_settings(source);
+	OBSDataAutoRelease new_settings = obs_data_create();
+	OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
 	obs_data_apply(new_settings, curr_settings);
 	obs_data_apply(new_settings, curr_settings);
 	obs_data_set_string(new_settings, "undo_sname",
 	obs_data_set_string(new_settings, "undo_sname",
 			    obs_source_get_name(source));
 			    obs_source_get_name(source));
@@ -91,8 +86,6 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
 				.arg(obs_source_get_name(source)),
 				.arg(obs_source_get_name(source)),
 			undo_redo, undo_redo, undo_data, redo_data, repeatable);
 			undo_redo, undo_redo, undo_data, redo_data, repeatable);
 
 
-	obs_data_release(new_settings);
-	obs_data_release(curr_settings);
 	oldData = nullptr;
 	oldData = nullptr;
 }
 }
 
 
@@ -165,13 +158,12 @@ void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source,
 {
 {
 	std::string cur_id;
 	std::string cur_id;
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	if (is_int) {
 	if (is_int) {
 		cur_id = std::to_string(obs_data_get_int(settings, prop_name));
 		cur_id = std::to_string(obs_data_get_int(settings, prop_name));
 	} else {
 	} else {
 		cur_id = obs_data_get_string(settings, prop_name);
 		cur_id = obs_data_get_string(settings, prop_name);
 	}
 	}
-	obs_data_release(settings);
 
 
 	combo->blockSignals(true);
 	combo->blockSignals(true);
 
 
@@ -209,14 +201,13 @@ void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx,
 {
 {
 	QString id = combo->itemData(idx).toString();
 	QString id = combo->itemData(idx).toString();
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	if (is_int) {
 	if (is_int) {
 		obs_data_set_int(settings, prop_name, id.toInt());
 		obs_data_set_int(settings, prop_name, id.toInt());
 	} else {
 	} else {
 		obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
 		obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
 	}
 	}
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 }
 }
 
 
 void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
 void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
@@ -328,9 +319,8 @@ DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
 	ui->deviceLabel = nullptr;
 	ui->deviceLabel = nullptr;
 	ui->device = nullptr;
 	ui->device = nullptr;
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	active = obs_data_get_bool(settings, "active");
 	active = obs_data_get_bool(settings, "active");
-	obs_data_release(settings);
 
 
 	obs_module_t *mod = obs_get_module("win-dshow");
 	obs_module_t *mod = obs_get_module("win-dshow");
 	activateText = obs_module_get_locale_text(mod, "Activate");
 	activateText = obs_module_get_locale_text(mod, "Activate");
@@ -351,9 +341,8 @@ void DeviceCaptureToolbar::on_activateButton_clicked()
 		return;
 		return;
 	}
 	}
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	bool now_active = obs_data_get_bool(settings, "active");
 	bool now_active = obs_data_get_bool(settings, "active");
-	obs_data_release(settings);
 
 
 	bool desyncedSetting = now_active != active;
 	bool desyncedSetting = now_active != active;
 
 
@@ -388,10 +377,9 @@ GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
 	ui->windowLabel->setText(
 	ui->windowLabel->setText(
 		obs_module_get_locale_text(mod, "WindowCapture.Window"));
 		obs_module_get_locale_text(mod, "WindowCapture.Window"));
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	std::string cur_mode = obs_data_get_string(settings, "capture_mode");
 	std::string cur_mode = obs_data_get_string(settings, "capture_mode");
 	std::string cur_window = obs_data_get_string(settings, "window");
 	std::string cur_window = obs_data_get_string(settings, "window");
-	obs_data_release(settings);
 
 
 	ui->mode->blockSignals(true);
 	ui->mode->blockSignals(true);
 	p = obs_properties_get(props.get(), "capture_mode");
 	p = obs_properties_get(props.get(), "capture_mode");
@@ -435,10 +423,9 @@ void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
 	QString id = ui->mode->itemData(idx).toString();
 	QString id = ui->mode->itemData(idx).toString();
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
 	obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 
 
 	UpdateWindowVisibility();
 	UpdateWindowVisibility();
@@ -454,10 +441,9 @@ void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
 	QString id = ui->window->itemData(idx).toString();
 	QString id = ui->window->itemData(idx).toString();
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "window", QT_TO_UTF8(id));
 	obs_data_set_string(settings, "window", QT_TO_UTF8(id));
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 }
 }
 
 
@@ -471,9 +457,8 @@ ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
 	obs_module_t *mod = obs_get_module("image-source");
 	obs_module_t *mod = obs_get_module("image-source");
 	ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
 	ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	std::string file = obs_data_get_string(settings, "file");
 	std::string file = obs_data_get_string(settings, "file");
-	obs_data_release(settings);
 
 
 	ui->path->setText(file.c_str());
 	ui->path->setText(file.c_str());
 }
 }
@@ -503,10 +488,9 @@ void ImageSourceToolbar::on_browse_clicked()
 	ui->path->setText(path);
 	ui->path->setText(path);
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "file", QT_TO_UTF8(path));
 	obs_data_set_string(settings, "file", QT_TO_UTF8(path));
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 }
 }
 
 
@@ -533,9 +517,8 @@ ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
 {
 {
 	ui->setupUi(this);
 	ui->setupUi(this);
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 	unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
 	unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
-	obs_data_release(settings);
 
 
 	color = color_from_int(val);
 	color = color_from_int(val);
 	UpdateColor();
 	UpdateColor();
@@ -589,10 +572,9 @@ void ColorSourceToolbar::on_choose_clicked()
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_int(settings, "color", color_to_int(color));
 	obs_data_set_int(settings, "color", color_to_int(color));
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 
 
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 }
 }
@@ -606,16 +588,15 @@ TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
 {
 {
 	ui->setupUi(this);
 	ui->setupUi(this);
 
 
-	obs_data_t *settings = obs_source_get_settings(source);
+	OBSDataAutoRelease settings = obs_source_get_settings(source);
 
 
 	const char *id = obs_source_get_unversioned_id(source);
 	const char *id = obs_source_get_unversioned_id(source);
 	bool ft2 = strcmp(id, "text_ft2_source") == 0;
 	bool ft2 = strcmp(id, "text_ft2_source") == 0;
 	bool read_from_file = obs_data_get_bool(
 	bool read_from_file = obs_data_get_bool(
 		settings, ft2 ? "from_file" : "read_from_file");
 		settings, ft2 ? "from_file" : "read_from_file");
 
 
-	obs_data_t *font_obj = obs_data_get_obj(settings, "font");
+	OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
 	MakeQFont(font_obj, font);
 	MakeQFont(font_obj, font);
-	obs_data_release(font_obj);
 
 
 	// Use "color1" if it's a freetype source and "color" elsewise
 	// Use "color1" if it's a freetype source and "color" elsewise
 	unsigned int val = (unsigned int)obs_data_get_int(
 	unsigned int val = (unsigned int)obs_data_get_int(
@@ -634,8 +615,6 @@ TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
 	ui->text->setVisible(single_line);
 	ui->text->setVisible(single_line);
 	if (single_line)
 	if (single_line)
 		ui->text->setText(text);
 		ui->text->setText(text);
-
-	obs_data_release(settings);
 }
 }
 
 
 TextSourceToolbar::~TextSourceToolbar()
 TextSourceToolbar::~TextSourceToolbar()
@@ -664,7 +643,7 @@ void TextSourceToolbar::on_selectFont_clicked()
 		return;
 		return;
 	}
 	}
 
 
-	obs_data_t *font_obj = obs_data_create();
+	OBSDataAutoRelease font_obj = obs_data_create();
 
 
 	obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
 	obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
 	obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
 	obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
@@ -677,13 +656,11 @@ void TextSourceToolbar::on_selectFont_clicked()
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_obj(settings, "font", font_obj);
 	obs_data_set_obj(settings, "font", font_obj);
-	obs_data_release(font_obj);
 
 
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 
 
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 }
 }
@@ -719,7 +696,7 @@ void TextSourceToolbar::on_selectColor_clicked()
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	if (freetype) {
 	if (freetype) {
 		obs_data_set_int(settings, "color1", color_to_int(color));
 		obs_data_set_int(settings, "color1", color_to_int(color));
 		obs_data_set_int(settings, "color2", color_to_int(color));
 		obs_data_set_int(settings, "color2", color_to_int(color));
@@ -727,7 +704,6 @@ void TextSourceToolbar::on_selectColor_clicked()
 		obs_data_set_int(settings, "color", color_to_int(color));
 		obs_data_set_int(settings, "color", color_to_int(color));
 	}
 	}
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 
 
 	SetUndoProperties(source);
 	SetUndoProperties(source);
 }
 }
@@ -741,10 +717,9 @@ void TextSourceToolbar::on_text_textChanged()
 
 
 	SaveOldProperties(source);
 	SaveOldProperties(source);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "text", QT_TO_UTF8(ui->text->text()));
 	obs_data_set_string(settings, "text", QT_TO_UTF8(ui->text->text()));
 	obs_source_update(source, settings);
 	obs_source_update(source, settings);
-	obs_data_release(settings);
 
 
 	SetUndoProperties(source, true);
 	SetUndoProperties(source, true);
 }
 }

+ 1 - 1
UI/context-bar-controls.hpp

@@ -22,7 +22,7 @@ protected:
 		std::unique_ptr<obs_properties_t, properties_delete_t>;
 		std::unique_ptr<obs_properties_t, properties_delete_t>;
 
 
 	properties_t props;
 	properties_t props;
-	OBSData oldData;
+	OBSDataAutoRelease oldData;
 
 
 	void SaveOldProperties(obs_source_t *source);
 	void SaveOldProperties(obs_source_t *source);
 	void SetUndoProperties(obs_source_t *source, bool repeatable = false);
 	void SetUndoProperties(obs_source_t *source, bool repeatable = false);

+ 16 - 32
UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp

@@ -33,9 +33,7 @@ struct SceneSwitch {
 
 
 static inline bool WeakSourceValid(obs_weak_source_t *ws)
 static inline bool WeakSourceValid(obs_weak_source_t *ws)
 {
 {
-	obs_source_t *source = obs_weak_source_get_source(ws);
-	if (source)
-		obs_source_release(source);
+	OBSSourceAutoRelease source = obs_weak_source_get_source(ws);
 	return !!source;
 	return !!source;
 }
 }
 
 
@@ -268,13 +266,11 @@ void SceneSwitcher::on_startAtLaunch_toggled(bool value)
 
 
 void SceneSwitcher::UpdateNonMatchingScene(const QString &name)
 void SceneSwitcher::UpdateNonMatchingScene(const QString &name)
 {
 {
-	obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
-	obs_weak_source_t *ws = obs_source_get_weak_source(scene);
+	OBSSourceAutoRelease scene =
+		obs_get_source_by_name(name.toUtf8().constData());
+	OBSWeakSourceAutoRelease ws = obs_source_get_weak_source(scene);
 
 
-	switcher->nonMatchingScene = ws;
-
-	obs_weak_source_release(ws);
-	obs_source_release(scene);
+	switcher->nonMatchingScene = ws.Get();
 }
 }
 
 
 void SceneSwitcher::on_noMatchDontSwitch_clicked()
 void SceneSwitcher::on_noMatchDontSwitch_clicked()
@@ -341,15 +337,15 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
 {
 {
 	if (saving) {
 	if (saving) {
 		lock_guard<mutex> lock(switcher->m);
 		lock_guard<mutex> lock(switcher->m);
-		obs_data_t *obj = obs_data_create();
-		obs_data_array_t *array = obs_data_array_create();
+		OBSDataAutoRelease obj = obs_data_create();
+		OBSDataArrayAutoRelease array = obs_data_array_create();
 
 
 		switcher->Prune();
 		switcher->Prune();
 
 
 		for (SceneSwitch &s : switcher->switches) {
 		for (SceneSwitch &s : switcher->switches) {
-			obs_data_t *array_obj = obs_data_create();
+			OBSDataAutoRelease array_obj = obs_data_create();
 
 
-			obs_source_t *source =
+			OBSSourceAutoRelease source =
 				obs_weak_source_get_source(s.scene);
 				obs_weak_source_get_source(s.scene);
 			if (source) {
 			if (source) {
 				const char *n = obs_source_get_name(source);
 				const char *n = obs_source_get_name(source);
@@ -357,10 +353,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
 				obs_data_set_string(array_obj, "window_title",
 				obs_data_set_string(array_obj, "window_title",
 						    s.window.c_str());
 						    s.window.c_str());
 				obs_data_array_push_back(array, array_obj);
 				obs_data_array_push_back(array, array_obj);
-				obs_source_release(source);
 			}
 			}
-
-			obs_data_release(array_obj);
 		}
 		}
 
 
 		string nonMatchingSceneName =
 		string nonMatchingSceneName =
@@ -375,15 +368,13 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
 		obs_data_set_array(obj, "switches", array);
 		obs_data_set_array(obj, "switches", array);
 
 
 		obs_data_set_obj(save_data, "auto-scene-switcher", obj);
 		obs_data_set_obj(save_data, "auto-scene-switcher", obj);
-
-		obs_data_array_release(array);
-		obs_data_release(obj);
 	} else {
 	} else {
 		switcher->m.lock();
 		switcher->m.lock();
 
 
-		obs_data_t *obj =
+		OBSDataAutoRelease obj =
 			obs_data_get_obj(save_data, "auto-scene-switcher");
 			obs_data_get_obj(save_data, "auto-scene-switcher");
-		obs_data_array_t *array = obs_data_get_array(obj, "switches");
+		OBSDataArrayAutoRelease array =
+			obs_data_get_array(obj, "switches");
 		size_t count = obs_data_array_count(array);
 		size_t count = obs_data_array_count(array);
 
 
 		if (!obj)
 		if (!obj)
@@ -404,7 +395,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
 		switcher->switches.clear();
 		switcher->switches.clear();
 
 
 		for (size_t i = 0; i < count; i++) {
 		for (size_t i = 0; i < count; i++) {
-			obs_data_t *array_obj = obs_data_array_item(array, i);
+			OBSDataAutoRelease array_obj =
+				obs_data_array_item(array, i);
 
 
 			const char *scene =
 			const char *scene =
 				obs_data_get_string(array_obj, "scene");
 				obs_data_get_string(array_obj, "scene");
@@ -413,13 +405,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
 
 
 			switcher->switches.emplace_back(
 			switcher->switches.emplace_back(
 				GetWeakSourceByName(scene), window);
 				GetWeakSourceByName(scene), window);
-
-			obs_data_release(array_obj);
 		}
 		}
 
 
-		obs_data_array_release(array);
-		obs_data_release(obj);
-
 		switcher->m.unlock();
 		switcher->m.unlock();
 
 
 		if (active)
 		if (active)
@@ -484,16 +471,13 @@ void SwitcherData::Thread()
 			}
 			}
 
 
 			if (match) {
 			if (match) {
-				obs_source_t *source =
+				OBSSourceAutoRelease source =
 					obs_weak_source_get_source(scene);
 					obs_weak_source_get_source(scene);
-				obs_source_t *currentSource =
+				OBSSourceAutoRelease currentSource =
 					obs_frontend_get_current_scene();
 					obs_frontend_get_current_scene();
 
 
 				if (source && source != currentSource)
 				if (source && source != currentSource)
 					obs_frontend_set_current_scene(source);
 					obs_frontend_set_current_scene(source);
-
-				obs_source_release(currentSource);
-				obs_source_release(source);
 			}
 			}
 		}
 		}
 
 

+ 4 - 6
UI/frontend-plugins/frontend-tools/captions.cpp

@@ -226,10 +226,9 @@ void CaptionsDialog::on_provider_currentIndexChanged(int idx)
 
 
 static void caption_text(const std::string &text)
 static void caption_text(const std::string &text)
 {
 {
-	obs_output *output = obs_frontend_get_streaming_output();
+	OBSOutputAutoRelease output = obs_frontend_get_streaming_output();
 	if (output) {
 	if (output) {
 		obs_output_output_caption_text1(output, text.c_str());
 		obs_output_output_caption_text1(output, text.c_str());
-		obs_output_release(output);
 	}
 	}
 }
 }
 
 
@@ -396,7 +395,7 @@ static void obs_event(enum obs_frontend_event event, void *)
 static void save_caption_data(obs_data_t *save_data, bool saving, void *)
 static void save_caption_data(obs_data_t *save_data, bool saving, void *)
 {
 {
 	if (saving) {
 	if (saving) {
-		obs_data_t *obj = obs_data_create();
+		OBSDataAutoRelease obj = obs_data_create();
 
 
 		obs_data_set_string(obj, "source",
 		obs_data_set_string(obj, "source",
 				    captions->source_name.c_str());
 				    captions->source_name.c_str());
@@ -406,11 +405,11 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void *)
 				    captions->handler_id.c_str());
 				    captions->handler_id.c_str());
 
 
 		obs_data_set_obj(save_data, "captions", obj);
 		obs_data_set_obj(save_data, "captions", obj);
-		obs_data_release(obj);
 	} else {
 	} else {
 		captions->stop();
 		captions->stop();
 
 
-		obs_data_t *obj = obs_data_get_obj(save_data, "captions");
+		OBSDataAutoRelease obj =
+			obs_data_get_obj(save_data, "captions");
 		if (!obj)
 		if (!obj)
 			obj = obs_data_create();
 			obj = obs_data_create();
 
 
@@ -424,7 +423,6 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void *)
 		captions->handler_id = obs_data_get_string(obj, "provider");
 		captions->handler_id = obs_data_get_string(obj, "provider");
 		captions->source =
 		captions->source =
 			GetWeakSourceByName(captions->source_name.c_str());
 			GetWeakSourceByName(captions->source_name.c_str());
-		obs_data_release(obj);
 
 
 		if (enabled)
 		if (enabled)
 			captions->start();
 			captions->start();

+ 3 - 6
UI/frontend-plugins/frontend-tools/output-timer.cpp

@@ -250,7 +250,7 @@ void OutputTimer::EventStopRecording()
 static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
 static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
 {
 {
 	if (saving) {
 	if (saving) {
-		obs_data_t *obj = obs_data_create();
+		OBSDataAutoRelease obj = obs_data_create();
 
 
 		obs_data_set_int(obj, "streamTimerHours",
 		obs_data_set_int(obj, "streamTimerHours",
 				 ot->ui->streamingTimerHours->value());
 				 ot->ui->streamingTimerHours->value());
@@ -275,10 +275,9 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
 				  ot->ui->pauseRecordTimer->isChecked());
 				  ot->ui->pauseRecordTimer->isChecked());
 
 
 		obs_data_set_obj(save_data, "output-timer", obj);
 		obs_data_set_obj(save_data, "output-timer", obj);
-
-		obs_data_release(obj);
 	} else {
 	} else {
-		obs_data_t *obj = obs_data_get_obj(save_data, "output-timer");
+		OBSDataAutoRelease obj =
+			obs_data_get_obj(save_data, "output-timer");
 
 
 		if (!obj)
 		if (!obj)
 			obj = obs_data_create();
 			obj = obs_data_create();
@@ -304,8 +303,6 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
 
 
 		ot->ui->pauseRecordTimer->setChecked(
 		ot->ui->pauseRecordTimer->setChecked(
 			obs_data_get_bool(obj, "pauseRecordTimer"));
 			obs_data_get_bool(obj, "pauseRecordTimer"));
-
-		obs_data_release(obj);
 	}
 	}
 }
 }
 
 

+ 13 - 24
UI/frontend-plugins/frontend-tools/scripts.cpp

@@ -243,8 +243,7 @@ void ScriptsTool::ReloadScript(const char *path)
 		if (strcmp(script_path, path) == 0) {
 		if (strcmp(script_path, path) == 0) {
 			obs_script_reload(script);
 			obs_script_reload(script);
 
 
-			OBSData settings = obs_data_create();
-			obs_data_release(settings);
+			OBSDataAutoRelease settings = obs_data_create();
 
 
 			obs_properties_t *prop =
 			obs_properties_t *prop =
 				obs_script_get_properties(script);
 				obs_script_get_properties(script);
@@ -275,9 +274,9 @@ void ScriptsTool::SetScriptDefaults(const char *path)
 	for (OBSScript &script : scriptData->scripts) {
 	for (OBSScript &script : scriptData->scripts) {
 		const char *script_path = obs_script_get_path(script);
 		const char *script_path = obs_script_get_path(script);
 		if (strcmp(script_path, path) == 0) {
 		if (strcmp(script_path, path) == 0) {
-			obs_data_t *settings = obs_script_get_settings(script);
+			OBSDataAutoRelease settings =
+				obs_script_get_settings(script);
 			obs_data_clear(settings);
 			obs_data_clear(settings);
-			obs_data_release(settings);
 
 
 			obs_script_update(script, nullptr);
 			obs_script_update(script, nullptr);
 			on_reloadScripts_clicked();
 			on_reloadScripts_clicked();
@@ -353,8 +352,7 @@ void ScriptsTool::on_addScripts_clicked()
 			item->setData(Qt::UserRole, QString(file));
 			item->setData(Qt::UserRole, QString(file));
 			ui->scripts->addItem(item);
 			ui->scripts->addItem(item);
 
 
-			OBSData settings = obs_data_create();
-			obs_data_release(settings);
+			OBSDataAutoRelease settings = obs_data_create();
 
 
 			obs_properties_t *prop =
 			obs_properties_t *prop =
 				obs_script_get_properties(script);
 				obs_script_get_properties(script);
@@ -499,11 +497,10 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
 		return;
 		return;
 	}
 	}
 
 
-	OBSData settings = obs_script_get_settings(script);
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_script_get_settings(script);
 
 
 	propertiesView = new OBSPropertiesView(
 	propertiesView = new OBSPropertiesView(
-		settings, script,
+		settings.Get(), script,
 		(PropertiesReloadCallback)obs_script_get_properties, nullptr,
 		(PropertiesReloadCallback)obs_script_get_properties, nullptr,
 		(PropertiesVisualUpdateCb)obs_script_update);
 		(PropertiesVisualUpdateCb)obs_script_update);
 	ui->propertiesLayout->addWidget(propertiesView);
 	ui->propertiesLayout->addWidget(propertiesView);
@@ -585,30 +582,26 @@ static void obs_event(enum obs_frontend_event event, void *)
 
 
 static void load_script_data(obs_data_t *load_data, bool, void *)
 static void load_script_data(obs_data_t *load_data, bool, void *)
 {
 {
-	obs_data_array_t *array = obs_data_get_array(load_data, "scripts-tool");
+	OBSDataArrayAutoRelease array =
+		obs_data_get_array(load_data, "scripts-tool");
 
 
 	delete scriptData;
 	delete scriptData;
 	scriptData = new ScriptData;
 	scriptData = new ScriptData;
 
 
 	size_t size = obs_data_array_count(array);
 	size_t size = obs_data_array_count(array);
 	for (size_t i = 0; i < size; i++) {
 	for (size_t i = 0; i < size; i++) {
-		obs_data_t *obj = obs_data_array_item(array, i);
+		OBSDataAutoRelease obj = obs_data_array_item(array, i);
 		const char *path = obs_data_get_string(obj, "path");
 		const char *path = obs_data_get_string(obj, "path");
-		obs_data_t *settings = obs_data_get_obj(obj, "settings");
+		OBSDataAutoRelease settings = obs_data_get_obj(obj, "settings");
 
 
 		obs_script_t *script = obs_script_create(path, settings);
 		obs_script_t *script = obs_script_create(path, settings);
 		if (script) {
 		if (script) {
 			scriptData->scripts.emplace_back(script);
 			scriptData->scripts.emplace_back(script);
 		}
 		}
-
-		obs_data_release(settings);
-		obs_data_release(obj);
 	}
 	}
 
 
 	if (scriptsWindow)
 	if (scriptsWindow)
 		scriptsWindow->RefreshLists();
 		scriptsWindow->RefreshLists();
-
-	obs_data_array_release(array);
 }
 }
 
 
 static void save_script_data(obs_data_t *save_data, bool saving, void *)
 static void save_script_data(obs_data_t *save_data, bool saving, void *)
@@ -616,23 +609,19 @@ static void save_script_data(obs_data_t *save_data, bool saving, void *)
 	if (!saving)
 	if (!saving)
 		return;
 		return;
 
 
-	obs_data_array_t *array = obs_data_array_create();
+	OBSDataArrayAutoRelease array = obs_data_array_create();
 
 
 	for (OBSScript &script : scriptData->scripts) {
 	for (OBSScript &script : scriptData->scripts) {
 		const char *script_path = obs_script_get_path(script);
 		const char *script_path = obs_script_get_path(script);
-		obs_data_t *settings = obs_script_save(script);
+		OBSDataAutoRelease settings = obs_script_save(script);
 
 
-		obs_data_t *obj = obs_data_create();
+		OBSDataAutoRelease obj = obs_data_create();
 		obs_data_set_string(obj, "path", script_path);
 		obs_data_set_string(obj, "path", script_path);
 		obs_data_set_obj(obj, "settings", settings);
 		obs_data_set_obj(obj, "settings", settings);
 		obs_data_array_push_back(array, obj);
 		obs_data_array_push_back(array, obj);
-		obs_data_release(obj);
-
-		obs_data_release(settings);
 	}
 	}
 
 
 	obs_data_set_array(save_data, "scripts-tool", array);
 	obs_data_set_array(save_data, "scripts-tool", array);
-	obs_data_array_release(array);
 }
 }
 
 
 static void script_log(void *, obs_script_t *script, int log_level,
 static void script_log(void *, obs_script_t *script, int log_level,

+ 4 - 8
UI/obs-app.cpp

@@ -643,17 +643,14 @@ static string GetSceneCollectionFileFromName(const char *name)
 		if (ent.directory)
 		if (ent.directory)
 			continue;
 			continue;
 
 
-		obs_data_t *data =
+		OBSDataAutoRelease data =
 			obs_data_create_from_json_file_safe(ent.path, "bak");
 			obs_data_create_from_json_file_safe(ent.path, "bak");
 		const char *curName = obs_data_get_string(data, "name");
 		const char *curName = obs_data_get_string(data, "name");
 
 
 		if (astrcmpi(name, curName) == 0) {
 		if (astrcmpi(name, curName) == 0) {
 			outputPath = ent.path;
 			outputPath = ent.path;
-			obs_data_release(data);
 			break;
 			break;
 		}
 		}
-
-		obs_data_release(data);
 	}
 	}
 
 
 	os_globfree(glob);
 	os_globfree(glob);
@@ -1446,10 +1443,9 @@ bool OBSApp::OBSInit()
 	bool browserHWAccel =
 	bool browserHWAccel =
 		config_get_bool(globalConfig, "General", "BrowserHWAccel");
 		config_get_bool(globalConfig, "General", "BrowserHWAccel");
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel);
 	obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel);
 	obs_apply_private_data(settings);
 	obs_apply_private_data(settings);
-	obs_data_release(settings);
 
 
 	blog(LOG_INFO, "Current Date/Time: %s",
 	blog(LOG_INFO, "Current Date/Time: %s",
 	     CurrentDateTimeString().c_str());
 	     CurrentDateTimeString().c_str());
@@ -2556,7 +2552,8 @@ static void convert_x264_settings(obs_data_t *data)
 
 
 static void convert_14_2_encoder_setting(const char *encoder, const char *file)
 static void convert_14_2_encoder_setting(const char *encoder, const char *file)
 {
 {
-	obs_data_t *data = obs_data_create_from_json_file_safe(file, "bak");
+	OBSDataAutoRelease data =
+		obs_data_create_from_json_file_safe(file, "bak");
 	obs_data_item_t *cbr_item = obs_data_item_byname(data, "cbr");
 	obs_data_item_t *cbr_item = obs_data_item_byname(data, "cbr");
 	obs_data_item_t *rc_item = obs_data_item_byname(data, "rate_control");
 	obs_data_item_t *rc_item = obs_data_item_byname(data, "rate_control");
 	bool modified = false;
 	bool modified = false;
@@ -2585,7 +2582,6 @@ static void convert_14_2_encoder_setting(const char *encoder, const char *file)
 
 
 	obs_data_item_release(&rc_item);
 	obs_data_item_release(&rc_item);
 	obs_data_item_release(&cbr_item);
 	obs_data_item_release(&cbr_item);
-	obs_data_release(data);
 }
 }
 
 
 static void upgrade_settings(void)
 static void upgrade_settings(void)

+ 6 - 15
UI/properties-view.cpp

@@ -587,7 +587,7 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
 					QFormLayout *layout, QLabel *&label)
 					QFormLayout *layout, QLabel *&label)
 {
 {
 	const char *name = obs_property_name(prop);
 	const char *name = obs_property_name(prop);
-	obs_data_array_t *array = obs_data_get_array(settings, name);
+	OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
 	QListWidget *list = new QListWidget();
 	QListWidget *list = new QListWidget();
 	size_t count = obs_data_array_count(array);
 	size_t count = obs_data_array_count(array);
 
 
@@ -599,12 +599,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
 	list->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 	list->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 
 
 	for (size_t i = 0; i < count; i++) {
 	for (size_t i = 0; i < count; i++) {
-		obs_data_t *item = obs_data_array_item(array, i);
+		OBSDataAutoRelease item = obs_data_array_item(array, i);
 		list->addItem(QT_UTF8(obs_data_get_string(item, "value")));
 		list->addItem(QT_UTF8(obs_data_get_string(item, "value")));
 		QListWidgetItem *const list_item = list->item((int)i);
 		QListWidgetItem *const list_item = list->item((int)i);
 		list_item->setSelected(obs_data_get_bool(item, "selected"));
 		list_item->setSelected(obs_data_get_bool(item, "selected"));
 		list_item->setHidden(obs_data_get_bool(item, "hidden"));
 		list_item->setHidden(obs_data_get_bool(item, "hidden"));
-		obs_data_release(item);
 	}
 	}
 
 
 	WidgetInfo *info = new WidgetInfo(this, prop, list);
 	WidgetInfo *info = new WidgetInfo(this, prop, list);
@@ -636,8 +635,6 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
 
 
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
 	layout->addRow(label, subLayout);
 	layout->addRow(label, subLayout);
-
-	obs_data_array_release(array);
 }
 }
 
 
 QWidget *OBSPropertiesView::AddButton(obs_property_t *prop)
 QWidget *OBSPropertiesView::AddButton(obs_property_t *prop)
@@ -752,7 +749,7 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
 				QLabel *&label)
 				QLabel *&label)
 {
 {
 	const char *name = obs_property_name(prop);
 	const char *name = obs_property_name(prop);
-	obs_data_t *font_obj = obs_data_get_obj(settings, name);
+	OBSDataAutoRelease font_obj = obs_data_get_obj(settings, name);
 	const char *face = obs_data_get_string(font_obj, "face");
 	const char *face = obs_data_get_string(font_obj, "face");
 	const char *style = obs_data_get_string(font_obj, "style");
 	const char *style = obs_data_get_string(font_obj, "style");
 	QPushButton *button = new QPushButton;
 	QPushButton *button = new QPushButton;
@@ -789,8 +786,6 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
 
 
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
 	layout->addRow(label, subLayout);
 	layout->addRow(label, subLayout);
-
-	obs_data_release(font_obj);
 }
 }
 
 
 namespace std {
 namespace std {
@@ -1790,7 +1785,7 @@ bool WidgetInfo::ColorAlphaChanged(const char *setting)
 
 
 bool WidgetInfo::FontChanged(const char *setting)
 bool WidgetInfo::FontChanged(const char *setting)
 {
 {
-	obs_data_t *font_obj = obs_data_get_obj(view->settings, setting);
+	OBSDataAutoRelease font_obj = obs_data_get_obj(view->settings, setting);
 	bool success;
 	bool success;
 	uint32_t flags;
 	uint32_t flags;
 	QFont font;
 	QFont font;
@@ -1809,7 +1804,6 @@ bool WidgetInfo::FontChanged(const char *setting)
 		MakeQFont(font_obj, font);
 		MakeQFont(font_obj, font);
 		font = QFontDialog::getFont(&success, font, view, "Pick a Font",
 		font = QFontDialog::getFont(&success, font, view, "Pick a Font",
 					    options);
 					    options);
-		obs_data_release(font_obj);
 	}
 	}
 
 
 	if (!success)
 	if (!success)
@@ -1833,7 +1827,6 @@ bool WidgetInfo::FontChanged(const char *setting)
 	label->setText(QString("%1 %2").arg(font.family(), font.styleName()));
 	label->setText(QString("%1 %2").arg(font.family(), font.styleName()));
 
 
 	obs_data_set_obj(view->settings, setting, font_obj);
 	obs_data_set_obj(view->settings, setting, font_obj);
-	obs_data_release(font_obj);
 	return true;
 	return true;
 }
 }
 
 
@@ -1862,21 +1855,19 @@ void WidgetInfo::EditableListChanged()
 {
 {
 	const char *setting = obs_property_name(property);
 	const char *setting = obs_property_name(property);
 	QListWidget *list = reinterpret_cast<QListWidget *>(widget);
 	QListWidget *list = reinterpret_cast<QListWidget *>(widget);
-	obs_data_array *array = obs_data_array_create();
+	OBSDataArrayAutoRelease array = obs_data_array_create();
 
 
 	for (int i = 0; i < list->count(); i++) {
 	for (int i = 0; i < list->count(); i++) {
 		QListWidgetItem *item = list->item(i);
 		QListWidgetItem *item = list->item(i);
-		obs_data_t *arrayItem = obs_data_create();
+		OBSDataAutoRelease arrayItem = obs_data_create();
 		obs_data_set_string(arrayItem, "value",
 		obs_data_set_string(arrayItem, "value",
 				    QT_TO_UTF8(item->text()));
 				    QT_TO_UTF8(item->text()));
 		obs_data_set_bool(arrayItem, "selected", item->isSelected());
 		obs_data_set_bool(arrayItem, "selected", item->isSelected());
 		obs_data_set_bool(arrayItem, "hidden", item->isHidden());
 		obs_data_set_bool(arrayItem, "hidden", item->isHidden());
 		obs_data_array_push_back(array, arrayItem);
 		obs_data_array_push_back(array, arrayItem);
-		obs_data_release(arrayItem);
 	}
 	}
 
 
 	obs_data_set_array(view->settings, setting, array);
 	obs_data_set_array(view->settings, setting, array);
-	obs_data_array_release(array);
 
 
 	ControlChanged();
 	ControlChanged();
 }
 }

+ 3 - 5
UI/qt-wrappers.cpp

@@ -189,9 +189,9 @@ QDataStream &operator>>(QDataStream &in, OBSScene &scene)
 
 
 	in >> sceneName;
 	in >> sceneName;
 
 
-	obs_source_t *source = obs_get_source_by_name(QT_TO_UTF8(sceneName));
+	OBSSourceAutoRelease source =
+		obs_get_source_by_name(QT_TO_UTF8(sceneName));
 	scene = obs_scene_from_source(source);
 	scene = obs_scene_from_source(source);
-	obs_source_release(source);
 
 
 	return in;
 	return in;
 }
 }
@@ -211,14 +211,12 @@ QDataStream &operator>>(QDataStream &in, OBSSceneItem &si)
 
 
 	in >> sceneName >> sourceName;
 	in >> sceneName >> sourceName;
 
 
-	obs_source_t *sceneSource =
+	OBSSourceAutoRelease sceneSource =
 		obs_get_source_by_name(QT_TO_UTF8(sceneName));
 		obs_get_source_by_name(QT_TO_UTF8(sceneName));
 
 
 	obs_scene_t *scene = obs_scene_from_source(sceneSource);
 	obs_scene_t *scene = obs_scene_from_source(sceneSource);
 	si = obs_scene_find_source(scene, QT_TO_UTF8(sourceName));
 	si = obs_scene_find_source(scene, QT_TO_UTF8(sourceName));
 
 
-	obs_source_release(sceneSource);
-
 	return in;
 	return in;
 }
 }
 
 

+ 21 - 28
UI/source-tree.cpp

@@ -41,7 +41,8 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 	obs_source_t *source = obs_sceneitem_get_source(sceneitem);
 	obs_source_t *source = obs_sceneitem_get_source(sceneitem);
 	const char *name = obs_source_get_name(source);
 	const char *name = obs_source_get_name(source);
 
 
-	obs_data_t *privData = obs_sceneitem_get_private_settings(sceneitem);
+	OBSDataAutoRelease privData =
+		obs_sceneitem_get_private_settings(sceneitem);
 	int preset = obs_data_get_int(privData, "color-preset");
 	int preset = obs_data_get_int(privData, "color-preset");
 
 
 	if (preset == 1) {
 	if (preset == 1) {
@@ -56,8 +57,6 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 		setStyleSheet("background: none");
 		setStyleSheet("background: none");
 	}
 	}
 
 
-	obs_data_release(privData);
-
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 	const char *id = obs_source_get_id(source);
 	const char *id = obs_source_get_id(source);
 
 
@@ -142,13 +141,13 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 
 
 		auto undo_redo = [](const std::string &name, int64_t id,
 		auto undo_redo = [](const std::string &name, int64_t id,
 				    bool val) {
 				    bool val) {
-			obs_source_t *s = obs_get_source_by_name(name.c_str());
+			OBSSourceAutoRelease s =
+				obs_get_source_by_name(name.c_str());
 			obs_scene_t *sc = obs_group_or_scene_from_source(s);
 			obs_scene_t *sc = obs_group_or_scene_from_source(s);
 			obs_sceneitem_t *si =
 			obs_sceneitem_t *si =
 				obs_scene_find_sceneitem_by_id(sc, id);
 				obs_scene_find_sceneitem_by_id(sc, id);
 			if (si)
 			if (si)
 				obs_sceneitem_set_visible(si, val);
 				obs_sceneitem_set_visible(si, val);
-			obs_source_release(s);
 		};
 		};
 
 
 		QString str = QTStr(val ? "Undo.ShowSceneItem"
 		QString str = QTStr(val ? "Undo.ShowSceneItem"
@@ -439,8 +438,8 @@ void SourceTreeItem::ExitEditModeInternal(bool save)
 	/* ----------------------------------------- */
 	/* ----------------------------------------- */
 	/* check for existing source                 */
 	/* check for existing source                 */
 
 
-	obs_source_t *existingSource = obs_get_source_by_name(newName.c_str());
-	obs_source_release(existingSource);
+	OBSSourceAutoRelease existingSource =
+		obs_get_source_by_name(newName.c_str());
 	bool exists = !!existingSource;
 	bool exists = !!existingSource;
 
 
 	if (exists) {
 	if (exists) {
@@ -457,27 +456,25 @@ void SourceTreeItem::ExitEditModeInternal(bool save)
 	std::string scene_name =
 	std::string scene_name =
 		obs_source_get_name(main->GetCurrentSceneSource());
 		obs_source_get_name(main->GetCurrentSceneSource());
 	auto undo = [scene_name, prevName, main](const std::string &data) {
 	auto undo = [scene_name, prevName, main](const std::string &data) {
-		obs_source_t *source = obs_get_source_by_name(data.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(data.c_str());
 		obs_source_set_name(source, prevName.c_str());
 		obs_source_set_name(source, prevName.c_str());
-		obs_source_release(source);
 
 
-		obs_source_t *scene_source =
+		OBSSourceAutoRelease scene_source =
 			obs_get_source_by_name(scene_name.c_str());
 			obs_get_source_by_name(scene_name.c_str());
-		main->SetCurrentScene(scene_source, true);
-		obs_source_release(scene_source);
+		main->SetCurrentScene(scene_source.Get(), true);
 	};
 	};
 
 
 	std::string editedName = newName;
 	std::string editedName = newName;
 
 
 	auto redo = [scene_name, main, editedName](const std::string &data) {
 	auto redo = [scene_name, main, editedName](const std::string &data) {
-		obs_source_t *source = obs_get_source_by_name(data.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(data.c_str());
 		obs_source_set_name(source, editedName.c_str());
 		obs_source_set_name(source, editedName.c_str());
-		obs_source_release(source);
 
 
-		obs_source_t *scene_source =
+		OBSSourceAutoRelease scene_source =
 			obs_get_source_by_name(scene_name.c_str());
 			obs_get_source_by_name(scene_name.c_str());
-		main->SetCurrentScene(scene_source, true);
-		obs_source_release(scene_source);
+		main->SetCurrentScene(scene_source.Get(), true);
 	};
 	};
 
 
 	main->undo_s.add_action(QTStr("Undo.Rename").arg(newName.c_str()), undo,
 	main->undo_s.add_action(QTStr("Undo.Rename").arg(newName.c_str()), undo,
@@ -592,12 +589,11 @@ void SourceTreeItem::Update(bool force)
 #endif
 #endif
 		boxLayout->insertWidget(0, expand);
 		boxLayout->insertWidget(0, expand);
 
 
-		obs_data_t *data =
+		OBSDataAutoRelease data =
 			obs_sceneitem_get_private_settings(sceneitem);
 			obs_sceneitem_get_private_settings(sceneitem);
 		expand->blockSignals(true);
 		expand->blockSignals(true);
 		expand->setChecked(obs_data_get_bool(data, "collapsed"));
 		expand->setChecked(obs_data_get_bool(data, "collapsed"));
 		expand->blockSignals(false);
 		expand->blockSignals(false);
-		obs_data_release(data);
 
 
 		connect(expand, &QPushButton::toggled, this,
 		connect(expand, &QPushButton::toggled, this,
 			&SourceTreeItem::ExpandClicked);
 			&SourceTreeItem::ExpandClicked);
@@ -610,8 +606,7 @@ void SourceTreeItem::Update(bool force)
 
 
 void SourceTreeItem::ExpandClicked(bool checked)
 void SourceTreeItem::ExpandClicked(bool checked)
 {
 {
-	OBSData data = obs_sceneitem_get_private_settings(sceneitem);
-	obs_data_release(data);
+	OBSDataAutoRelease data = obs_sceneitem_get_private_settings(sceneitem);
 
 
 	obs_data_set_bool(data, "collapsed", checked);
 	obs_data_set_bool(data, "collapsed", checked);
 
 
@@ -670,7 +665,8 @@ static bool enumItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr)
 	}
 	}
 
 
 	if (obs_sceneitem_is_group(item)) {
 	if (obs_sceneitem_is_group(item)) {
-		obs_data_t *data = obs_sceneitem_get_private_settings(item);
+		OBSDataAutoRelease data =
+			obs_sceneitem_get_private_settings(item);
 
 
 		bool collapse = obs_data_get_bool(data, "collapsed");
 		bool collapse = obs_data_get_bool(data, "collapsed");
 		if (!collapse) {
 		if (!collapse) {
@@ -679,8 +675,6 @@ static bool enumItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr)
 
 
 			obs_scene_enum_items(scene, enumItem, &items);
 			obs_scene_enum_items(scene, enumItem, &items);
 		}
 		}
-
-		obs_data_release(data);
 	}
 	}
 
 
 	items.insert(0, item);
 	items.insert(0, item);
@@ -908,8 +902,8 @@ QString SourceTreeModel::GetNewGroupName()
 
 
 	int i = 2;
 	int i = 2;
 	for (;;) {
 	for (;;) {
-		obs_source_t *group = obs_get_source_by_name(QT_TO_UTF8(name));
-		obs_source_release(group);
+		OBSSourceAutoRelease group =
+			obs_get_source_by_name(QT_TO_UTF8(name));
 		if (!group)
 		if (!group)
 			break;
 			break;
 		name = QTStr("Basic.Main.Group").arg(QString::number(i++));
 		name = QTStr("Basic.Main.Group").arg(QString::number(i++));
@@ -1398,10 +1392,9 @@ void SourceTree::dropEvent(QDropEvent *event)
 	};
 	};
 
 
 	auto insertLastGroup = [&]() {
 	auto insertLastGroup = [&]() {
-		obs_data_t *data =
+		OBSDataAutoRelease data =
 			obs_sceneitem_get_private_settings(lastGroup);
 			obs_sceneitem_get_private_settings(lastGroup);
 		bool collapsed = obs_data_get_bool(data, "collapsed");
 		bool collapsed = obs_data_get_bool(data, "collapsed");
-		obs_data_release(data);
 
 
 		if (collapsed) {
 		if (collapsed) {
 			insertCollapsedIdx = 0;
 			insertCollapsedIdx = 0;

+ 4 - 4
UI/volume-control.cpp

@@ -68,9 +68,9 @@ void VolControl::SetMuted(bool checked)
 	obs_source_set_muted(source, checked);
 	obs_source_set_muted(source, checked);
 
 
 	auto undo_redo = [](const std::string &name, bool val) {
 	auto undo_redo = [](const std::string &name, bool val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_muted(source, val);
 		obs_source_set_muted(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	QString text =
 	QString text =
@@ -92,9 +92,9 @@ void VolControl::SliderChanged(int vol)
 	updateText();
 	updateText();
 
 
 	auto undo_redo = [](const std::string &name, float val) {
 	auto undo_redo = [](const std::string &name, float val) {
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 		obs_source_set_volume(source, val);
 		obs_source_set_volume(source, val);
-		obs_source_release(source);
 	};
 	};
 
 
 	float val = obs_source_get_volume(source);
 	float val = obs_source_get_volume(source);

+ 22 - 40
UI/window-basic-auto-config-test.cpp

@@ -119,8 +119,7 @@ void AutoConfigTestPage::StartRecordingEncoderStage()
 
 
 void AutoConfigTestPage::GetServers(std::vector<ServerInfo> &servers)
 void AutoConfigTestPage::GetServers(std::vector<ServerInfo> &servers)
 {
 {
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "service", wiz->serviceName.c_str());
 	obs_data_set_string(settings, "service", wiz->serviceName.c_str());
 
 
 	obs_properties_t *ppts = obs_get_service_properties("rtmp_common");
 	obs_properties_t *ppts = obs_get_service_properties("rtmp_common");
@@ -182,15 +181,12 @@ void AutoConfigTestPage::TestBandwidthThread()
 	const char *serverType = wiz->customServer ? "rtmp_custom"
 	const char *serverType = wiz->customServer ? "rtmp_custom"
 						   : "rtmp_common";
 						   : "rtmp_common";
 
 
-	OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
-						       nullptr, nullptr);
-	OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
-						       nullptr, 0, nullptr);
-	OBSService service = obs_service_create(serverType, "test_service",
-						nullptr, nullptr);
-	obs_encoder_release(vencoder);
-	obs_encoder_release(aencoder);
-	obs_service_release(service);
+	OBSEncoderAutoRelease vencoder = obs_video_encoder_create(
+		"obs_x264", "test_x264", nullptr, nullptr);
+	OBSEncoderAutoRelease aencoder = obs_audio_encoder_create(
+		"ffmpeg_aac", "test_aac", nullptr, 0, nullptr);
+	OBSServiceAutoRelease service = obs_service_create(
+		serverType, "test_service", nullptr, nullptr);
 
 
 	/* -----------------------------------*/
 	/* -----------------------------------*/
 	/* configure settings                 */
 	/* configure settings                 */
@@ -202,14 +198,10 @@ void AutoConfigTestPage::TestBandwidthThread()
 	// output: "bind_ip" via main config -> "Output", "BindIP"
 	// output: "bind_ip" via main config -> "Output", "BindIP"
 	//         obs_output_set_service
 	//         obs_output_set_service
 
 
-	OBSData service_settings = obs_data_create();
-	OBSData vencoder_settings = obs_data_create();
-	OBSData aencoder_settings = obs_data_create();
-	OBSData output_settings = obs_data_create();
-	obs_data_release(service_settings);
-	obs_data_release(vencoder_settings);
-	obs_data_release(aencoder_settings);
-	obs_data_release(output_settings);
+	OBSDataAutoRelease service_settings = obs_data_create();
+	OBSDataAutoRelease vencoder_settings = obs_data_create();
+	OBSDataAutoRelease aencoder_settings = obs_data_create();
+	OBSDataAutoRelease output_settings = obs_data_create();
 
 
 	std::string key = wiz->key;
 	std::string key = wiz->key;
 	if (wiz->service == AutoConfig::Service::Twitch) {
 	if (wiz->service == AutoConfig::Service::Twitch) {
@@ -281,9 +273,8 @@ void AutoConfigTestPage::TestBandwidthThread()
 	if (!output_type)
 	if (!output_type)
 		output_type = "rtmp_output";
 		output_type = "rtmp_output";
 
 
-	OBSOutput output =
+	OBSOutputAutoRelease output =
 		obs_output_create(output_type, "test_stream", nullptr, nullptr);
 		obs_output_create(output_type, "test_stream", nullptr, nullptr);
-	obs_output_release(output);
 	obs_output_update(output, output_settings);
 	obs_output_update(output, output_settings);
 
 
 	const char *audio_codec = obs_output_get_supported_audio_codecs(output);
 	const char *audio_codec = obs_output_get_supported_audio_codecs(output);
@@ -292,7 +283,6 @@ void AutoConfigTestPage::TestBandwidthThread()
 		const char *id = FindAudioEncoderFromCodec(audio_codec);
 		const char *id = FindAudioEncoderFromCodec(audio_codec);
 		aencoder = obs_audio_encoder_create(id, "test_audio", nullptr,
 		aencoder = obs_audio_encoder_create(id, "test_audio", nullptr,
 						    0, nullptr);
 						    0, nullptr);
-		obs_encoder_release(aencoder);
 	}
 	}
 
 
 	/* -----------------------------------*/
 	/* -----------------------------------*/
@@ -531,23 +521,18 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
 	/* -----------------------------------*/
 	/* -----------------------------------*/
 	/* create obs objects                 */
 	/* create obs objects                 */
 
 
-	OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
-						       nullptr, nullptr);
-	OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
-						       nullptr, 0, nullptr);
-	OBSOutput output =
+	OBSEncoderAutoRelease vencoder = obs_video_encoder_create(
+		"obs_x264", "test_x264", nullptr, nullptr);
+	OBSEncoderAutoRelease aencoder = obs_audio_encoder_create(
+		"ffmpeg_aac", "test_aac", nullptr, 0, nullptr);
+	OBSOutputAutoRelease output =
 		obs_output_create("null_output", "null", nullptr, nullptr);
 		obs_output_create("null_output", "null", nullptr, nullptr);
-	obs_output_release(output);
-	obs_encoder_release(vencoder);
-	obs_encoder_release(aencoder);
 
 
 	/* -----------------------------------*/
 	/* -----------------------------------*/
 	/* configure settings                 */
 	/* configure settings                 */
 
 
-	OBSData aencoder_settings = obs_data_create();
-	OBSData vencoder_settings = obs_data_create();
-	obs_data_release(aencoder_settings);
-	obs_data_release(vencoder_settings);
+	OBSDataAutoRelease aencoder_settings = obs_data_create();
+	OBSDataAutoRelease vencoder_settings = obs_data_create();
 	obs_data_set_int(aencoder_settings, "bitrate", 32);
 	obs_data_set_int(aencoder_settings, "bitrate", 32);
 
 
 	if (wiz->type != AutoConfig::Type::Recording) {
 	if (wiz->type != AutoConfig::Type::Recording) {
@@ -1020,14 +1005,11 @@ void AutoConfigTestPage::FinalizeResults()
 		const char *serverType = wiz->customServer ? "rtmp_custom"
 		const char *serverType = wiz->customServer ? "rtmp_custom"
 							   : "rtmp_common";
 							   : "rtmp_common";
 
 
-		OBSService service = obs_service_create(
+		OBSServiceAutoRelease service = obs_service_create(
 			serverType, "temp_service", nullptr, nullptr);
 			serverType, "temp_service", nullptr, nullptr);
-		obs_service_release(service);
 
 
-		OBSData service_settings = obs_data_create();
-		OBSData vencoder_settings = obs_data_create();
-		obs_data_release(service_settings);
-		obs_data_release(vencoder_settings);
+		OBSDataAutoRelease service_settings = obs_data_create();
+		OBSDataAutoRelease vencoder_settings = obs_data_create();
 
 
 		obs_data_set_int(vencoder_settings, "bitrate",
 		obs_data_set_int(vencoder_settings, "bitrate",
 				 wiz->idealBitrate);
 				 wiz->idealBitrate);

+ 15 - 28
UI/window-basic-auto-config.cpp

@@ -43,17 +43,15 @@ static OBSData OpenServiceSettings(std::string &type)
 	if (ret <= 0)
 	if (ret <= 0)
 		return OBSData();
 		return OBSData();
 
 
-	OBSData data =
+	OBSDataAutoRelease data =
 		obs_data_create_from_json_file_safe(serviceJsonPath, "bak");
 		obs_data_create_from_json_file_safe(serviceJsonPath, "bak");
-	obs_data_release(data);
 
 
 	obs_data_set_default_string(data, "type", "rtmp_common");
 	obs_data_set_default_string(data, "type", "rtmp_common");
 	type = obs_data_get_string(data, "type");
 	type = obs_data_get_string(data, "type");
 
 
-	OBSData settings = obs_data_get_obj(data, "settings");
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_get_obj(data, "settings");
 
 
-	return settings;
+	return settings.Get();
 }
 }
 
 
 static void GetServiceInfo(std::string &type, std::string &service,
 static void GetServiceInfo(std::string &type, std::string &service,
@@ -340,8 +338,7 @@ inline bool AutoConfigStreamPage::IsCustomService() const
 
 
 bool AutoConfigStreamPage::validatePage()
 bool AutoConfigStreamPage::validatePage()
 {
 {
-	OBSData service_settings = obs_data_create();
-	obs_data_release(service_settings);
+	OBSDataAutoRelease service_settings = obs_data_create();
 
 
 	wiz->customServer = IsCustomService();
 	wiz->customServer = IsCustomService();
 
 
@@ -353,9 +350,8 @@ bool AutoConfigStreamPage::validatePage()
 				    QT_TO_UTF8(ui->service->currentText()));
 				    QT_TO_UTF8(ui->service->currentText()));
 	}
 	}
 
 
-	OBSService service = obs_service_create(serverType, "temp_service",
-						service_settings, nullptr);
-	obs_service_release(service);
+	OBSServiceAutoRelease service = obs_service_create(
+		serverType, "temp_service", service_settings, nullptr);
 
 
 	int bitrate;
 	int bitrate;
 	if (!ui->doBandwidthTest->isChecked()) {
 	if (!ui->doBandwidthTest->isChecked()) {
@@ -376,8 +372,7 @@ bool AutoConfigStreamPage::validatePage()
 #endif
 #endif
 	}
 	}
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_int(settings, "bitrate", bitrate);
 	obs_data_set_int(settings, "bitrate", bitrate);
 	obs_service_apply_encoder_settings(service, settings, nullptr);
 	obs_service_apply_encoder_settings(service, settings, nullptr);
 
 
@@ -697,8 +692,7 @@ void AutoConfigStreamPage::UpdateMoreInfoLink()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -724,8 +718,7 @@ void AutoConfigStreamPage::UpdateKeyLink()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -759,8 +752,7 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
 {
 {
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_bool(settings, "show_all", showAll);
 	obs_data_set_bool(settings, "show_all", showAll);
 
 
@@ -823,8 +815,7 @@ void AutoConfigStreamPage::UpdateServerList()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -904,8 +895,7 @@ AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
 	/* ----------------------------------------- */
 	/* ----------------------------------------- */
 	/* check to see if Twitch's "auto" available */
 	/* check to see if Twitch's "auto" available */
 
 
-	OBSData twitchSettings = obs_data_create();
-	obs_data_release(twitchSettings);
+	OBSDataAutoRelease twitchSettings = obs_data_create();
 
 
 	obs_data_set_string(twitchSettings, "service", "Twitch");
 	obs_data_set_string(twitchSettings, "service", "Twitch");
 
 
@@ -1077,11 +1067,9 @@ void AutoConfig::SaveStreamSettings()
 	const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
 	const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
 
 
 	obs_service_t *oldService = main->GetService();
 	obs_service_t *oldService = main->GetService();
-	OBSData hotkeyData = obs_hotkeys_save_service(oldService);
-	obs_data_release(hotkeyData);
+	OBSDataAutoRelease hotkeyData = obs_hotkeys_save_service(oldService);
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	if (!customServer)
 	if (!customServer)
 		obs_data_set_string(settings, "service", serviceName.c_str());
 		obs_data_set_string(settings, "service", serviceName.c_str());
@@ -1093,9 +1081,8 @@ void AutoConfig::SaveStreamSettings()
 	obs_data_set_string(settings, "key", key.c_str());
 	obs_data_set_string(settings, "key", key.c_str());
 #endif
 #endif
 
 
-	OBSService newService = obs_service_create(
+	OBSServiceAutoRelease newService = obs_service_create(
 		service_id, "default_service", settings, hotkeyData);
 		service_id, "default_service", settings, hotkeyData);
-	obs_service_release(newService);
 
 
 	if (!newService)
 	if (!newService)
 		return;
 		return;

+ 54 - 100
UI/window-basic-filters.cpp

@@ -205,16 +205,16 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
 	const char *source_name = obs_source_get_name(source);
 	const char *source_name = obs_source_get_name(source);
 	OBSBasic *main = OBSBasic::Get();
 	OBSBasic *main = OBSBasic::Get();
 
 
-	obs_data_t *redo_wrapper = obs_data_create();
+	OBSDataAutoRelease redo_wrapper = obs_data_create();
 	obs_data_set_string(redo_wrapper, "name", source_name);
 	obs_data_set_string(redo_wrapper, "name", source_name);
 	obs_data_set_string(redo_wrapper, "settings",
 	obs_data_set_string(redo_wrapper, "settings",
 			    obs_data_get_json(new_settings));
 			    obs_data_get_json(new_settings));
 	obs_data_set_string(redo_wrapper, "parent",
 	obs_data_set_string(redo_wrapper, "parent",
 			    obs_source_get_name(parent));
 			    obs_source_get_name(parent));
 
 
-	obs_data_t *filter_settings = obs_source_get_settings(source);
+	OBSDataAutoRelease filter_settings = obs_source_get_settings(source);
 
 
-	obs_data_t *undo_wrapper = obs_data_create();
+	OBSDataAutoRelease undo_wrapper = obs_data_create();
 	obs_data_set_string(undo_wrapper, "name", source_name);
 	obs_data_set_string(undo_wrapper, "name", source_name);
 	obs_data_set_string(undo_wrapper, "settings",
 	obs_data_set_string(undo_wrapper, "settings",
 			    obs_data_get_json(nd_old_settings));
 			    obs_data_get_json(nd_old_settings));
@@ -222,26 +222,22 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
 			    obs_source_get_name(parent));
 			    obs_source_get_name(parent));
 
 
 	auto undo_redo = [](const std::string &data) {
 	auto undo_redo = [](const std::string &data) {
-		obs_data_t *dat = obs_data_create_from_json(data.c_str());
-		obs_source_t *parent_source = obs_get_source_by_name(
+		OBSDataAutoRelease dat =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease parent_source = obs_get_source_by_name(
 			obs_data_get_string(dat, "parent"));
 			obs_data_get_string(dat, "parent"));
 		const char *filter_name = obs_data_get_string(dat, "name");
 		const char *filter_name = obs_data_get_string(dat, "name");
-		obs_source_t *filter = obs_source_get_filter_by_name(
+		OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
 			parent_source, filter_name);
 			parent_source, filter_name);
-		obs_data_t *new_settings = obs_data_create_from_json(
+		OBSDataAutoRelease new_settings = obs_data_create_from_json(
 			obs_data_get_string(dat, "settings"));
 			obs_data_get_string(dat, "settings"));
 
 
-		obs_data_t *current_settings = obs_source_get_settings(filter);
+		OBSDataAutoRelease current_settings =
+			obs_source_get_settings(filter);
 		obs_data_clear(current_settings);
 		obs_data_clear(current_settings);
-		obs_data_release(current_settings);
 
 
 		obs_source_update(filter, new_settings);
 		obs_source_update(filter, new_settings);
 		obs_source_update_properties(filter);
 		obs_source_update_properties(filter);
-
-		obs_data_release(dat);
-		obs_data_release(new_settings);
-		obs_source_release(filter);
-		obs_source_release(parent_source);
 	};
 	};
 
 
 	main->undo_s.enable();
 	main->undo_s.enable();
@@ -252,10 +248,6 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
 	main->undo_s.add_action(QTStr("Undo.Filters").arg(name.c_str()),
 	main->undo_s.add_action(QTStr("Undo.Filters").arg(name.c_str()),
 				undo_redo, undo_redo, undo_data, redo_data);
 				undo_redo, undo_redo, undo_data, redo_data);
 
 
-	obs_data_release(redo_wrapper);
-	obs_data_release(undo_wrapper);
-	obs_data_release(filter_settings);
-
 	obs_source_update(source, new_settings);
 	obs_source_update(source, new_settings);
 }
 }
 
 
@@ -272,7 +264,7 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
 	if (!filter)
 	if (!filter)
 		return;
 		return;
 
 
-	obs_data_t *settings = obs_source_get_settings(filter);
+	OBSDataAutoRelease settings = obs_source_get_settings(filter);
 
 
 	auto disabled_undo = [](void *vp, obs_data_t *settings) {
 	auto disabled_undo = [](void *vp, obs_data_t *settings) {
 		OBSBasic *main =
 		OBSBasic *main =
@@ -283,7 +275,7 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
 	};
 	};
 
 
 	view = new OBSPropertiesView(
 	view = new OBSPropertiesView(
-		settings, filter,
+		settings.Get(), filter,
 		(PropertiesReloadCallback)obs_source_properties,
 		(PropertiesReloadCallback)obs_source_properties,
 		(PropertiesUpdateCallback)FilterChangeUndoRedo,
 		(PropertiesUpdateCallback)FilterChangeUndoRedo,
 		(PropertiesVisualUpdateCb)disabled_undo);
 		(PropertiesVisualUpdateCb)disabled_undo);
@@ -292,8 +284,6 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
 				       "update_properties",
 				       "update_properties",
 				       OBSBasicFilters::UpdateProperties, this);
 				       OBSBasicFilters::UpdateProperties, this);
 
 
-	obs_data_release(settings);
-
 	view->setMaximumHeight(250);
 	view->setMaximumHeight(250);
 	view->setMinimumHeight(150);
 	view->setMinimumHeight(150);
 	ui->rightLayout->addWidget(view);
 	ui->rightLayout->addWidget(view);
@@ -532,7 +522,7 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
 void OBSBasicFilters::AddNewFilter(const char *id)
 void OBSBasicFilters::AddNewFilter(const char *id)
 {
 {
 	if (id && *id) {
 	if (id && *id) {
-		obs_source_t *existing_filter;
+		OBSSourceAutoRelease existing_filter;
 		string name = obs_source_get_display_name(id);
 		string name = obs_source_get_display_name(id);
 
 
 		QString placeholder = QString::fromStdString(name);
 		QString placeholder = QString::fromStdString(name);
@@ -540,7 +530,6 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 		int i = 2;
 		int i = 2;
 		while ((existing_filter = obs_source_get_filter_by_name(
 		while ((existing_filter = obs_source_get_filter_by_name(
 				source, QT_TO_UTF8(text)))) {
 				source, QT_TO_UTF8(text)))) {
-			obs_source_release(existing_filter);
 			text = QString("%1 %2").arg(placeholder).arg(i++);
 			text = QString("%1 %2").arg(placeholder).arg(i++);
 		}
 		}
 
 
@@ -563,12 +552,11 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 		if (existing_filter) {
 		if (existing_filter) {
 			OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 			OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 					       QTStr("NameExists.Text"));
 					       QTStr("NameExists.Text"));
-			obs_source_release(existing_filter);
 			AddNewFilter(id);
 			AddNewFilter(id);
 			return;
 			return;
 		}
 		}
 
 
-		obs_data_t *wrapper = obs_data_create();
+		OBSDataAutoRelease wrapper = obs_data_create();
 		obs_data_set_string(wrapper, "sname",
 		obs_data_set_string(wrapper, "sname",
 				    obs_source_get_name(source));
 				    obs_source_get_name(source));
 		obs_data_set_string(wrapper, "fname", name.c_str());
 		obs_data_set_string(wrapper, "fname", name.c_str());
@@ -595,31 +583,26 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 			obs_source_release(filter);
 			obs_source_release(filter);
 		};
 		};
 
 
-		obs_data_t *rwrapper = obs_data_create();
+		OBSDataAutoRelease rwrapper = obs_data_create();
 		obs_data_set_string(rwrapper, "sname",
 		obs_data_set_string(rwrapper, "sname",
 				    obs_source_get_name(source));
 				    obs_source_get_name(source));
 		auto redo = [scene_name, id = std::string(id),
 		auto redo = [scene_name, id = std::string(id),
 			     name](const std::string &data) {
 			     name](const std::string &data) {
-			obs_source_t *ssource =
+			OBSSourceAutoRelease ssource =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-				->SetCurrentScene(ssource, true);
-			obs_source_release(ssource);
+				->SetCurrentScene(ssource.Get(), true);
 
 
-			obs_data_t *dat =
+			OBSDataAutoRelease dat =
 				obs_data_create_from_json(data.c_str());
 				obs_data_create_from_json(data.c_str());
-			obs_source_t *source = obs_get_source_by_name(
+			OBSSourceAutoRelease source = obs_get_source_by_name(
 				obs_data_get_string(dat, "sname"));
 				obs_data_get_string(dat, "sname"));
 
 
-			obs_source_t *filter = obs_source_create(
+			OBSSourceAutoRelease filter = obs_source_create(
 				id.c_str(), name.c_str(), nullptr, nullptr);
 				id.c_str(), name.c_str(), nullptr, nullptr);
 			if (filter) {
 			if (filter) {
 				obs_source_filter_add(source, filter);
 				obs_source_filter_add(source, filter);
-				obs_source_release(filter);
 			}
 			}
-
-			obs_data_release(dat);
-			obs_source_release(source);
 		};
 		};
 
 
 		std::string undo_data(obs_data_get_json(wrapper));
 		std::string undo_data(obs_data_get_json(wrapper));
@@ -627,10 +610,7 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 		main->undo_s.add_action(QTStr("Undo.Add").arg(name.c_str()),
 		main->undo_s.add_action(QTStr("Undo.Add").arg(name.c_str()),
 					undo, redo, undo_data, redo_data);
 					undo, redo, undo_data, redo_data);
 
 
-		obs_data_release(wrapper);
-		obs_data_release(rwrapper);
-
-		obs_source_t *filter =
+		OBSSourceAutoRelease filter =
 			obs_source_create(id, name.c_str(), nullptr, nullptr);
 			obs_source_create(id, name.c_str(), nullptr, nullptr);
 		if (filter) {
 		if (filter) {
 			const char *sourceName = obs_source_get_name(source);
 			const char *sourceName = obs_source_get_name(source);
@@ -641,7 +621,6 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 			     name.c_str(), id, sourceName);
 			     name.c_str(), id, sourceName);
 
 
 			obs_source_filter_add(source, filter);
 			obs_source_filter_add(source, filter);
-			obs_source_release(filter);
 		}
 		}
 	}
 	}
 }
 }
@@ -947,14 +926,13 @@ void OBSBasicFilters::DuplicateItem(QListWidgetItem *item)
 {
 {
 	OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
 	OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
 	string name = obs_source_get_name(filter);
 	string name = obs_source_get_name(filter);
-	obs_source_t *existing_filter;
+	OBSSourceAutoRelease existing_filter;
 
 
 	QString placeholder = QString::fromStdString(name);
 	QString placeholder = QString::fromStdString(name);
 	QString text{placeholder};
 	QString text{placeholder};
 	int i = 2;
 	int i = 2;
 	while ((existing_filter = obs_source_get_filter_by_name(
 	while ((existing_filter = obs_source_get_filter_by_name(
 			source, QT_TO_UTF8(text)))) {
 			source, QT_TO_UTF8(text)))) {
-		obs_source_release(existing_filter);
 		text = QString("%1 %2").arg(placeholder).arg(i++);
 		text = QString("%1 %2").arg(placeholder).arg(i++);
 	}
 	}
 
 
@@ -975,12 +953,11 @@ void OBSBasicFilters::DuplicateItem(QListWidgetItem *item)
 	if (existing_filter) {
 	if (existing_filter) {
 		OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 		OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 				       QTStr("NameExists.Text"));
 				       QTStr("NameExists.Text"));
-		obs_source_release(existing_filter);
 		DuplicateItem(item);
 		DuplicateItem(item);
 		return;
 		return;
 	}
 	}
 	bool enabled = obs_source_enabled(filter);
 	bool enabled = obs_source_enabled(filter);
-	obs_source_t *new_filter =
+	OBSSourceAutoRelease new_filter =
 		obs_source_duplicate(filter, name.c_str(), false);
 		obs_source_duplicate(filter, name.c_str(), false);
 	if (new_filter) {
 	if (new_filter) {
 		const char *sourceName = obs_source_get_name(source);
 		const char *sourceName = obs_source_get_name(source);
@@ -991,7 +968,6 @@ void OBSBasicFilters::DuplicateItem(QListWidgetItem *item)
 		     name.c_str(), id, name.c_str(), sourceName);
 		     name.c_str(), id, name.c_str(), sourceName);
 		obs_source_set_enabled(new_filter, enabled);
 		obs_source_set_enabled(new_filter, enabled);
 		obs_source_filter_add(source, new_filter);
 		obs_source_filter_add(source, new_filter);
-		obs_source_release(new_filter);
 	}
 	}
 }
 }
 
 
@@ -1036,7 +1012,7 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 
 
 	const char *prevName = obs_source_get_name(filter);
 	const char *prevName = obs_source_get_name(filter);
 	bool sameName = (name == prevName);
 	bool sameName = (name == prevName);
-	obs_source_t *foundFilter = nullptr;
+	OBSSourceAutoRelease foundFilter = nullptr;
 
 
 	if (!sameName)
 	if (!sameName)
 		foundFilter =
 		foundFilter =
@@ -1049,8 +1025,6 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 			OBSMessageBox::information(window(),
 			OBSMessageBox::information(window(),
 						   QTStr("NameExists.Title"),
 						   QTStr("NameExists.Title"),
 						   QTStr("NameExists.Text"));
 						   QTStr("NameExists.Text"));
-			obs_source_release(foundFilter);
-
 		} else if (name.empty()) {
 		} else if (name.empty()) {
 			OBSMessageBox::information(window(),
 			OBSMessageBox::information(window(),
 						   QTStr("NoNameEntered.Title"),
 						   QTStr("NoNameEntered.Title"),
@@ -1071,36 +1045,32 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 				->GetCurrentSceneSource());
 				->GetCurrentSceneSource());
 		auto undo = [scene_name, prev = std::string(prevName),
 		auto undo = [scene_name, prev = std::string(prevName),
 			     name](const std::string &data) {
 			     name](const std::string &data) {
-			obs_source_t *ssource =
+			OBSSourceAutoRelease ssource =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-				->SetCurrentScene(ssource, true);
-			obs_source_release(ssource);
+				->SetCurrentScene(ssource.Get(), true);
 
 
-			obs_source_t *source =
+			OBSSourceAutoRelease source =
 				obs_get_source_by_name(data.c_str());
 				obs_get_source_by_name(data.c_str());
-			obs_source_t *filter = obs_source_get_filter_by_name(
-				source, name.c_str());
+			OBSSourceAutoRelease filter =
+				obs_source_get_filter_by_name(source,
+							      name.c_str());
 			obs_source_set_name(filter, prev.c_str());
 			obs_source_set_name(filter, prev.c_str());
-			obs_source_release(source);
-			obs_source_release(filter);
 		};
 		};
 
 
 		auto redo = [scene_name, prev = std::string(prevName),
 		auto redo = [scene_name, prev = std::string(prevName),
 			     name](const std::string &data) {
 			     name](const std::string &data) {
-			obs_source_t *ssource =
+			OBSSourceAutoRelease ssource =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-				->SetCurrentScene(ssource, true);
-			obs_source_release(ssource);
+				->SetCurrentScene(ssource.Get(), true);
 
 
-			obs_source_t *source =
+			OBSSourceAutoRelease source =
 				obs_get_source_by_name(data.c_str());
 				obs_get_source_by_name(data.c_str());
-			obs_source_t *filter = obs_source_get_filter_by_name(
-				source, prev.c_str());
+			OBSSourceAutoRelease filter =
+				obs_source_get_filter_by_name(source,
+							      prev.c_str());
 			obs_source_set_name(filter, name.c_str());
 			obs_source_set_name(filter, name.c_str());
-			obs_source_release(source);
-			obs_source_release(filter);
 		};
 		};
 
 
 		std::string undo_data(sourceName);
 		std::string undo_data(sourceName);
@@ -1138,14 +1108,12 @@ void OBSBasicFilters::ResetFilters()
 	if (!filter)
 	if (!filter)
 		return;
 		return;
 
 
-	obs_data_t *settings = obs_source_get_settings(filter);
+	OBSDataAutoRelease settings = obs_source_get_settings(filter);
 
 
-	obs_data_t *empty_settings = obs_data_create();
+	OBSDataAutoRelease empty_settings = obs_data_create();
 	FilterChangeUndoRedo((void *)filter, settings, empty_settings);
 	FilterChangeUndoRedo((void *)filter, settings, empty_settings);
-	obs_data_release(empty_settings);
 
 
 	obs_data_clear(settings);
 	obs_data_clear(settings);
-	obs_data_release(settings);
 
 
 	if (!view->DeferUpdate())
 	if (!view->DeferUpdate())
 		obs_source_update(filter, nullptr);
 		obs_source_update(filter, nullptr);
@@ -1171,9 +1139,9 @@ void OBSBasicFilters::PasteFilter()
 	if (!filter)
 	if (!filter)
 		return;
 		return;
 
 
-	obs_data_array_t *undo_array = obs_source_backup_filters(source);
+	OBSDataArrayAutoRelease undo_array = obs_source_backup_filters(source);
 	obs_source_copy_single_filter(source, filter);
 	obs_source_copy_single_filter(source, filter);
-	obs_data_array_t *redo_array = obs_source_backup_filters(source);
+	OBSDataArrayAutoRelease redo_array = obs_source_backup_filters(source);
 
 
 	const char *filterName = obs_source_get_name(filter);
 	const char *filterName = obs_source_get_name(filter);
 	const char *sourceName = obs_source_get_name(source);
 	const char *sourceName = obs_source_get_name(source);
@@ -1182,14 +1150,11 @@ void OBSBasicFilters::PasteFilter()
 
 
 	main->CreateFilterPasteUndoRedoAction(text, source, undo_array,
 	main->CreateFilterPasteUndoRedoAction(text, source, undo_array,
 					      redo_array);
 					      redo_array);
-
-	obs_data_array_release(undo_array);
-	obs_data_array_release(redo_array);
 }
 }
 
 
 void OBSBasicFilters::delete_filter(OBSSource filter)
 void OBSBasicFilters::delete_filter(OBSSource filter)
 {
 {
-	obs_data_t *wrapper = obs_save_source(filter);
+	OBSDataAutoRelease wrapper = obs_save_source(filter);
 	std::string parent_name(obs_source_get_name(source));
 	std::string parent_name(obs_source_get_name(source));
 	obs_data_set_string(wrapper, "undo_name", parent_name.c_str());
 	obs_data_set_string(wrapper, "undo_name", parent_name.c_str());
 
 
@@ -1197,43 +1162,35 @@ void OBSBasicFilters::delete_filter(OBSSource filter)
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->GetCurrentSceneSource());
 			->GetCurrentSceneSource());
 	auto undo = [scene_name](const std::string &data) {
 	auto undo = [scene_name](const std::string &data) {
-		obs_source_t *ssource =
+		OBSSourceAutoRelease ssource =
 			obs_get_source_by_name(scene_name.c_str());
 			obs_get_source_by_name(scene_name.c_str());
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-			->SetCurrentScene(ssource, true);
-		obs_source_release(ssource);
+			->SetCurrentScene(ssource.Get(), true);
 
 
-		obs_data_t *dat = obs_data_create_from_json(data.c_str());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSDataAutoRelease dat =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			obs_data_get_string(dat, "undo_name"));
 			obs_data_get_string(dat, "undo_name"));
-		obs_source_t *filter = obs_load_source(dat);
+		OBSSourceAutoRelease filter = obs_load_source(dat);
 		obs_source_filter_add(source, filter);
 		obs_source_filter_add(source, filter);
-
-		obs_data_release(dat);
-		obs_source_release(source);
-		obs_source_release(filter);
 	};
 	};
 
 
-	obs_data_t *rwrapper = obs_data_create();
+	OBSDataAutoRelease rwrapper = obs_data_create();
 	obs_data_set_string(rwrapper, "fname", obs_source_get_name(filter));
 	obs_data_set_string(rwrapper, "fname", obs_source_get_name(filter));
 	obs_data_set_string(rwrapper, "sname", parent_name.c_str());
 	obs_data_set_string(rwrapper, "sname", parent_name.c_str());
 	auto redo = [scene_name](const std::string &data) {
 	auto redo = [scene_name](const std::string &data) {
-		obs_source_t *ssource =
+		OBSSourceAutoRelease ssource =
 			obs_get_source_by_name(scene_name.c_str());
 			obs_get_source_by_name(scene_name.c_str());
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-			->SetCurrentScene(ssource, true);
-		obs_source_release(ssource);
+			->SetCurrentScene(ssource.Get(), true);
 
 
-		obs_data_t *dat = obs_data_create_from_json(data.c_str());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSDataAutoRelease dat =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			obs_data_get_string(dat, "sname"));
 			obs_data_get_string(dat, "sname"));
-		obs_source_t *filter = obs_source_get_filter_by_name(
+		OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
 			source, obs_data_get_string(dat, "fname"));
 			source, obs_data_get_string(dat, "fname"));
 		obs_source_filter_remove(source, filter);
 		obs_source_filter_remove(source, filter);
-
-		obs_data_release(dat);
-		obs_source_release(filter);
-		obs_source_release(source);
 	};
 	};
 
 
 	std::string undo_data(obs_data_get_json(wrapper));
 	std::string undo_data(obs_data_get_json(wrapper));
@@ -1242,7 +1199,4 @@ void OBSBasicFilters::delete_filter(OBSSource filter)
 		QTStr("Undo.Delete").arg(obs_source_get_name(filter)), undo,
 		QTStr("Undo.Delete").arg(obs_source_get_name(filter)), undo,
 		redo, undo_data, redo_data, false);
 		redo, undo_data, redo_data, false);
 	obs_source_filter_remove(source, filter);
 	obs_source_filter_remove(source, filter);
-
-	obs_data_release(wrapper);
-	obs_data_release(rwrapper);
 }
 }

+ 4 - 9
UI/window-basic-main-dropfiles.cpp

@@ -50,12 +50,11 @@ static string GenerateSourceName(const char *base)
 			name += ")";
 			name += ")";
 		}
 		}
 
 
-		obs_source_t *source = obs_get_source_by_name(name.c_str());
+		OBSSourceAutoRelease source =
+			obs_get_source_by_name(name.c_str());
 
 
 		if (!source)
 		if (!source)
 			return name;
 			return name;
-		else
-			obs_source_release(source);
 	}
 	}
 }
 }
 
 
@@ -106,8 +105,8 @@ void OBSBasic::AddDropURL(const char *url, QString &name, obs_data_t *settings,
 void OBSBasic::AddDropSource(const char *data, DropType image)
 void OBSBasic::AddDropSource(const char *data, DropType image)
 {
 {
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
-	obs_data_t *settings = obs_data_create();
-	obs_source_t *source = nullptr;
+	OBSDataAutoRelease settings = obs_data_create();
+	OBSSourceAutoRelease source = nullptr;
 	const char *type = nullptr;
 	const char *type = nullptr;
 	std::vector<const char *> types;
 	std::vector<const char *> types;
 	QString name;
 	QString name;
@@ -167,7 +166,6 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
 		}
 		}
 	}
 	}
 	if (type == nullptr || !obs_source_get_display_name(type)) {
 	if (type == nullptr || !obs_source_get_display_name(type)) {
-		obs_data_release(settings);
 		return;
 		return;
 	}
 	}
 
 
@@ -179,10 +177,7 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
 	if (source) {
 	if (source) {
 		OBSScene scene = main->GetCurrentScene();
 		OBSScene scene = main->GetCurrentScene();
 		obs_scene_add(scene, source);
 		obs_scene_add(scene, source);
-		obs_source_release(source);
 	}
 	}
-
-	obs_data_release(settings);
 }
 }
 
 
 void OBSBasic::dragEnterEvent(QDragEnterEvent *event)
 void OBSBasic::dragEnterEvent(QDragEnterEvent *event)

+ 29 - 71
UI/window-basic-main-outputs.cpp

@@ -206,7 +206,6 @@ inline BasicOutputHandler::BasicOutputHandler(OBSBasic *main_) : main(main_)
 		virtualCam = obs_output_create("virtualcam_output",
 		virtualCam = obs_output_create("virtualcam_output",
 					       "virtualcam_output", nullptr,
 					       "virtualcam_output", nullptr,
 					       nullptr);
 					       nullptr);
-		obs_output_release(virtualCam);
 
 
 		signal_handler_t *signal =
 		signal_handler_t *signal =
 			obs_output_get_signal_handler(virtualCam);
 			obs_output_get_signal_handler(virtualCam);
@@ -310,9 +309,8 @@ void SimpleOutput::LoadRecordingPreset_Lossless()
 	if (!fileOutput)
 	if (!fileOutput)
 		throw "Failed to create recording FFmpeg output "
 		throw "Failed to create recording FFmpeg output "
 		      "(simple output)";
 		      "(simple output)";
-	obs_output_release(fileOutput);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "format_name", "avi");
 	obs_data_set_string(settings, "format_name", "avi");
 	obs_data_set_string(settings, "video_encoder", "utvideo");
 	obs_data_set_string(settings, "video_encoder", "utvideo");
 	obs_data_set_string(settings, "audio_encoder", "pcm_s16le");
 	obs_data_set_string(settings, "audio_encoder", "pcm_s16le");
@@ -320,7 +318,6 @@ void SimpleOutput::LoadRecordingPreset_Lossless()
 	int aMixes = 1;
 	int aMixes = 1;
 	obs_output_set_mixers(fileOutput, aMixes);
 	obs_output_set_mixers(fileOutput, aMixes);
 	obs_output_update(fileOutput, settings);
 	obs_output_update(fileOutput, settings);
-	obs_data_release(settings);
 }
 }
 
 
 void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId)
 void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId)
@@ -426,7 +423,7 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 		bool useReplayBuffer = config_get_bool(main->Config(),
 		bool useReplayBuffer = config_get_bool(main->Config(),
 						       "SimpleOutput", "RecRB");
 						       "SimpleOutput", "RecRB");
 		if (useReplayBuffer) {
 		if (useReplayBuffer) {
-			obs_data_t *hotkey;
+			OBSDataAutoRelease hotkey;
 			const char *str = config_get_string(
 			const char *str = config_get_string(
 				main->Config(), "Hotkeys", "ReplayBuffer");
 				main->Config(), "Hotkeys", "ReplayBuffer");
 			if (str)
 			if (str)
@@ -438,11 +435,9 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 							 Str("ReplayBuffer"),
 							 Str("ReplayBuffer"),
 							 nullptr, hotkey);
 							 nullptr, hotkey);
 
 
-			obs_data_release(hotkey);
 			if (!replayBuffer)
 			if (!replayBuffer)
 				throw "Failed to create replay buffer output "
 				throw "Failed to create replay buffer output "
 				      "(simple output)";
 				      "(simple output)";
-			obs_output_release(replayBuffer);
 
 
 			signal_handler_t *signal =
 			signal_handler_t *signal =
 				obs_output_get_signal_handler(replayBuffer);
 				obs_output_get_signal_handler(replayBuffer);
@@ -463,7 +458,6 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 		if (!fileOutput)
 		if (!fileOutput)
 			throw "Failed to create recording output "
 			throw "Failed to create recording output "
 			      "(simple output)";
 			      "(simple output)";
-		obs_output_release(fileOutput);
 	}
 	}
 
 
 	startRecording.Connect(obs_output_get_signal_handler(fileOutput),
 	startRecording.Connect(obs_output_get_signal_handler(fileOutput),
@@ -484,8 +478,8 @@ int SimpleOutput::GetAudioBitrate() const
 
 
 void SimpleOutput::Update()
 void SimpleOutput::Update()
 {
 {
-	obs_data_t *h264Settings = obs_data_create();
-	obs_data_t *aacSettings = obs_data_create();
+	OBSDataAutoRelease h264Settings = obs_data_create();
+	OBSDataAutoRelease aacSettings = obs_data_create();
 
 
 	int videoBitrate =
 	int videoBitrate =
 		config_get_uint(main->Config(), "SimpleOutput", "VBitrate");
 		config_get_uint(main->Config(), "SimpleOutput", "VBitrate");
@@ -546,20 +540,15 @@ void SimpleOutput::Update()
 	obs_encoder_update(h264Streaming, h264Settings);
 	obs_encoder_update(h264Streaming, h264Settings);
 	obs_encoder_update(aacStreaming, aacSettings);
 	obs_encoder_update(aacStreaming, aacSettings);
 	obs_encoder_update(aacArchive, aacSettings);
 	obs_encoder_update(aacArchive, aacSettings);
-
-	obs_data_release(h264Settings);
-	obs_data_release(aacSettings);
 }
 }
 
 
 void SimpleOutput::UpdateRecordingAudioSettings()
 void SimpleOutput::UpdateRecordingAudioSettings()
 {
 {
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_int(settings, "bitrate", 192);
 	obs_data_set_int(settings, "bitrate", 192);
 	obs_data_set_string(settings, "rate_control", "CBR");
 	obs_data_set_string(settings, "rate_control", "CBR");
 
 
 	obs_encoder_update(aacRecording, settings);
 	obs_encoder_update(aacRecording, settings);
-
-	obs_data_release(settings);
 }
 }
 
 
 #define CROSS_DIST_CUTOFF 2000.0
 #define CROSS_DIST_CUTOFF 2000.0
@@ -584,7 +573,7 @@ int SimpleOutput::CalcCRF(int crf)
 
 
 void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf)
 void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf)
 {
 {
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_int(settings, "crf", crf);
 	obs_data_set_int(settings, "crf", crf);
 	obs_data_set_bool(settings, "use_bufsize", true);
 	obs_data_set_bool(settings, "use_bufsize", true);
 	obs_data_set_string(settings, "rate_control", "CRF");
 	obs_data_set_string(settings, "rate_control", "CRF");
@@ -593,8 +582,6 @@ void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf)
 			    lowCPUx264 ? "ultrafast" : "veryfast");
 			    lowCPUx264 ? "ultrafast" : "veryfast");
 
 
 	obs_encoder_update(h264Recording, settings);
 	obs_encoder_update(h264Recording, settings);
-
-	obs_data_release(settings);
 }
 }
 
 
 static bool icq_available(obs_encoder_t *encoder)
 static bool icq_available(obs_encoder_t *encoder)
@@ -620,7 +607,7 @@ void SimpleOutput::UpdateRecordingSettings_qsv11(int crf)
 {
 {
 	bool icq = icq_available(h264Recording);
 	bool icq = icq_available(h264Recording);
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "profile", "high");
 	obs_data_set_string(settings, "profile", "high");
 
 
 	if (icq) {
 	if (icq) {
@@ -634,21 +621,17 @@ void SimpleOutput::UpdateRecordingSettings_qsv11(int crf)
 	}
 	}
 
 
 	obs_encoder_update(h264Recording, settings);
 	obs_encoder_update(h264Recording, settings);
-
-	obs_data_release(settings);
 }
 }
 
 
 void SimpleOutput::UpdateRecordingSettings_nvenc(int cqp)
 void SimpleOutput::UpdateRecordingSettings_nvenc(int cqp)
 {
 {
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "rate_control", "CQP");
 	obs_data_set_string(settings, "rate_control", "CQP");
 	obs_data_set_string(settings, "profile", "high");
 	obs_data_set_string(settings, "profile", "high");
 	obs_data_set_string(settings, "preset", "hq");
 	obs_data_set_string(settings, "preset", "hq");
 	obs_data_set_int(settings, "cqp", cqp);
 	obs_data_set_int(settings, "cqp", cqp);
 
 
 	obs_encoder_update(h264Recording, settings);
 	obs_encoder_update(h264Recording, settings);
-
-	obs_data_release(settings);
 }
 }
 
 
 void SimpleOutput::UpdateStreamingSettings_amd(obs_data_t *settings,
 void SimpleOutput::UpdateStreamingSettings_amd(obs_data_t *settings,
@@ -672,7 +655,7 @@ void SimpleOutput::UpdateStreamingSettings_amd(obs_data_t *settings,
 
 
 void SimpleOutput::UpdateRecordingSettings_amd_cqp(int cqp)
 void SimpleOutput::UpdateRecordingSettings_amd_cqp(int cqp)
 {
 {
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	// Static Properties
 	// Static Properties
 	obs_data_set_int(settings, "Usage", 0);
 	obs_data_set_int(settings, "Usage", 0);
@@ -692,7 +675,6 @@ void SimpleOutput::UpdateRecordingSettings_amd_cqp(int cqp)
 
 
 	// Update and release
 	// Update and release
 	obs_encoder_update(h264Recording, settings);
 	obs_encoder_update(h264Recording, settings);
-	obs_data_release(settings);
 }
 }
 
 
 void SimpleOutput::UpdateRecordingSettings()
 void SimpleOutput::UpdateRecordingSettings()
@@ -788,7 +770,6 @@ bool SimpleOutput::SetupStreaming(obs_service_t *service)
 			     type);
 			     type);
 			return false;
 			return false;
 		}
 		}
-		obs_output_release(streamOutput);
 
 
 		streamDelayStarting.Connect(
 		streamDelayStarting.Connect(
 			obs_output_get_signal_handler(streamOutput), "starting",
 			obs_output_get_signal_handler(streamOutput), "starting",
@@ -820,7 +801,7 @@ bool SimpleOutput::SetupStreaming(obs_service_t *service)
 				const char *id =
 				const char *id =
 					FindAudioEncoderFromCodec(codec);
 					FindAudioEncoderFromCodec(codec);
 				int audioBitrate = GetAudioBitrate();
 				int audioBitrate = GetAudioBitrate();
-				obs_data_t *settings = obs_data_create();
+				OBSDataAutoRelease settings = obs_data_create();
 				obs_data_set_int(settings, "bitrate",
 				obs_data_set_int(settings, "bitrate",
 						 audioBitrate);
 						 audioBitrate);
 
 
@@ -834,8 +815,6 @@ bool SimpleOutput::SetupStreaming(obs_service_t *service)
 				obs_encoder_update(aacStreaming, settings);
 				obs_encoder_update(aacStreaming, settings);
 				obs_encoder_set_audio(aacStreaming,
 				obs_encoder_set_audio(aacStreaming,
 						      obs_get_audio());
 						      obs_get_audio());
-
-				obs_data_release(settings);
 			}
 			}
 		}
 		}
 
 
@@ -876,7 +855,7 @@ void SimpleOutput::SetupVodTrack(obs_service_t *service)
 	bool enableForCustomServer = config_get_bool(
 	bool enableForCustomServer = config_get_bool(
 		GetGlobalConfig(), "General", "EnableCustomServerVodTrack");
 		GetGlobalConfig(), "General", "EnableCustomServerVodTrack");
 
 
-	obs_data_t *settings = obs_service_get_settings(service);
+	OBSDataAutoRelease settings = obs_service_get_settings(service);
 	const char *name = obs_data_get_string(settings, "service");
 	const char *name = obs_data_get_string(settings, "service");
 
 
 	const char *id = obs_service_get_id(service);
 	const char *id = obs_service_get_id(service);
@@ -889,8 +868,6 @@ void SimpleOutput::SetupVodTrack(obs_service_t *service)
 		obs_output_set_audio_encoder(streamOutput, aacArchive, 1);
 		obs_output_set_audio_encoder(streamOutput, aacArchive, 1);
 	else
 	else
 		clear_archive_encoder(streamOutput, SIMPLE_ARCHIVE_NAME);
 		clear_archive_encoder(streamOutput, SIMPLE_ARCHIVE_NAME);
-
-	obs_data_release(settings);
 }
 }
 
 
 bool SimpleOutput::StartStreaming(obs_service_t *service)
 bool SimpleOutput::StartStreaming(obs_service_t *service)
@@ -914,7 +891,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
 	bool enableDynBitrate =
 	bool enableDynBitrate =
 		config_get_bool(main->Config(), "Output", "DynamicBitrate");
 		config_get_bool(main->Config(), "Output", "DynamicBitrate");
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "bind_ip", bindIP);
 	obs_data_set_string(settings, "bind_ip", bindIP);
 	obs_data_set_bool(settings, "new_socket_loop_enabled",
 	obs_data_set_bool(settings, "new_socket_loop_enabled",
 			  enableNewSocketLoop);
 			  enableNewSocketLoop);
@@ -922,7 +899,6 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
 			  enableLowLatencyMode);
 			  enableLowLatencyMode);
 	obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
 	obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
 	obs_output_update(streamOutput, settings);
 	obs_output_update(streamOutput, settings);
-	obs_data_release(settings);
 
 
 	if (!reconnect)
 	if (!reconnect)
 		maxRetries = 0;
 		maxRetries = 0;
@@ -1004,7 +980,7 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
 	string f;
 	string f;
 	string strPath;
 	string strPath;
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	if (updateReplayBuffer) {
 	if (updateReplayBuffer) {
 		f = GetFormatString(filenameFormat, rbPrefix, rbSuffix);
 		f = GetFormatString(filenameFormat, rbPrefix, rbSuffix);
 		strPath = GetOutputFilename(path, ffmpegOutput ? "avi" : format,
 		strPath = GetOutputFilename(path, ffmpegOutput ? "avi" : format,
@@ -1034,7 +1010,6 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer)
 	else
 	else
 		obs_output_update(fileOutput, settings);
 		obs_output_update(fileOutput, settings);
 
 
-	obs_data_release(settings);
 	return true;
 	return true;
 }
 }
 
 
@@ -1158,7 +1133,7 @@ struct AdvancedOutput : BasicOutputHandler {
 static OBSData GetDataFromJsonFile(const char *jsonFile)
 static OBSData GetDataFromJsonFile(const char *jsonFile)
 {
 {
 	char fullPath[512];
 	char fullPath[512];
-	obs_data_t *data = nullptr;
+	OBSDataAutoRelease data = nullptr;
 
 
 	int ret = GetProfilePath(fullPath, sizeof(fullPath), jsonFile);
 	int ret = GetProfilePath(fullPath, sizeof(fullPath), jsonFile);
 	if (ret > 0) {
 	if (ret > 0) {
@@ -1170,9 +1145,8 @@ static OBSData GetDataFromJsonFile(const char *jsonFile)
 
 
 	if (!data)
 	if (!data)
 		data = obs_data_create();
 		data = obs_data_create();
-	OBSData dataRet(data);
-	obs_data_release(data);
-	return dataRet;
+
+	return data.Get();
 }
 }
 
 
 static void ApplyEncoderDefaults(OBSData &settings,
 static void ApplyEncoderDefaults(OBSData &settings,
@@ -1227,23 +1201,21 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 		if (!fileOutput)
 		if (!fileOutput)
 			throw "Failed to create recording FFmpeg output "
 			throw "Failed to create recording FFmpeg output "
 			      "(advanced output)";
 			      "(advanced output)";
-		obs_output_release(fileOutput);
 	} else {
 	} else {
 		bool useReplayBuffer =
 		bool useReplayBuffer =
 			config_get_bool(main->Config(), "AdvOut", "RecRB");
 			config_get_bool(main->Config(), "AdvOut", "RecRB");
 		if (useReplayBuffer) {
 		if (useReplayBuffer) {
 			const char *str = config_get_string(
 			const char *str = config_get_string(
 				main->Config(), "Hotkeys", "ReplayBuffer");
 				main->Config(), "Hotkeys", "ReplayBuffer");
-			obs_data_t *hotkey = obs_data_create_from_json(str);
+			OBSDataAutoRelease hotkey =
+				obs_data_create_from_json(str);
 			replayBuffer = obs_output_create("replay_buffer",
 			replayBuffer = obs_output_create("replay_buffer",
 							 Str("ReplayBuffer"),
 							 Str("ReplayBuffer"),
 							 nullptr, hotkey);
 							 nullptr, hotkey);
 
 
-			obs_data_release(hotkey);
 			if (!replayBuffer)
 			if (!replayBuffer)
 				throw "Failed to create replay buffer output "
 				throw "Failed to create replay buffer output "
 				      "(simple output)";
 				      "(simple output)";
-			obs_output_release(replayBuffer);
 
 
 			signal_handler_t *signal =
 			signal_handler_t *signal =
 				obs_output_get_signal_handler(replayBuffer);
 				obs_output_get_signal_handler(replayBuffer);
@@ -1264,7 +1236,6 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
 		if (!fileOutput)
 		if (!fileOutput)
 			throw "Failed to create recording output "
 			throw "Failed to create recording output "
 			      "(advanced output)";
 			      "(advanced output)";
-		obs_output_release(fileOutput);
 
 
 		if (!useStreamEncoder) {
 		if (!useStreamEncoder) {
 			h264Recording = obs_video_encoder_create(
 			h264Recording = obs_video_encoder_create(
@@ -1415,11 +1386,10 @@ inline void AdvancedOutput::SetupStreaming()
 
 
 	const char *id = obs_service_get_id(main->GetService());
 	const char *id = obs_service_get_id(main->GetService());
 	if (strcmp(id, "rtmp_custom") == 0) {
 	if (strcmp(id, "rtmp_custom") == 0) {
-		obs_data_t *settings = obs_data_create();
+		OBSDataAutoRelease settings = obs_data_create();
 		obs_service_apply_encoder_settings(main->GetService(), settings,
 		obs_service_apply_encoder_settings(main->GetService(), settings,
 						   nullptr);
 						   nullptr);
 		obs_encoder_update(h264Streaming, settings);
 		obs_encoder_update(h264Streaming, settings);
-		obs_data_release(settings);
 	}
 	}
 }
 }
 
 
@@ -1444,7 +1414,7 @@ inline void AdvancedOutput::SetupRecording()
 	else
 	else
 		tracks = config_get_int(main->Config(), "AdvOut", "RecTracks");
 		tracks = config_get_int(main->Config(), "AdvOut", "RecTracks");
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	unsigned int cx = 0;
 	unsigned int cx = 0;
 	unsigned int cy = 0;
 	unsigned int cy = 0;
 	int idx = 0;
 	int idx = 0;
@@ -1498,7 +1468,6 @@ inline void AdvancedOutput::SetupRecording()
 	obs_output_update(fileOutput, settings);
 	obs_output_update(fileOutput, settings);
 	if (replayBuffer)
 	if (replayBuffer)
 		obs_output_update(replayBuffer, settings);
 		obs_output_update(replayBuffer, settings);
-	obs_data_release(settings);
 }
 }
 
 
 inline void AdvancedOutput::SetupFFmpeg()
 inline void AdvancedOutput::SetupFFmpeg()
@@ -1529,7 +1498,7 @@ inline void AdvancedOutput::SetupFFmpeg()
 		config_get_int(main->Config(), "AdvOut", "FFAEncoderId");
 		config_get_int(main->Config(), "AdvOut", "FFAEncoderId");
 	const char *aEncCustom =
 	const char *aEncCustom =
 		config_get_string(main->Config(), "AdvOut", "FFACustom");
 		config_get_string(main->Config(), "AdvOut", "FFACustom");
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "url", url);
 	obs_data_set_string(settings, "url", url);
 	obs_data_set_string(settings, "format_name", formatName);
 	obs_data_set_string(settings, "format_name", formatName);
@@ -1559,8 +1528,6 @@ inline void AdvancedOutput::SetupFFmpeg()
 	obs_output_set_mixers(fileOutput, aMixes);
 	obs_output_set_mixers(fileOutput, aMixes);
 	obs_output_set_media(fileOutput, obs_get_video(), obs_get_audio());
 	obs_output_set_media(fileOutput, obs_get_video(), obs_get_audio());
 	obs_output_update(fileOutput, settings);
 	obs_output_update(fileOutput, settings);
-
-	obs_data_release(settings);
 }
 }
 
 
 static inline void SetEncoderName(obs_encoder_t *encoder, const char *name,
 static inline void SetEncoderName(obs_encoder_t *encoder, const char *name,
@@ -1579,7 +1546,7 @@ inline void AdvancedOutput::UpdateAudioSettings()
 		config_get_int(main->Config(), "AdvOut", "TrackIndex");
 		config_get_int(main->Config(), "AdvOut", "TrackIndex");
 	int vodTrackIndex =
 	int vodTrackIndex =
 		config_get_int(main->Config(), "AdvOut", "VodTrackIndex");
 		config_get_int(main->Config(), "AdvOut", "VodTrackIndex");
-	obs_data_t *settings[MAX_AUDIO_MIXES];
+	OBSDataAutoRelease settings[MAX_AUDIO_MIXES];
 
 
 	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
 	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
 		settings[i] = obs_data_create();
 		settings[i] = obs_data_create();
@@ -1621,8 +1588,6 @@ inline void AdvancedOutput::UpdateAudioSettings()
 			obs_encoder_update(streamAudioEnc, settings[i]);
 			obs_encoder_update(streamAudioEnc, settings[i]);
 		if (track == vodTrackIndex)
 		if (track == vodTrackIndex)
 			obs_encoder_update(streamArchiveEnc, settings[i]);
 			obs_encoder_update(streamArchiveEnc, settings[i]);
-
-		obs_data_release(settings[i]);
 	}
 	}
 }
 }
 
 
@@ -1670,11 +1635,10 @@ inline void AdvancedOutput::SetupVodTrack(obs_service_t *service)
 		vodTrackEnabled = enableForCustomServer ? vodTrackEnabled
 		vodTrackEnabled = enableForCustomServer ? vodTrackEnabled
 							: false;
 							: false;
 	} else {
 	} else {
-		obs_data_t *settings = obs_service_get_settings(service);
+		OBSDataAutoRelease settings = obs_service_get_settings(service);
 		const char *service = obs_data_get_string(settings, "service");
 		const char *service = obs_data_get_string(settings, "service");
 		if (!ServiceSupportsVodTrack(service))
 		if (!ServiceSupportsVodTrack(service))
 			vodTrackEnabled = false;
 			vodTrackEnabled = false;
-		obs_data_release(settings);
 	}
 	}
 
 
 	if (vodTrackEnabled && streamTrack != vodTrackIndex)
 	if (vodTrackEnabled && streamTrack != vodTrackIndex)
@@ -1733,7 +1697,6 @@ bool AdvancedOutput::SetupStreaming(obs_service_t *service)
 			     type);
 			     type);
 			return false;
 			return false;
 		}
 		}
-		obs_output_release(streamOutput);
 
 
 		streamDelayStarting.Connect(
 		streamDelayStarting.Connect(
 			obs_output_get_signal_handler(streamOutput), "starting",
 			obs_output_get_signal_handler(streamOutput), "starting",
@@ -1762,9 +1725,9 @@ bool AdvancedOutput::SetupStreaming(obs_service_t *service)
 			}
 			}
 
 
 			if (strcmp(codec, "aac") != 0) {
 			if (strcmp(codec, "aac") != 0) {
-				OBSData settings = obs_encoder_get_settings(
-					streamAudioEnc);
-				obs_data_release(settings);
+				OBSDataAutoRelease settings =
+					obs_encoder_get_settings(
+						streamAudioEnc);
 
 
 				const char *id =
 				const char *id =
 					FindAudioEncoderFromCodec(codec);
 					FindAudioEncoderFromCodec(codec);
@@ -1813,7 +1776,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
 	bool enableDynBitrate =
 	bool enableDynBitrate =
 		config_get_bool(main->Config(), "Output", "DynamicBitrate");
 		config_get_bool(main->Config(), "Output", "DynamicBitrate");
 
 
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_string(settings, "bind_ip", bindIP);
 	obs_data_set_string(settings, "bind_ip", bindIP);
 	obs_data_set_bool(settings, "new_socket_loop_enabled",
 	obs_data_set_bool(settings, "new_socket_loop_enabled",
 			  enableNewSocketLoop);
 			  enableNewSocketLoop);
@@ -1821,7 +1784,6 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
 			  enableLowLatencyMode);
 			  enableLowLatencyMode);
 	obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
 	obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
 	obs_output_update(streamOutput, settings);
 	obs_output_update(streamOutput, settings);
-	obs_data_release(settings);
 
 
 	if (!reconnect)
 	if (!reconnect)
 		maxRetries = 0;
 		maxRetries = 0;
@@ -1892,13 +1854,11 @@ bool AdvancedOutput::StartRecording()
 						      filenameFormat,
 						      filenameFormat,
 						      ffmpegRecording);
 						      ffmpegRecording);
 
 
-		obs_data_t *settings = obs_data_create();
+		OBSDataAutoRelease settings = obs_data_create();
 		obs_data_set_string(settings, ffmpegRecording ? "url" : "path",
 		obs_data_set_string(settings, ffmpegRecording ? "url" : "path",
 				    strPath.c_str());
 				    strPath.c_str());
 
 
 		obs_output_update(fileOutput, settings);
 		obs_output_update(fileOutput, settings);
-
-		obs_data_release(settings);
 	}
 	}
 
 
 	if (!obs_output_start(fileOutput)) {
 	if (!obs_output_start(fileOutput)) {
@@ -1967,7 +1927,7 @@ bool AdvancedOutput::StartReplayBuffer()
 		string strPath = GetOutputFilename(
 		string strPath = GetOutputFilename(
 			path, recFormat, noSpace, overwriteIfExists, f.c_str());
 			path, recFormat, noSpace, overwriteIfExists, f.c_str());
 
 
-		obs_data_t *settings = obs_data_create();
+		OBSDataAutoRelease settings = obs_data_create();
 
 
 		obs_data_set_string(settings, "directory", path);
 		obs_data_set_string(settings, "directory", path);
 		obs_data_set_string(settings, "format", f.c_str());
 		obs_data_set_string(settings, "format", f.c_str());
@@ -1978,8 +1938,6 @@ bool AdvancedOutput::StartReplayBuffer()
 				 usesBitrate ? 0 : rbSize);
 				 usesBitrate ? 0 : rbSize);
 
 
 		obs_output_update(replayBuffer, settings);
 		obs_output_update(replayBuffer, settings);
-
-		obs_data_release(settings);
 	}
 	}
 
 
 	if (!obs_output_start(replayBuffer)) {
 	if (!obs_output_start(replayBuffer)) {

+ 4 - 4
UI/window-basic-main-outputs.hpp

@@ -5,10 +5,10 @@
 class OBSBasic;
 class OBSBasic;
 
 
 struct BasicOutputHandler {
 struct BasicOutputHandler {
-	OBSOutput fileOutput;
-	OBSOutput streamOutput;
-	OBSOutput replayBuffer;
-	OBSOutput virtualCam;
+	OBSOutputAutoRelease fileOutput;
+	OBSOutputAutoRelease streamOutput;
+	OBSOutputAutoRelease replayBuffer;
+	OBSOutputAutoRelease virtualCam;
 	bool streamingActive = false;
 	bool streamingActive = false;
 	bool recordingActive = false;
 	bool recordingActive = false;
 	bool delayActive = false;
 	bool delayActive = false;

+ 1 - 3
UI/window-basic-main-scene-collections.cpp

@@ -53,7 +53,7 @@ void EnumSceneCollections(std::function<bool(const char *, const char *)> &&cb)
 		if (glob->gl_pathv[i].directory)
 		if (glob->gl_pathv[i].directory)
 			continue;
 			continue;
 
 
-		obs_data_t *data =
+		OBSDataAutoRelease data =
 			obs_data_create_from_json_file_safe(filePath, "bak");
 			obs_data_create_from_json_file_safe(filePath, "bak");
 		std::string name = obs_data_get_string(data, "name");
 		std::string name = obs_data_get_string(data, "name");
 
 
@@ -64,8 +64,6 @@ void EnumSceneCollections(std::function<bool(const char *, const char *)> &&cb)
 			name.resize(name.size() - 5);
 			name.resize(name.size() - 5);
 		}
 		}
 
 
-		obs_data_release(data);
-
 		if (!cb(name.c_str(), filePath))
 		if (!cb(name.c_str(), filePath))
 			break;
 			break;
 	}
 	}

+ 31 - 60
UI/window-basic-main-transitions.cpp

@@ -68,7 +68,7 @@ void OBSBasic::InitDefaultTransitions()
 		const char *name = obs_source_get_display_name(id);
 		const char *name = obs_source_get_display_name(id);
 
 
 		if (!obs_is_source_configurable(id)) {
 		if (!obs_is_source_configurable(id)) {
-			obs_source_t *tr =
+			OBSSourceAutoRelease tr =
 				obs_source_create_private(id, name, NULL);
 				obs_source_create_private(id, name, NULL);
 			InitTransition(tr);
 			InitTransition(tr);
 			transitions.emplace_back(tr);
 			transitions.emplace_back(tr);
@@ -77,8 +77,6 @@ void OBSBasic::InitDefaultTransitions()
 				fadeTransition = tr;
 				fadeTransition = tr;
 			else if (strcmp(id, "cut_transition") == 0)
 			else if (strcmp(id, "cut_transition") == 0)
 				cutTransition = tr;
 				cutTransition = tr;
-
-			obs_source_release(tr);
 		} else {
 		} else {
 			AddTransitionVal val;
 			AddTransitionVal val;
 			val.name = QTStr("Add") + QStringLiteral(": ") +
 			val.name = QTStr("Add") + QStringLiteral(": ") +
@@ -239,8 +237,9 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
 	quickTransitionIdCounter = 1;
 	quickTransitionIdCounter = 1;
 
 
 	for (size_t i = 0; i < count; i++) {
 	for (size_t i = 0; i < count; i++) {
-		obs_data_t *data = obs_data_array_item(array, i);
-		obs_data_array_t *hotkeys = obs_data_get_array(data, "hotkeys");
+		OBSDataAutoRelease data = obs_data_array_item(array, i);
+		OBSDataArrayAutoRelease hotkeys =
+			obs_data_get_array(data, "hotkeys");
 		const char *name = obs_data_get_string(data, "name");
 		const char *name = obs_data_get_string(data, "name");
 		int duration = obs_data_get_int(data, "duration");
 		int duration = obs_data_get_int(data, "duration");
 		int id = obs_data_get_int(data, "id");
 		int id = obs_data_get_int(data, "id");
@@ -262,9 +261,6 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
 						hotkeys);
 						hotkeys);
 			}
 			}
 		}
 		}
-
-		obs_data_release(data);
-		obs_data_array_release(hotkeys);
 	}
 	}
 }
 }
 
 
@@ -273,8 +269,8 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
 	obs_data_array_t *array = obs_data_array_create();
 	obs_data_array_t *array = obs_data_array_create();
 
 
 	for (QuickTransition &qt : quickTransitions) {
 	for (QuickTransition &qt : quickTransitions) {
-		obs_data_t *data = obs_data_create();
-		obs_data_array_t *hotkeys = obs_hotkey_save(qt.hotkey);
+		OBSDataAutoRelease data = obs_data_create();
+		OBSDataArrayAutoRelease hotkeys = obs_hotkey_save(qt.hotkey);
 
 
 		obs_data_set_string(data, "name",
 		obs_data_set_string(data, "name",
 				    obs_source_get_name(qt.source));
 				    obs_source_get_name(qt.source));
@@ -284,9 +280,6 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
 		obs_data_set_bool(data, "fade_to_black", qt.fadeToBlack);
 		obs_data_set_bool(data, "fade_to_black", qt.fadeToBlack);
 
 
 		obs_data_array_push_back(array, data);
 		obs_data_array_push_back(array, data);
-
-		obs_data_release(data);
-		obs_data_array_release(hotkeys);
 	}
 	}
 
 
 	return array;
 	return array;
@@ -333,15 +326,13 @@ void OBSBasic::TransitionStopped()
 
 
 void OBSBasic::OverrideTransition(OBSSource transition)
 void OBSBasic::OverrideTransition(OBSSource transition)
 {
 {
-	obs_source_t *oldTransition = obs_get_output_source(0);
+	OBSSourceAutoRelease oldTransition = obs_get_output_source(0);
 
 
 	if (transition != oldTransition) {
 	if (transition != oldTransition) {
 		obs_transition_swap_begin(transition, oldTransition);
 		obs_transition_swap_begin(transition, oldTransition);
 		obs_set_output_source(0, transition);
 		obs_set_output_source(0, transition);
 		obs_transition_swap_end(transition, oldTransition);
 		obs_transition_swap_end(transition, oldTransition);
 	}
 	}
-
-	obs_source_release(oldTransition);
 }
 }
 
 
 void OBSBasic::TransitionFullyStopped()
 void OBSBasic::TransitionFullyStopped()
@@ -387,13 +378,12 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force,
 		source = obs_scene_get_source(scene);
 		source = obs_scene_get_source(scene);
 	}
 	}
 
 
-	OBSSource transition = obs_get_output_source(0);
+	OBSSourceAutoRelease transition = obs_get_output_source(0);
 	if (!transition) {
 	if (!transition) {
 		if (usingPreviewProgram && sceneDuplicationMode)
 		if (usingPreviewProgram && sceneDuplicationMode)
 			obs_scene_release(scene);
 			obs_scene_release(scene);
 		return;
 		return;
 	}
 	}
-	obs_source_release(transition);
 
 
 	float t = obs_transition_get_time(transition);
 	float t = obs_transition_get_time(transition);
 	bool stillTransitioning = t < 1.0f && t > 0.0f;
 	bool stillTransitioning = t < 1.0f && t > 0.0f;
@@ -462,8 +452,7 @@ static inline void SetComboTransition(QComboBox *combo, obs_source_t *tr)
 
 
 void OBSBasic::SetTransition(OBSSource transition)
 void OBSBasic::SetTransition(OBSSource transition)
 {
 {
-	obs_source_t *oldTransition = obs_get_output_source(0);
-	obs_source_release(oldTransition);
+	OBSSourceAutoRelease oldTransition = obs_get_output_source(0);
 
 
 	if (transition == oldTransition)
 	if (transition == oldTransition)
 		return;
 		return;
@@ -561,9 +550,8 @@ void OBSBasic::AddTransition(QString id)
 		ClearQuickTransitionWidgets();
 		ClearQuickTransitionWidgets();
 		RefreshQuickTransitions();
 		RefreshQuickTransitions();
 	} else {
 	} else {
-		obs_source_t *transition = obs_get_output_source(0);
+		OBSSourceAutoRelease transition = obs_get_output_source(0);
 		SetComboTransition(ui->transitions, transition);
 		SetComboTransition(ui->transitions, transition);
-		obs_source_release(transition);
 	}
 	}
 }
 }
 
 
@@ -929,8 +917,7 @@ void OBSBasic::TBarReleased()
 {
 {
 	int val = tBar->value();
 	int val = tBar->value();
 
 
-	OBSSource transition = obs_get_output_source(0);
-	obs_source_release(transition);
+	OBSSourceAutoRelease transition = obs_get_output_source(0);
 
 
 	if ((tBar->maximum() - val) <= T_BAR_CLAMP) {
 	if ((tBar->maximum() - val) <= T_BAR_CLAMP) {
 		obs_transition_set_manual_time(transition, 1.0f);
 		obs_transition_set_manual_time(transition, 1.0f);
@@ -968,8 +955,7 @@ static bool ValidTBarTransition(OBSSource transition)
 
 
 void OBSBasic::TBarChanged(int value)
 void OBSBasic::TBarChanged(int value)
 {
 {
-	OBSSource transition = obs_get_output_source(0);
-	obs_source_release(transition);
+	OBSSourceAutoRelease transition = obs_get_output_source(0);
 
 
 	tBar->setValue(value);
 	tBar->setValue(value);
 
 
@@ -1029,8 +1015,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
 	QMenu *menu = new QMenu(QTStr("TransitionOverride"));
 	QMenu *menu = new QMenu(QTStr("TransitionOverride"));
 	QAction *action;
 	QAction *action;
 
 
-	OBSData data = obs_source_get_private_settings(scene);
-	obs_data_release(data);
+	OBSDataAutoRelease data = obs_source_get_private_settings(scene);
 
 
 	obs_data_set_default_int(data, "transition_duration", 300);
 	obs_data_set_default_int(data, "transition_duration", 300);
 
 
@@ -1047,8 +1032,8 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
 	auto setTransition = [this](QAction *action) {
 	auto setTransition = [this](QAction *action) {
 		int idx = action->property("transition_index").toInt();
 		int idx = action->property("transition_index").toInt();
 		OBSSource scene = GetCurrentSceneSource();
 		OBSSource scene = GetCurrentSceneSource();
-		OBSData data = obs_source_get_private_settings(scene);
-		obs_data_release(data);
+		OBSDataAutoRelease data =
+			obs_source_get_private_settings(scene);
 
 
 		if (idx == -1) {
 		if (idx == -1) {
 			obs_data_set_string(data, "transition", "");
 			obs_data_set_string(data, "transition", "");
@@ -1065,8 +1050,8 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
 
 
 	auto setDuration = [this](int duration) {
 	auto setDuration = [this](int duration) {
 		OBSSource scene = GetCurrentSceneSource();
 		OBSSource scene = GetCurrentSceneSource();
-		OBSData data = obs_source_get_private_settings(scene);
-		obs_data_release(data);
+		OBSDataAutoRelease data =
+			obs_source_get_private_settings(scene);
 
 
 		obs_data_set_int(data, "transition_duration", duration);
 		obs_data_set_int(data, "transition_duration", duration);
 	};
 	};
@@ -1163,20 +1148,18 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
 
 
 		auto undo_redo = [sceneName, sceneItemId,
 		auto undo_redo = [sceneName, sceneItemId,
 				  visible](const std::string &data) {
 				  visible](const std::string &data) {
-			obs_source_t *source =
+			OBSSourceAutoRelease source =
 				obs_get_source_by_name(sceneName.c_str());
 				obs_get_source_by_name(sceneName.c_str());
 			obs_scene_t *scene = obs_scene_from_source(source);
 			obs_scene_t *scene = obs_scene_from_source(source);
 			obs_sceneitem_t *i = obs_scene_find_sceneitem_by_id(
 			obs_sceneitem_t *i = obs_scene_find_sceneitem_by_id(
 				scene, sceneItemId);
 				scene, sceneItemId);
 			if (i) {
 			if (i) {
-				obs_data_t *dat =
+				OBSDataAutoRelease dat =
 					obs_data_create_from_json(data.c_str());
 					obs_data_create_from_json(data.c_str());
 				obs_sceneitem_transition_load(i, dat, visible);
 				obs_sceneitem_transition_load(i, dat, visible);
-				obs_data_release(dat);
 			}
 			}
-			obs_source_release(source);
 		};
 		};
-		obs_data_t *oldTransitionData =
+		OBSDataAutoRelease oldTransitionData =
 			obs_sceneitem_transition_save(sceneItem, visible);
 			obs_sceneitem_transition_save(sceneItem, visible);
 		if (id.isNull() || id.isEmpty()) {
 		if (id.isNull() || id.isEmpty()) {
 			if (visible)
 			if (visible)
@@ -1229,7 +1212,7 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
 			if (obs_source_configurable(tr))
 			if (obs_source_configurable(tr))
 				CreatePropertiesWindow(tr);
 				CreatePropertiesWindow(tr);
 		}
 		}
-		obs_data_t *newTransitionData =
+		OBSDataAutoRelease newTransitionData =
 			obs_sceneitem_transition_save(sceneItem, visible);
 			obs_sceneitem_transition_save(sceneItem, visible);
 		std::string undo_data(obs_data_get_json(oldTransitionData));
 		std::string undo_data(obs_data_get_json(oldTransitionData));
 		std::string redo_data(obs_data_get_json(newTransitionData));
 		std::string redo_data(obs_data_get_json(newTransitionData));
@@ -1241,8 +1224,6 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
 						obs_sceneitem_get_source(
 						obs_sceneitem_get_source(
 							sceneItem))),
 							sceneItem))),
 				undo_redo, undo_redo, undo_data, redo_data);
 				undo_redo, undo_redo, undo_data, redo_data);
-		obs_data_release(newTransitionData);
-		obs_data_release(oldTransitionData);
 	};
 	};
 	if (visible) {
 	if (visible) {
 		auto setDuration = [](int duration) {
 		auto setDuration = [](int duration) {
@@ -1612,7 +1593,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
 
 
 		OBSScene curScene = GetCurrentScene();
 		OBSScene curScene = GetCurrentScene();
 
 
-		obs_scene_t *dup;
+		OBSSceneAutoRelease dup;
 		if (sceneDuplicationMode) {
 		if (sceneDuplicationMode) {
 			dup = obs_scene_duplicate(
 			dup = obs_scene_duplicate(
 				curScene,
 				curScene,
@@ -1626,11 +1607,9 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
 			obs_scene_addref(dup);
 			obs_scene_addref(dup);
 		}
 		}
 
 
-		obs_source_t *transition = obs_get_output_source(0);
+		OBSSourceAutoRelease transition = obs_get_output_source(0);
 		obs_source_t *dup_source = obs_scene_get_source(dup);
 		obs_source_t *dup_source = obs_scene_get_source(dup);
 		obs_transition_set(transition, dup_source);
 		obs_transition_set(transition, dup_source);
-		obs_source_release(transition);
-		obs_scene_release(dup);
 
 
 		if (curScene) {
 		if (curScene) {
 			obs_source_t *source = obs_scene_get_source(curScene);
 			obs_source_t *source = obs_scene_get_source(curScene);
@@ -1779,8 +1758,8 @@ obs_data_array_t *OBSBasic::SaveTransitions()
 		if (!tr || !obs_source_configurable(tr))
 		if (!tr || !obs_source_configurable(tr))
 			continue;
 			continue;
 
 
-		obs_data_t *sourceData = obs_data_create();
-		obs_data_t *settings = obs_source_get_settings(tr);
+		OBSDataAutoRelease sourceData = obs_data_create();
+		OBSDataAutoRelease settings = obs_source_get_settings(tr);
 
 
 		obs_data_set_string(sourceData, "name",
 		obs_data_set_string(sourceData, "name",
 				    obs_source_get_name(tr));
 				    obs_source_get_name(tr));
@@ -1788,9 +1767,6 @@ obs_data_array_t *OBSBasic::SaveTransitions()
 		obs_data_set_obj(sourceData, "settings", settings);
 		obs_data_set_obj(sourceData, "settings", settings);
 
 
 		obs_data_array_push_back(transitions, sourceData);
 		obs_data_array_push_back(transitions, sourceData);
-
-		obs_data_release(settings);
-		obs_data_release(sourceData);
 	}
 	}
 
 
 	return transitions;
 	return transitions;
@@ -1802,12 +1778,13 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions,
 	size_t count = obs_data_array_count(transitions);
 	size_t count = obs_data_array_count(transitions);
 
 
 	for (size_t i = 0; i < count; i++) {
 	for (size_t i = 0; i < count; i++) {
-		obs_data_t *item = obs_data_array_item(transitions, i);
+		OBSDataAutoRelease item = obs_data_array_item(transitions, i);
 		const char *name = obs_data_get_string(item, "name");
 		const char *name = obs_data_get_string(item, "name");
 		const char *id = obs_data_get_string(item, "id");
 		const char *id = obs_data_get_string(item, "id");
-		obs_data_t *settings = obs_data_get_obj(item, "settings");
+		OBSDataAutoRelease settings =
+			obs_data_get_obj(item, "settings");
 
 
-		obs_source_t *source =
+		OBSSourceAutoRelease source =
 			obs_source_create_private(id, name, settings);
 			obs_source_create_private(id, name, settings);
 		if (!obs_obj_invalid(source)) {
 		if (!obs_obj_invalid(source)) {
 			InitTransition(source);
 			InitTransition(source);
@@ -1815,10 +1792,6 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions,
 			if (cb)
 			if (cb)
 				cb(private_data, source);
 				cb(private_data, source);
 		}
 		}
-
-		obs_data_release(settings);
-		obs_data_release(item);
-		obs_source_release(source);
 	}
 	}
 }
 }
 
 
@@ -1827,8 +1800,7 @@ OBSSource OBSBasic::GetOverrideTransition(OBSSource source)
 	if (!source)
 	if (!source)
 		return nullptr;
 		return nullptr;
 
 
-	OBSData data = obs_source_get_private_settings(source);
-	obs_data_release(data);
+	OBSDataAutoRelease data = obs_source_get_private_settings(source);
 
 
 	const char *trOverrideName = obs_data_get_string(data, "transition");
 	const char *trOverrideName = obs_data_get_string(data, "transition");
 
 
@@ -1845,8 +1817,7 @@ int OBSBasic::GetOverrideTransitionDuration(OBSSource source)
 	if (!source)
 	if (!source)
 		return 300;
 		return 300;
 
 
-	OBSData data = obs_source_get_private_settings(source);
-	obs_data_release(data);
+	OBSDataAutoRelease data = obs_source_get_private_settings(source);
 	obs_data_set_default_int(data, "transition_duration", 300);
 	obs_data_set_default_int(data, "transition_duration", 300);
 
 
 	return (int)obs_data_get_int(data, "transition_duration");
 	return (int)obs_data_get_int(data, "transition_duration");

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 143 - 245
UI/window-basic-main.cpp


+ 1 - 1
UI/window-basic-main.hpp

@@ -219,7 +219,7 @@ private:
 	ContextBarSize contextBarSize = ContextBarSize_Normal;
 	ContextBarSize contextBarSize = ContextBarSize_Normal;
 
 
 	std::deque<SourceCopyInfo> clipboard;
 	std::deque<SourceCopyInfo> clipboard;
-	OBSWeakSource copyFiltersSource;
+	OBSWeakSourceAutoRelease copyFiltersSource;
 	bool copyVisible = true;
 	bool copyVisible = true;
 
 
 	bool closing = false;
 	bool closing = false;

+ 6 - 18
UI/window-basic-preview.cpp

@@ -32,9 +32,6 @@ OBSBasicPreview::~OBSBasicPreview()
 		gs_vertexbuffer_destroy(rectFill);
 		gs_vertexbuffer_destroy(rectFill);
 
 
 	obs_leave_graphics();
 	obs_leave_graphics();
-
-	if (wrapper)
-		obs_data_release(wrapper);
 }
 }
 
 
 vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
 vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
@@ -568,8 +565,6 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
 	vec2_zero(&lastMoveOffset);
 	vec2_zero(&lastMoveOffset);
 
 
 	mousePos = startPos;
 	mousePos = startPos;
-	if (wrapper)
-		obs_data_release(wrapper);
 	wrapper =
 	wrapper =
 		obs_scene_save_transform_states(main->GetCurrentScene(), true);
 		obs_scene_save_transform_states(main->GetCurrentScene(), true);
 	changed = false;
 	changed = false;
@@ -706,17 +701,16 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
 		selectedItems.clear();
 		selectedItems.clear();
 	}
 	}
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
-	obs_data_t *rwrapper =
+	OBSDataAutoRelease rwrapper =
 		obs_scene_save_transform_states(main->GetCurrentScene(), true);
 		obs_scene_save_transform_states(main->GetCurrentScene(), true);
 
 
 	auto undo_redo = [](const std::string &data) {
 	auto undo_redo = [](const std::string &data) {
-		obs_data_t *dat = obs_data_create_from_json(data.c_str());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSDataAutoRelease dat =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			obs_data_get_string(dat, "scene_name"));
 			obs_data_get_string(dat, "scene_name"));
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-			->SetCurrentScene(source, true);
-		obs_source_release(source);
-		obs_data_release(dat);
+			->SetCurrentScene(source.Get(), true);
 
 
 		obs_scene_load_transform_states(data.c_str());
 		obs_scene_load_transform_states(data.c_str());
 	};
 	};
@@ -732,13 +726,7 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
 				undo_redo, undo_redo, undo_data, redo_data);
 				undo_redo, undo_redo, undo_data, redo_data);
 	}
 	}
 
 
-	if (wrapper)
-		obs_data_release(wrapper);
-
-	if (rwrapper)
-		obs_data_release(rwrapper);
-
-	wrapper = NULL;
+	wrapper = nullptr;
 }
 }
 
 
 struct SelectedItemBounds {
 struct SelectedItemBounds {

+ 1 - 1
UI/window-basic-preview.hpp

@@ -106,7 +106,7 @@ private:
 
 
 	void ProcessClick(const vec2 &pos);
 	void ProcessClick(const vec2 &pos);
 
 
-	obs_data_t *wrapper = NULL;
+	OBSDataAutoRelease wrapper = nullptr;
 	bool changed;
 	bool changed;
 
 
 public:
 public:

+ 25 - 50
UI/window-basic-properties.cpp

@@ -78,9 +78,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 	/* The OBSData constructor increments the reference once */
 	/* The OBSData constructor increments the reference once */
 	obs_data_release(oldSettings);
 	obs_data_release(oldSettings);
 
 
-	OBSData nd_settings = obs_source_get_settings(source);
+	OBSDataAutoRelease nd_settings = obs_source_get_settings(source);
 	obs_data_apply(oldSettings, nd_settings);
 	obs_data_apply(oldSettings, nd_settings);
-	obs_data_release(nd_settings);
 
 
 	auto handle_memory = [](void *vp, obs_data_t *old_settings,
 	auto handle_memory = [](void *vp, obs_data_t *old_settings,
 				obs_data_t *new_settings) {
 				obs_data_t *new_settings) {
@@ -93,7 +92,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 	};
 	};
 
 
 	view = new OBSPropertiesView(
 	view = new OBSPropertiesView(
-		nd_settings, source,
+		nd_settings.Get(), source,
 		(PropertiesReloadCallback)obs_source_properties,
 		(PropertiesReloadCallback)obs_source_properties,
 		(PropertiesUpdateCallback)handle_memory,
 		(PropertiesUpdateCallback)handle_memory,
 		(PropertiesVisualUpdateCb)obs_source_update);
 		(PropertiesVisualUpdateCb)obs_source_update);
@@ -163,14 +162,11 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 		sourceB =
 		sourceB =
 			obs_source_create_private("scene", "sourceB", nullptr);
 			obs_source_create_private("scene", "sourceB", nullptr);
 
 
-		obs_source_release(sourceA);
-		obs_source_release(sourceB);
-
 		uint32_t colorA = 0xFFB26F52;
 		uint32_t colorA = 0xFFB26F52;
 		uint32_t colorB = 0xFF6FB252;
 		uint32_t colorB = 0xFF6FB252;
 
 
-		CreateTransitionScene(sourceA, "A", colorA);
-		CreateTransitionScene(sourceB, "B", colorB);
+		CreateTransitionScene(sourceA.Get(), "A", colorA);
+		CreateTransitionScene(sourceB.Get(), "B", colorB);
 
 
 		/**
 		/**
 		 * The cloned source is made from scratch, rather than using
 		 * The cloned source is made from scratch, rather than using
@@ -178,27 +174,23 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 		 * play correctly otherwise.
 		 * play correctly otherwise.
 		 */
 		 */
 
 
-		obs_data_t *settings = obs_source_get_settings(source);
+		OBSDataAutoRelease settings = obs_source_get_settings(source);
 
 
 		sourceClone = obs_source_create_private(
 		sourceClone = obs_source_create_private(
 			obs_source_get_id(source), "clone", settings);
 			obs_source_get_id(source), "clone", settings);
-		obs_source_release(sourceClone);
 
 
 		obs_source_inc_active(sourceClone);
 		obs_source_inc_active(sourceClone);
 		obs_transition_set(sourceClone, sourceA);
 		obs_transition_set(sourceClone, sourceA);
 
 
-		obs_data_release(settings);
-
 		auto updateCallback = [=]() {
 		auto updateCallback = [=]() {
-			obs_data_t *settings = obs_source_get_settings(source);
+			OBSDataAutoRelease settings =
+				obs_source_get_settings(source);
 			obs_source_update(sourceClone, settings);
 			obs_source_update(sourceClone, settings);
 
 
 			obs_transition_clear(sourceClone);
 			obs_transition_clear(sourceClone);
 			obs_transition_set(sourceClone, sourceA);
 			obs_transition_set(sourceClone, sourceA);
 			obs_transition_force_stop(sourceClone);
 			obs_transition_force_stop(sourceClone);
 
 
-			obs_data_release(settings);
-
 			direction = true;
 			direction = true;
 		};
 		};
 
 
@@ -258,8 +250,8 @@ void OBSBasicProperties::AddPreviewButton()
 
 
 static obs_source_t *CreateLabel(const char *name, size_t h)
 static obs_source_t *CreateLabel(const char *name, size_t h)
 {
 {
-	obs_data_t *settings = obs_data_create();
-	obs_data_t *font = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
+	OBSDataAutoRelease font = obs_data_create();
 
 
 	std::string text;
 	std::string text;
 	text += " ";
 	text += " ";
@@ -289,26 +281,24 @@ static obs_source_t *CreateLabel(const char *name, size_t h)
 	obs_source_t *txtSource =
 	obs_source_t *txtSource =
 		obs_source_create_private(text_source_id, name, settings);
 		obs_source_create_private(text_source_id, name, settings);
 
 
-	obs_data_release(font);
-	obs_data_release(settings);
-
 	return txtSource;
 	return txtSource;
 }
 }
 
 
 static void CreateTransitionScene(OBSSource scene, const char *text,
 static void CreateTransitionScene(OBSSource scene, const char *text,
 				  uint32_t color)
 				  uint32_t color)
 {
 {
-	obs_data_t *settings = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
 	obs_data_set_int(settings, "width", obs_source_get_width(scene));
 	obs_data_set_int(settings, "width", obs_source_get_width(scene));
 	obs_data_set_int(settings, "height", obs_source_get_height(scene));
 	obs_data_set_int(settings, "height", obs_source_get_height(scene));
 	obs_data_set_int(settings, "color", color);
 	obs_data_set_int(settings, "color", color);
 
 
-	obs_source_t *colorBG = obs_source_create_private(
+	OBSSourceAutoRelease colorBG = obs_source_create_private(
 		"color_source", "background", settings);
 		"color_source", "background", settings);
 
 
 	obs_scene_add(obs_scene_from_source(scene), colorBG);
 	obs_scene_add(obs_scene_from_source(scene), colorBG);
 
 
-	obs_source_t *label = CreateLabel(text, obs_source_get_height(scene));
+	OBSSourceAutoRelease label =
+		CreateLabel(text, obs_source_get_height(scene));
 	obs_sceneitem_t *item =
 	obs_sceneitem_t *item =
 		obs_scene_add(obs_scene_from_source(scene), label);
 		obs_scene_add(obs_scene_from_source(scene), label);
 
 
@@ -322,10 +312,6 @@ static void CreateTransitionScene(OBSSource scene, const char *text,
 
 
 	obs_sceneitem_set_bounds(item, &size);
 	obs_sceneitem_set_bounds(item, &size);
 	obs_sceneitem_set_bounds_type(item, OBS_BOUNDS_SCALE_INNER);
 	obs_sceneitem_set_bounds_type(item, OBS_BOUNDS_SCALE_INNER);
-
-	obs_data_release(settings);
-	obs_source_release(colorBG);
-	obs_source_release(label);
 }
 }
 
 
 void OBSBasicProperties::SourceRemoved(void *data, calldata_t *params)
 void OBSBasicProperties::SourceRemoved(void *data, calldata_t *params)
@@ -361,27 +347,24 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 			obs_source_get_name(main->GetCurrentSceneSource());
 			obs_source_get_name(main->GetCurrentSceneSource());
 
 
 		auto undo_redo = [scene_name](const std::string &data) {
 		auto undo_redo = [scene_name](const std::string &data) {
-			obs_data_t *settings =
+			OBSDataAutoRelease settings =
 				obs_data_create_from_json(data.c_str());
 				obs_data_create_from_json(data.c_str());
-			obs_source_t *source = obs_get_source_by_name(
+			OBSSourceAutoRelease source = obs_get_source_by_name(
 				obs_data_get_string(settings, "undo_sname"));
 				obs_data_get_string(settings, "undo_sname"));
 			obs_source_reset_settings(source, settings);
 			obs_source_reset_settings(source, settings);
 
 
 			obs_source_update_properties(source);
 			obs_source_update_properties(source);
 
 
-			obs_source_t *scene_source =
+			OBSSourceAutoRelease scene_source =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
 
 
-			OBSBasic::Get()->SetCurrentScene(scene_source, true);
-
-			obs_source_release(scene_source);
-
-			obs_data_release(settings);
-			obs_source_release(source);
+			OBSBasic::Get()->SetCurrentScene(scene_source.Get(),
+							 true);
 		};
 		};
 
 
-		obs_data_t *new_settings = obs_data_create();
-		obs_data_t *curr_settings = obs_source_get_settings(source);
+		OBSDataAutoRelease new_settings = obs_data_create();
+		OBSDataAutoRelease curr_settings =
+			obs_source_get_settings(source);
 		obs_data_apply(new_settings, curr_settings);
 		obs_data_apply(new_settings, curr_settings);
 		obs_data_set_string(new_settings, "undo_sname",
 		obs_data_set_string(new_settings, "undo_sname",
 				    obs_source_get_name(source));
 				    obs_source_get_name(source));
@@ -397,9 +380,6 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 					.arg(obs_source_get_name(source)),
 					.arg(obs_source_get_name(source)),
 				undo_redo, undo_redo, undo_data, redo_data);
 				undo_redo, undo_redo, undo_data, redo_data);
 
 
-		obs_data_release(new_settings);
-		obs_data_release(curr_settings);
-
 		acceptClicked = true;
 		acceptClicked = true;
 		close();
 		close();
 
 
@@ -407,9 +387,8 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 			view->UpdateSettings();
 			view->UpdateSettings();
 
 
 	} else if (val == QDialogButtonBox::RejectRole) {
 	} else if (val == QDialogButtonBox::RejectRole) {
-		obs_data_t *settings = obs_source_get_settings(source);
+		OBSDataAutoRelease settings = obs_source_get_settings(source);
 		obs_data_clear(settings);
 		obs_data_clear(settings);
-		obs_data_release(settings);
 
 
 		if (view->DeferUpdate())
 		if (view->DeferUpdate())
 			obs_data_apply(settings, oldSettings);
 			obs_data_apply(settings, oldSettings);
@@ -419,9 +398,8 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 		close();
 		close();
 
 
 	} else if (val == QDialogButtonBox::ResetRole) {
 	} else if (val == QDialogButtonBox::ResetRole) {
-		obs_data_t *settings = obs_source_get_settings(source);
+		OBSDataAutoRelease settings = obs_source_get_settings(source);
 		obs_data_clear(settings);
 		obs_data_clear(settings);
-		obs_data_release(settings);
 
 
 		if (!view->DeferUpdate())
 		if (!view->DeferUpdate())
 			obs_source_update(source, nullptr);
 			obs_source_update(source, nullptr);
@@ -542,14 +520,11 @@ void OBSBasicProperties::Init()
 
 
 int OBSBasicProperties::CheckSettings()
 int OBSBasicProperties::CheckSettings()
 {
 {
-	OBSData currentSettings = obs_source_get_settings(source);
+	OBSDataAutoRelease currentSettings = obs_source_get_settings(source);
 	const char *oldSettingsJson = obs_data_get_json(oldSettings);
 	const char *oldSettingsJson = obs_data_get_json(oldSettings);
 	const char *currentSettingsJson = obs_data_get_json(currentSettings);
 	const char *currentSettingsJson = obs_data_get_json(currentSettings);
 
 
-	int ret = strcmp(currentSettingsJson, oldSettingsJson);
-
-	obs_data_release(currentSettings);
-	return ret;
+	return strcmp(currentSettingsJson, oldSettingsJson);
 }
 }
 
 
 bool OBSBasicProperties::ConfirmQuit()
 bool OBSBasicProperties::ConfirmQuit()

+ 3 - 3
UI/window-basic-properties.hpp

@@ -45,9 +45,9 @@ private:
 	QDialogButtonBox *buttonBox;
 	QDialogButtonBox *buttonBox;
 	QSplitter *windowSplitter;
 	QSplitter *windowSplitter;
 
 
-	OBSSource sourceA;
-	OBSSource sourceB;
-	OBSSource sourceClone;
+	OBSSourceAutoRelease sourceA;
+	OBSSourceAutoRelease sourceB;
+	OBSSourceAutoRelease sourceClone;
 	bool direction = true;
 	bool direction = true;
 
 
 	static void SourceRemoved(void *data, calldata_t *params);
 	static void SourceRemoved(void *data, calldata_t *params);

+ 12 - 24
UI/window-basic-settings-stream.cpp

@@ -108,7 +108,7 @@ void OBSBasicSettings::LoadStream1Settings()
 
 
 	loading = true;
 	loading = true;
 
 
-	obs_data_t *settings = obs_service_get_settings(service_obj);
+	OBSDataAutoRelease settings = obs_service_get_settings(service_obj);
 
 
 	const char *service = obs_data_get_string(settings, "service");
 	const char *service = obs_data_get_string(settings, "service");
 	const char *server = obs_data_get_string(settings, "server");
 	const char *server = obs_data_get_string(settings, "server");
@@ -159,8 +159,6 @@ void OBSBasicSettings::LoadStream1Settings()
 	lastService.clear();
 	lastService.clear();
 	on_service_currentIndexChanged(0);
 	on_service_currentIndexChanged(0);
 
 
-	obs_data_release(settings);
-
 	UpdateKeyLink();
 	UpdateKeyLink();
 	UpdateMoreInfoLink();
 	UpdateMoreInfoLink();
 	UpdateVodTrackSetting();
 	UpdateVodTrackSetting();
@@ -183,11 +181,9 @@ void OBSBasicSettings::SaveStream1Settings()
 	const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
 	const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
 
 
 	obs_service_t *oldService = main->GetService();
 	obs_service_t *oldService = main->GetService();
-	OBSData hotkeyData = obs_hotkeys_save_service(oldService);
-	obs_data_release(hotkeyData);
+	OBSDataAutoRelease hotkeyData = obs_hotkeys_save_service(oldService);
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	if (!customServer) {
 	if (!customServer) {
 		obs_data_set_string(settings, "service",
 		obs_data_set_string(settings, "service",
@@ -231,9 +227,8 @@ void OBSBasicSettings::SaveStream1Settings()
 
 
 	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
 	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
 
 
-	OBSService newService = obs_service_create(
+	OBSServiceAutoRelease newService = obs_service_create(
 		service_id, "default_service", settings, hotkeyData);
 		service_id, "default_service", settings, hotkeyData);
-	obs_service_release(newService);
 
 
 	if (!newService)
 	if (!newService)
 		return;
 		return;
@@ -262,8 +257,7 @@ void OBSBasicSettings::UpdateMoreInfoLink()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -289,8 +283,7 @@ void OBSBasicSettings::UpdateKeyLink()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -324,8 +317,7 @@ void OBSBasicSettings::LoadServices(bool showAll)
 {
 {
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_bool(settings, "show_all", showAll);
 	obs_data_set_bool(settings, "show_all", showAll);
 
 
@@ -509,8 +501,7 @@ void OBSBasicSettings::UpdateServerList()
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_properties_t *props = obs_get_service_properties("rtmp_common");
 	obs_property_t *services = obs_properties_get(props, "service");
 	obs_property_t *services = obs_properties_get(props, "service");
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
 	obs_property_modified(services, settings);
 	obs_property_modified(services, settings);
@@ -556,8 +547,7 @@ OBSService OBSBasicSettings::SpawnTempService()
 	bool custom = IsCustomService();
 	bool custom = IsCustomService();
 	const char *service_id = custom ? "rtmp_custom" : "rtmp_common";
 	const char *service_id = custom ? "rtmp_custom" : "rtmp_common";
 
 
-	OBSData settings = obs_data_create();
-	obs_data_release(settings);
+	OBSDataAutoRelease settings = obs_data_create();
 
 
 	if (!custom) {
 	if (!custom) {
 		obs_data_set_string(settings, "service",
 		obs_data_set_string(settings, "service",
@@ -572,11 +562,9 @@ OBSService OBSBasicSettings::SpawnTempService()
 	}
 	}
 	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
 	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
 
 
-	OBSService newService = obs_service_create(service_id, "temp_service",
-						   settings, nullptr);
-	obs_service_release(newService);
-
-	return newService;
+	OBSServiceAutoRelease newService = obs_service_create(
+		service_id, "temp_service", settings, nullptr);
+	return newService.Get();
 }
 }
 
 
 void OBSBasicSettings::OnOAuthStreamKeyConnected()
 void OBSBasicSettings::OnOAuthStreamKeyConnected()

+ 12 - 24
UI/window-basic-settings.cpp

@@ -1828,7 +1828,7 @@ OBSPropertiesView *
 OBSBasicSettings::CreateEncoderPropertyView(const char *encoder,
 OBSBasicSettings::CreateEncoderPropertyView(const char *encoder,
 					    const char *path, bool changed)
 					    const char *path, bool changed)
 {
 {
-	obs_data_t *settings = obs_encoder_defaults(encoder);
+	OBSDataAutoRelease settings = obs_encoder_defaults(encoder);
 	OBSPropertiesView *view;
 	OBSPropertiesView *view;
 
 
 	if (path) {
 	if (path) {
@@ -1844,13 +1844,12 @@ OBSBasicSettings::CreateEncoderPropertyView(const char *encoder,
 	}
 	}
 
 
 	view = new OBSPropertiesView(
 	view = new OBSPropertiesView(
-		settings, encoder,
+		settings.Get(), encoder,
 		(PropertiesReloadCallback)obs_get_encoder_properties, 170);
 		(PropertiesReloadCallback)obs_get_encoder_properties, 170);
 	view->setFrameShape(QFrame::StyledPanel);
 	view->setFrameShape(QFrame::StyledPanel);
 	view->setProperty("changed", QVariant(changed));
 	view->setProperty("changed", QVariant(changed));
 	QObject::connect(view, SIGNAL(Changed()), this, SLOT(OutputsChanged()));
 	QObject::connect(view, SIGNAL(Changed()), this, SLOT(OutputsChanged()));
 
 
-	obs_data_release(settings);
 	return view;
 	return view;
 }
 }
 
 
@@ -2210,9 +2209,9 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop,
 {
 {
 	size_t count = obs_property_list_item_count(prop);
 	size_t count = obs_property_list_item_count(prop);
 
 
-	obs_source_t *source = obs_get_output_source(index);
+	OBSSourceAutoRelease source = obs_get_output_source(index);
 	const char *deviceId = nullptr;
 	const char *deviceId = nullptr;
-	obs_data_t *settings = nullptr;
+	OBSDataAutoRelease settings = nullptr;
 
 
 	if (source) {
 	if (source) {
 		settings = obs_source_get_settings(source);
 		settings = obs_source_get_settings(source);
@@ -2243,11 +2242,6 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop,
 					       "errorLabel");
 					       "errorLabel");
 		}
 		}
 	}
 	}
-
-	if (settings)
-		obs_data_release(settings);
-	if (source)
-		obs_source_release(source);
 }
 }
 
 
 void OBSBasicSettings::LoadAudioDevices()
 void OBSBasicSettings::LoadAudioDevices()
@@ -3715,13 +3709,11 @@ void OBSBasicSettings::SaveHotkeySettings()
 		if (!hotkey.first)
 		if (!hotkey.first)
 			continue;
 			continue;
 
 
-		obs_data_array_t *array = obs_hotkey_save(hw.id);
-		obs_data_t *data = obs_data_create();
+		OBSDataArrayAutoRelease array = obs_hotkey_save(hw.id);
+		OBSDataAutoRelease data = obs_data_create();
 		obs_data_set_array(data, "bindings", array);
 		obs_data_set_array(data, "bindings", array);
 		const char *json = obs_data_get_json(data);
 		const char *json = obs_data_get_json(data);
 		config_set_string(config, "Hotkeys", hw.name.c_str(), json);
 		config_set_string(config, "Hotkeys", hw.name.c_str(), json);
-		obs_data_release(data);
-		obs_data_array_release(array);
 	}
 	}
 
 
 	if (!main->outputHandler || !main->outputHandler->replayBuffer)
 	if (!main->outputHandler || !main->outputHandler->replayBuffer)
@@ -3729,11 +3721,10 @@ void OBSBasicSettings::SaveHotkeySettings()
 
 
 	const char *id = obs_obj_get_id(main->outputHandler->replayBuffer);
 	const char *id = obs_obj_get_id(main->outputHandler->replayBuffer);
 	if (strcmp(id, "replay_buffer") == 0) {
 	if (strcmp(id, "replay_buffer") == 0) {
-		obs_data_t *hotkeys = obs_hotkeys_save_output(
+		OBSDataAutoRelease hotkeys = obs_hotkeys_save_output(
 			main->outputHandler->replayBuffer);
 			main->outputHandler->replayBuffer);
 		config_set_string(config, "Hotkeys", "ReplayBuffer",
 		config_set_string(config, "Hotkeys", "ReplayBuffer",
 				  obs_data_get_json(hotkeys));
 				  obs_data_get_json(hotkeys));
-		obs_data_release(hotkeys);
 	}
 	}
 }
 }
 
 
@@ -4785,10 +4776,10 @@ void OBSBasicSettings::AdvReplayBufferChanged()
 					 sizeof(encoderJsonPath),
 					 sizeof(encoderJsonPath),
 					 "recordEncoder.json");
 					 "recordEncoder.json");
 		if (ret > 0) {
 		if (ret > 0) {
-			obs_data_t *data = obs_data_create_from_json_file_safe(
-				encoderJsonPath, "bak");
+			OBSDataAutoRelease data =
+				obs_data_create_from_json_file_safe(
+					encoderJsonPath, "bak");
 			obs_data_apply(settings, data);
 			obs_data_apply(settings, data);
-			obs_data_release(data);
 		}
 		}
 	}
 	}
 
 
@@ -4858,8 +4849,8 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
 	delete simpleOutRecWarning;
 	delete simpleOutRecWarning;
 
 
 	if (enforceBitrate && service) {
 	if (enforceBitrate && service) {
-		obs_data_t *videoSettings = obs_data_create();
-		obs_data_t *audioSettings = obs_data_create();
+		OBSDataAutoRelease videoSettings = obs_data_create();
+		OBSDataAutoRelease audioSettings = obs_data_create();
 		int oldVBitrate = ui->simpleOutputVBitrate->value();
 		int oldVBitrate = ui->simpleOutputVBitrate->value();
 		int oldABitrate =
 		int oldABitrate =
 			ui->simpleOutputABitrate->currentText().toInt();
 			ui->simpleOutputABitrate->currentText().toInt();
@@ -4881,9 +4872,6 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
 			warning += SIMPLE_OUTPUT_WARNING("AudioBitrate")
 			warning += SIMPLE_OUTPUT_WARNING("AudioBitrate")
 					   .arg(newABitrate);
 					   .arg(newABitrate);
 		}
 		}
-
-		obs_data_release(videoSettings);
-		obs_data_release(audioSettings);
 	}
 	}
 
 
 	if (qual == "Lossless") {
 	if (qual == "Lossless") {

+ 16 - 28
UI/window-basic-source-select.cpp

@@ -136,13 +136,11 @@ static char *get_new_source_name(const char *name)
 	dstr_copy(&new_name, name);
 	dstr_copy(&new_name, name);
 
 
 	for (;;) {
 	for (;;) {
-		obs_source_t *existing_source =
+		OBSSourceAutoRelease existing_source =
 			obs_get_source_by_name(new_name.array);
 			obs_get_source_by_name(new_name.array);
 		if (!existing_source)
 		if (!existing_source)
 			break;
 			break;
 
 
-		obs_source_release(existing_source);
-
 		dstr_printf(&new_name, "%s %d", name, ++inc + 1);
 		dstr_printf(&new_name, "%s %d", name, ++inc + 1);
 	}
 	}
 
 
@@ -183,10 +181,9 @@ static void AddExisting(OBSSource source, bool visible, bool duplicate,
 static void AddExisting(const char *name, bool visible, bool duplicate,
 static void AddExisting(const char *name, bool visible, bool duplicate,
 			obs_transform_info *transform, obs_sceneitem_crop *crop)
 			obs_transform_info *transform, obs_sceneitem_crop *crop)
 {
 {
-	obs_source_t *source = obs_get_source_by_name(name);
+	OBSSourceAutoRelease source = obs_get_source_by_name(name);
 	if (source) {
 	if (source) {
-		AddExisting(source, visible, duplicate, transform, crop);
-		obs_source_release(source);
+		AddExisting(source.Get(), visible, duplicate, transform, crop);
 	}
 	}
 }
 }
 
 
@@ -199,7 +196,7 @@ bool AddNew(QWidget *parent, const char *id, const char *name,
 	if (!scene)
 	if (!scene)
 		return false;
 		return false;
 
 
-	obs_source_t *source = obs_get_source_by_name(name);
+	OBSSourceAutoRelease source = obs_get_source_by_name(name);
 	if (source && parent) {
 	if (source && parent) {
 		OBSMessageBox::information(parent, QTStr("NameExists.Title"),
 		OBSMessageBox::information(parent, QTStr("NameExists.Title"),
 					   QTStr("NameExists.Text"));
 					   QTStr("NameExists.Text"));
@@ -231,7 +228,6 @@ bool AddNew(QWidget *parent, const char *id, const char *name,
 		}
 		}
 	}
 	}
 
 
-	obs_source_release(source);
 	return success;
 	return success;
 }
 }
 
 
@@ -264,19 +260,17 @@ void OBSBasicSourceSelect::on_buttonBox_accepted()
 		std::string scene_name =
 		std::string scene_name =
 			obs_source_get_name(main->GetCurrentSceneSource());
 			obs_source_get_name(main->GetCurrentSceneSource());
 		auto undo = [scene_name, main](const std::string &data) {
 		auto undo = [scene_name, main](const std::string &data) {
-			obs_source_t *source =
+			OBSSourceAutoRelease source =
 				obs_get_source_by_name(data.c_str());
 				obs_get_source_by_name(data.c_str());
-			obs_source_release(source);
 			obs_source_remove(source);
 			obs_source_remove(source);
 
 
-			obs_source_t *scene_source =
+			OBSSourceAutoRelease scene_source =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
-			main->SetCurrentScene(scene_source, true);
-			obs_source_release(scene_source);
+			main->SetCurrentScene(scene_source.Get(), true);
 		};
 		};
-		obs_data_t *wrapper = obs_data_create();
+		OBSDataAutoRelease wrapper = obs_data_create();
 		obs_data_set_string(wrapper, "id", id);
 		obs_data_set_string(wrapper, "id", id);
-		obs_sceneitem_t *item = obs_scene_sceneitem_from_source(
+		OBSSceneItemAutoRelease item = obs_scene_sceneitem_from_source(
 			main->GetCurrentScene(), newSource);
 			main->GetCurrentScene(), newSource);
 		obs_data_set_int(wrapper, "item_id",
 		obs_data_set_int(wrapper, "item_id",
 				 obs_sceneitem_get_id(item));
 				 obs_sceneitem_get_id(item));
@@ -286,31 +280,26 @@ void OBSBasicSourceSelect::on_buttonBox_accepted()
 		obs_data_set_bool(wrapper, "visible", visible);
 		obs_data_set_bool(wrapper, "visible", visible);
 
 
 		auto redo = [scene_name, main](const std::string &data) {
 		auto redo = [scene_name, main](const std::string &data) {
-			obs_source_t *scene_source =
+			OBSSourceAutoRelease scene_source =
 				obs_get_source_by_name(scene_name.c_str());
 				obs_get_source_by_name(scene_name.c_str());
-			main->SetCurrentScene(scene_source, true);
-			obs_source_release(scene_source);
+			main->SetCurrentScene(scene_source.Get(), true);
 
 
-			obs_data_t *dat =
+			OBSDataAutoRelease dat =
 				obs_data_create_from_json(data.c_str());
 				obs_data_create_from_json(data.c_str());
 			OBSSource source;
 			OBSSource source;
 			AddNew(NULL, obs_data_get_string(dat, "id"),
 			AddNew(NULL, obs_data_get_string(dat, "id"),
 			       obs_data_get_string(dat, "name"),
 			       obs_data_get_string(dat, "name"),
 			       obs_data_get_bool(dat, "visible"), source);
 			       obs_data_get_bool(dat, "visible"), source);
-			obs_sceneitem_t *item = obs_scene_sceneitem_from_source(
-				main->GetCurrentScene(), source);
+			OBSSceneItemAutoRelease item =
+				obs_scene_sceneitem_from_source(
+					main->GetCurrentScene(), source);
 			obs_sceneitem_set_id(item, (int64_t)obs_data_get_int(
 			obs_sceneitem_set_id(item, (int64_t)obs_data_get_int(
 							   dat, "item_id"));
 							   dat, "item_id"));
-
-			obs_data_release(dat);
-			obs_sceneitem_release(item);
 		};
 		};
 		undo_s.add_action(QTStr("Undo.Add").arg(ui->sourceName->text()),
 		undo_s.add_action(QTStr("Undo.Add").arg(ui->sourceName->text()),
 				  undo, redo,
 				  undo, redo,
 				  std::string(obs_source_get_name(newSource)),
 				  std::string(obs_source_get_name(newSource)),
 				  std::string(obs_data_get_json(wrapper)));
 				  std::string(obs_data_get_json(wrapper)));
-		obs_data_release(wrapper);
-		obs_sceneitem_release(item);
 	}
 	}
 
 
 	done(DialogCode::Accepted);
 	done(DialogCode::Accepted);
@@ -353,9 +342,8 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_,
 
 
 	QString text{placeHolderText};
 	QString text{placeHolderText};
 	int i = 2;
 	int i = 2;
-	obs_source_t *source = nullptr;
+	OBSSourceAutoRelease source = nullptr;
 	while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) {
 	while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) {
-		obs_source_release(source);
 		text = QString("%1 %2").arg(placeHolderText).arg(i++);
 		text = QString("%1 %2").arg(placeHolderText).arg(i++);
 	}
 	}
 
 

+ 4 - 8
UI/window-basic-stats.cpp

@@ -287,10 +287,8 @@ void OBSBasicStats::Update()
 	struct obs_video_info ovi = {};
 	struct obs_video_info ovi = {};
 	obs_get_video_info(&ovi);
 	obs_get_video_info(&ovi);
 
 
-	OBSOutput strOutput = obs_frontend_get_streaming_output();
-	OBSOutput recOutput = obs_frontend_get_recording_output();
-	obs_output_release(strOutput);
-	obs_output_release(recOutput);
+	OBSOutputAutoRelease strOutput = obs_frontend_get_streaming_output();
+	OBSOutputAutoRelease recOutput = obs_frontend_get_recording_output();
 
 
 	if (!strOutput && !recOutput)
 	if (!strOutput && !recOutput)
 		return;
 		return;
@@ -487,10 +485,8 @@ void OBSBasicStats::Reset()
 	first_rendered = 0xFFFFFFFF;
 	first_rendered = 0xFFFFFFFF;
 	first_lagged = 0xFFFFFFFF;
 	first_lagged = 0xFFFFFFFF;
 
 
-	OBSOutput strOutput = obs_frontend_get_streaming_output();
-	OBSOutput recOutput = obs_frontend_get_recording_output();
-	obs_output_release(strOutput);
-	obs_output_release(recOutput);
+	OBSOutputAutoRelease strOutput = obs_frontend_get_streaming_output();
+	OBSOutputAutoRelease recOutput = obs_frontend_get_recording_output();
 
 
 	outputLabels[0].Reset(strOutput);
 	outputLabels[0].Reset(strOutput);
 	outputLabels[1].Reset(recOutput);
 	outputLabels[1].Reset(recOutput);

+ 6 - 11
UI/window-basic-transform.cpp

@@ -77,29 +77,26 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent)
 	std::string name = obs_source_get_name(obs_sceneitem_get_source(item));
 	std::string name = obs_source_get_name(obs_sceneitem_get_source(item));
 	setWindowTitle(QTStr("Basic.TransformWindow.Title").arg(name.c_str()));
 	setWindowTitle(QTStr("Basic.TransformWindow.Title").arg(name.c_str()));
 
 
-	obs_data_t *wrapper =
+	OBSDataAutoRelease wrapper =
 		obs_scene_save_transform_states(main->GetCurrentScene(), false);
 		obs_scene_save_transform_states(main->GetCurrentScene(), false);
 	undo_data = std::string(obs_data_get_json(wrapper));
 	undo_data = std::string(obs_data_get_json(wrapper));
 
 
-	obs_data_release(wrapper);
-
 	channelChangedSignal.Connect(obs_get_signal_handler(), "channel_change",
 	channelChangedSignal.Connect(obs_get_signal_handler(), "channel_change",
 				     OBSChannelChanged, this);
 				     OBSChannelChanged, this);
 }
 }
 
 
 OBSBasicTransform::~OBSBasicTransform()
 OBSBasicTransform::~OBSBasicTransform()
 {
 {
-	obs_data_t *wrapper =
+	OBSDataAutoRelease wrapper =
 		obs_scene_save_transform_states(main->GetCurrentScene(), false);
 		obs_scene_save_transform_states(main->GetCurrentScene(), false);
 
 
 	auto undo_redo = [](const std::string &data) {
 	auto undo_redo = [](const std::string &data) {
-		obs_data_t *dat = obs_data_create_from_json(data.c_str());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSDataAutoRelease dat =
+			obs_data_create_from_json(data.c_str());
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			obs_data_get_string(dat, "scene_name"));
 			obs_data_get_string(dat, "scene_name"));
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-			->SetCurrentScene(source, true);
-		obs_source_release(source);
-		obs_data_release(dat);
+			->SetCurrentScene(source.Get(), true);
 		obs_scene_load_transform_states(data.c_str());
 		obs_scene_load_transform_states(data.c_str());
 	};
 	};
 
 
@@ -110,8 +107,6 @@ OBSBasicTransform::~OBSBasicTransform()
 				.arg(obs_source_get_name(obs_scene_get_source(
 				.arg(obs_source_get_name(obs_scene_get_source(
 					main->GetCurrentScene()))),
 					main->GetCurrentScene()))),
 			undo_redo, undo_redo, undo_data, redo_data);
 			undo_redo, undo_redo, undo_data, redo_data);
-
-	obs_data_release(wrapper);
 }
 }
 
 
 void OBSBasicTransform::SetScene(OBSScene scene)
 void OBSBasicTransform::SetScene(OBSScene scene)

+ 1 - 3
UI/window-missing-files.cpp

@@ -265,13 +265,11 @@ QVariant MissingFilesModel::data(const QModelIndex &index, int role) const
 		   index.column() == MissingFilesColumn::Source) {
 		   index.column() == MissingFilesColumn::Source) {
 		OBSBasic *main =
 		OBSBasic *main =
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
-		obs_source_t *source = obs_get_source_by_name(
+		OBSSourceAutoRelease source = obs_get_source_by_name(
 			files[index.row()].source.toStdString().c_str());
 			files[index.row()].source.toStdString().c_str());
 
 
 		if (source) {
 		if (source) {
 			result = main->GetSourceIcon(obs_source_get_id(source));
 			result = main->GetSourceIcon(obs_source_get_id(source));
-
-			obs_source_release(source);
 		}
 		}
 	} else if (role == Qt::FontRole &&
 	} else if (role == Qt::FontRole &&
 		   index.column() == MissingFilesColumn::State) {
 		   index.column() == MissingFilesColumn::State) {

+ 5 - 10
UI/window-projector.cpp

@@ -153,8 +153,8 @@ void OBSProjector::SetHideCursor()
 
 
 static OBSSource CreateLabel(const char *name, size_t h)
 static OBSSource CreateLabel(const char *name, size_t h)
 {
 {
-	obs_data_t *settings = obs_data_create();
-	obs_data_t *font = obs_data_create();
+	OBSDataAutoRelease settings = obs_data_create();
+	OBSDataAutoRelease font = obs_data_create();
 
 
 	std::string text;
 	std::string text;
 	text += " ";
 	text += " ";
@@ -181,14 +181,10 @@ static OBSSource CreateLabel(const char *name, size_t h)
 	const char *text_source_id = "text_ft2_source";
 	const char *text_source_id = "text_ft2_source";
 #endif
 #endif
 
 
-	OBSSource txtSource =
+	OBSSourceAutoRelease txtSource =
 		obs_source_create_private(text_source_id, name, settings);
 		obs_source_create_private(text_source_id, name, settings);
-	obs_source_release(txtSource);
 
 
-	obs_data_release(font);
-	obs_data_release(settings);
-
-	return txtSource;
+	return txtSource.Get();
 }
 }
 
 
 static inline uint32_t labelOffset(obs_source_t *label, uint32_t cx)
 static inline uint32_t labelOffset(obs_source_t *label, uint32_t cx)
@@ -931,8 +927,7 @@ void OBSProjector::UpdateMultiview()
 	size_t i = 0;
 	size_t i = 0;
 	while (i < scenes.sources.num && numSrcs < maxSrcs) {
 	while (i < scenes.sources.num && numSrcs < maxSrcs) {
 		obs_source_t *src = scenes.sources.array[i++];
 		obs_source_t *src = scenes.sources.array[i++];
-		OBSData data = obs_source_get_private_settings(src);
-		obs_data_release(data);
+		OBSDataAutoRelease data = obs_source_get_private_settings(src);
 
 
 		obs_data_set_default_bool(data, "show_in_multiview", true);
 		obs_data_set_default_bool(data, "show_in_multiview", true);
 		if (!obs_data_get_bool(data, "show_in_multiview"))
 		if (!obs_data_get_bool(data, "show_in_multiview"))

+ 46 - 0
libobs/obs.hpp

@@ -47,6 +47,52 @@ using OBSWeakEncoder = OBSRef<obs_weak_encoder_t *, obs_weak_encoder_addref,
 using OBSWeakService = OBSRef<obs_weak_service_t *, obs_weak_service_addref,
 using OBSWeakService = OBSRef<obs_weak_service_t *, obs_weak_service_addref,
 			      obs_weak_service_release>;
 			      obs_weak_service_release>;
 
 
+inline void ___source_dummy_addref(obs_source_t *){};
+inline void ___scene_dummy_addref(obs_scene_t *){};
+inline void ___sceneitem_dummy_addref(obs_sceneitem_t *){};
+inline void ___data_dummy_addref(obs_data_t *){};
+inline void ___data_array_dummy_addref(obs_data_array_t *){};
+inline void ___output_dummy_addref(obs_output_t *){};
+inline void ___encoder_dummy_addref(obs_encoder_t *){};
+inline void ___service_dummy_addref(obs_service_t *){};
+
+inline void ___weak_source_dummy_addref(obs_weak_source_t *){};
+inline void ___weak_output_dummy_addref(obs_weak_output_t *){};
+inline void ___weak_encoder_dummy_addref(obs_weak_encoder_t *){};
+inline void ___weak_service_dummy_addref(obs_weak_service_t *){};
+
+using OBSSourceAutoRelease =
+	OBSRef<obs_source_t *, ___source_dummy_addref, obs_source_release>;
+using OBSSceneAutoRelease =
+	OBSRef<obs_scene_t *, ___scene_dummy_addref, obs_scene_release>;
+using OBSSceneItemAutoRelease =
+	OBSRef<obs_sceneitem_t *, ___sceneitem_dummy_addref,
+	       obs_sceneitem_release>;
+using OBSDataAutoRelease =
+	OBSRef<obs_data_t *, ___data_dummy_addref, obs_data_release>;
+using OBSDataArrayAutoRelease =
+	OBSRef<obs_data_array_t *, ___data_array_dummy_addref,
+	       obs_data_array_release>;
+using OBSOutputAutoRelease =
+	OBSRef<obs_output_t *, ___output_dummy_addref, obs_output_release>;
+using OBSEncoderAutoRelease =
+	OBSRef<obs_encoder_t *, ___encoder_dummy_addref, obs_encoder_release>;
+using OBSServiceAutoRelease =
+	OBSRef<obs_service_t *, ___service_dummy_addref, obs_service_release>;
+
+using OBSWeakSourceAutoRelease =
+	OBSRef<obs_weak_source_t *, ___weak_source_dummy_addref,
+	       obs_weak_source_release>;
+using OBSWeakOutputAutoRelease =
+	OBSRef<obs_weak_output_t *, ___weak_output_dummy_addref,
+	       obs_weak_output_release>;
+using OBSWeakEncoderAutoRelease =
+	OBSRef<obs_weak_encoder_t *, ___weak_encoder_dummy_addref,
+	       obs_weak_encoder_release>;
+using OBSWeakServiceAutoRelease =
+	OBSRef<obs_weak_service_t *, ___weak_service_dummy_addref,
+	       obs_weak_service_release>;
+
 template<typename T, void addref(T), void release(T)> class OBSRef {
 template<typename T, void addref(T), void release(T)> class OBSRef {
 	T val;
 	T val;
 
 

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.