static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder) {

	obs_data_t       *saveData = obs_data_create();
	obs_data_array_t *sourcesArray = obs_save_sources();
	obs_source_t     *currentScene = obs_get_output_source(0);
	const char       *sceneName = obs_source_get_name(currentScene);

	const char *sceneCollection = config_get_string(App()->mGetGlobalConfig(),
		"Basic", "SceneCollection");

	SaveAudioDevice(DESKTOP_AUDIO_1, 1, saveData);
	SaveAudioDevice(DESKTOP_AUDIO_2, 2, saveData);
	SaveAudioDevice(AUX_AUDIO_1, 3, saveData);
	SaveAudioDevice(AUX_AUDIO_2, 4, saveData);
	SaveAudioDevice(AUX_AUDIO_3, 5, saveData);

	obs_data_set_string(saveData, "current_scene", sceneName);
	obs_data_set_array(saveData, "scene_order", sceneOrder);
	obs_data_set_string(saveData, "name", sceneCollection);
	obs_data_set_array(saveData, "sources", sourcesArray);
	obs_data_array_release(sourcesArray);
	obs_source_release(currentScene);

	return saveData;
}
Esempio n. 2
0
/**
 * Start recording
 *
 * We request the default format used by pulse here because the data will be
 * converted and possibly re-sampled by obs anyway.
 *
 * For now we request a buffer length of 25ms although pulse seems to ignore
 * this setting for monitor streams. For "real" input streams this should work
 * fine though.
 */
static int_fast32_t pulse_start_recording(struct pulse_data *data)
{
	if (pulse_get_server_info(pulse_server_info, (void *) data) < 0) {
		blog(LOG_ERROR, "Unable to get server info !");
		return -1;
	}

	if (pulse_get_source_info(pulse_source_info, data->device,
			(void *) data) < 0) {
		blog(LOG_ERROR, "Unable to get source info !");
		return -1;
	}

	pa_sample_spec spec;
	spec.format   = data->format;
	spec.rate     = data->samples_per_sec;
	spec.channels = data->channels;

	if (!pa_sample_spec_valid(&spec)) {
		blog(LOG_ERROR, "Sample spec is not valid");
		return -1;
	}

	data->speakers = pulse_channels_to_obs_speakers(spec.channels);
	data->bytes_per_frame = pa_frame_size(&spec);

	data->stream = pulse_stream_new(obs_source_get_name(data->source),
		&spec, NULL);
	if (!data->stream) {
		blog(LOG_ERROR, "Unable to create stream");
		return -1;
	}

	pulse_lock();
	pa_stream_set_read_callback(data->stream, pulse_stream_read,
		(void *) data);
	pulse_unlock();

	pa_buffer_attr attr;
	attr.fragsize  = pa_usec_to_bytes(25000, &spec);
	attr.maxlength = (uint32_t) -1;
	attr.minreq    = (uint32_t) -1;
	attr.prebuf    = (uint32_t) -1;
	attr.tlength   = (uint32_t) -1;

	pa_stream_flags_t flags = PA_STREAM_ADJUST_LATENCY;

	pulse_lock();
	int_fast32_t ret = pa_stream_connect_record(data->stream, data->device,
		&attr, flags);
	pulse_unlock();
	if (ret < 0) {
		pulse_stop_recording(data);
		blog(LOG_ERROR, "Unable to connect to stream");
		return -1;
	}

	blog(LOG_INFO, "Started recording from '%s'", data->device);
	return 0;
}
obs_data_array_t *BiLiOBSMainWid::mSaveSceneListOrder() {

	obs_data_array_t *sceneOrder = obs_data_array_create();

#if 1
	obs_source_t* currentScene = obs_get_output_source(0);
	std::list<std::string> tmpSceneOrder;

	//获取所有场景
	for (OBSSource& src : OBSEnumSources())
	{
		if (strcmp(obs_source_get_id(src), "scene") == 0)
			tmpSceneOrder.push_back(obs_source_get_name(src));
	}

	//当前场景放在第一个
	if (currentScene)
	{
		std::string currentSceneName = obs_source_get_name(currentScene);
		auto x = std::find(tmpSceneOrder.begin(), tmpSceneOrder.end(), currentSceneName);
		assert(x != tmpSceneOrder.end());
		tmpSceneOrder.erase(x);
		tmpSceneOrder.push_front(obs_source_get_name(currentScene));
	}

	//保存场景顺序
	for (auto& x : tmpSceneOrder) {
		obs_data_t *data = obs_data_create();
		obs_data_set_string(data, "name", x.c_str());
		obs_data_array_push_back(sceneOrder, data);
		obs_data_release(data);
	}

	obs_source_release(currentScene);
#else
	for (int i = 0; i < ui->scenes->count(); i++) {
		obs_data_t *data = obs_data_create();
		obs_data_set_string(data, "name",
				QT_TO_UTF8(ui->scenes->item(i)->text()));
		obs_data_array_push_back(sceneOrder, data);
		obs_data_release(data);
	}
#endif

	return sceneOrder;
}
void OBSBasicSourceSelect::SourceAdded(OBSSource source)
{
	const char *name     = obs_source_get_name(source);
	const char *sourceId = obs_source_get_id(source);

	if (strcmp(sourceId, id) != 0)
		return;

	ui->sourceList->addItem(name);
}
OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
	: QDialog (parent),
	  ui      (new Ui::OBSBasicSourceSelect),
	  id      (id_)
{
	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

	ui->setupUi(this);

	ui->sourceList->setAttribute(Qt::WA_MacShowFocusRect, false);

	QString placeHolderText{QT_UTF8(GetSourceDisplayName(id))};

	QString text{placeHolderText};
	int i = 2;
	obs_source_t *source = nullptr;
	while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) {
		obs_source_release(source);
		text = QString("%1 %2").arg(placeHolderText).arg(i++);
	}

	ui->sourceName->setText(text);
	ui->sourceName->setFocus();	//Fixes deselect of text.
	ui->sourceName->selectAll();

	installEventFilter(CreateShortcutFilter());

	if (strcmp(id_, "scene") == 0) {
		OBSBasic *main = reinterpret_cast<OBSBasic*>(
				App()->GetMainWindow());
		OBSSource curSceneSource = main->GetCurrentSceneSource();

		ui->selectExisting->setChecked(true);
		ui->createNew->setChecked(false);
		ui->createNew->setEnabled(false);
		ui->sourceName->setEnabled(false);

		int count = main->ui->scenes->count();
		for (int i = 0; i < count; i++) {
			QListWidgetItem *item = main->ui->scenes->item(i);
			OBSScene scene = GetOBSRef<OBSScene>(item);
			OBSSource sceneSource = obs_scene_get_source(scene);

			if (curSceneSource == sceneSource)
				continue;

			const char *name = obs_source_get_name(sceneSource);
			ui->sourceList->addItem(QT_UTF8(name));
		}
	} else if (strcmp(id_, "group") == 0) {
		obs_enum_sources(EnumGroups, this);
	} else {
		obs_enum_sources(EnumSources, this);
	}
}
	OBSSourceLabel(const obs_source_t *source, QWidget *parent=nullptr,
			Qt::WindowFlags f=0)
		: QLabel(obs_source_get_name(source), parent, f),
		  renamedSignal(obs_source_get_signal_handler(source), "rename",
				  &OBSSourceLabel::SourceRenamed, this),
		  removedSignal(obs_source_get_signal_handler(source), "remove",
				  &OBSSourceLabel::SourceRemoved, this),
		  destroyedSignal(obs_source_get_signal_handler(source),
				  "destroy", &OBSSourceLabel::SourceDestroyed,
				  this)
	{}
bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t source)
{
	OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
	const char *name = obs_source_get_name(source);
	const char *id   = obs_source_get_id(source);

	if (strcmp(id, window->id) == 0)
		window->ui->sourceList->addItem(QT_UTF8(name));

	return true;
}
Esempio n. 8
0
/**
	Takes an OBS source and generates a JSON encoded string representing information about the source.
	
	@param source is the OBS source that we want to turn into json data
	@return json encoded string
*/
const char* obsSourceToJSON(obs_source_t *source)
{
	const char *name = obs_source_get_name(source);

	json_t *obj = json_object();
	json_object_set_new(obj, "name", json_string(name));
	json_object_set_new(obj, "width", json_integer(obs_source_get_width(source)));
	json_object_set_new(obj, "height", json_integer(obs_source_get_height(source)));
	const char *jsonString = json_dumps(obj, 0);
	free(obj);

	return jsonString;
}
Esempio n. 9
0
void OBSBasic::on_switchSceneBtn_clicked()
{
	tbliveLog.Log(lss_info, L"on_switchSceneBtn_clicked");

	OBSScene curScene = GetCurrentScene();
	obs_source_t * source = obs_scene_get_source(curScene);
	SetCurrentScene(source, false);

	TransitionToScene(source, false);

	m_streamingScene = source;
	SetTabStreamingStatus(QT_UTF8(obs_source_get_name(m_streamingScene)));

	CurrentTabSceneUpdateControls();
}
void OBSBasicSourceSelect::SourceRemoved(OBSSource source)
{
	const char *name     = obs_source_get_name(source);
	const char *sourceId = obs_source_get_id(source);

	if (strcmp(sourceId, id) != 0)
		return;

	QList<QListWidgetItem*> items =
		ui->sourceList->findItems(name, Qt::MatchFixedString);

	if (!items.count())
		return;

	delete items[0];
}
Esempio n. 11
0
static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
{
	const char            *name = obs_data_get_string(item_data, "name");
	obs_source_t          *source = obs_get_source_by_name(name);
	struct obs_scene_item *item;
	bool visible;

	if (!source) {
		blog(LOG_WARNING, "[scene_load_item] Source %s not found!",
				name);
		return;
	}

	item = obs_scene_add(scene, source);
	if (!item) {
		blog(LOG_WARNING, "[scene_load_item] Could not add source '%s' "
		                  "to scene '%s'!",
		                  name, obs_source_get_name(scene->source));
		
		obs_source_release(source);
		return;
	}

	obs_data_set_default_int(item_data, "align",
			OBS_ALIGN_TOP | OBS_ALIGN_LEFT);

	item->rot     = (float)obs_data_get_double(item_data, "rot");
	item->align   = (uint32_t)obs_data_get_int(item_data, "align");
	visible = obs_data_get_bool(item_data, "visible");
	obs_data_get_vec2(item_data, "pos",    &item->pos);
	obs_data_get_vec2(item_data, "scale",  &item->scale);

	set_visibility(item, visible);

	item->bounds_type =
		(enum obs_bounds_type)obs_data_get_int(item_data,
				"bounds_type");
	item->bounds_align =
		(uint32_t)obs_data_get_int(item_data, "bounds_align");
	obs_data_get_vec2(item_data, "bounds", &item->bounds);

	obs_source_release(source);

	update_item_transform(item);
}
bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source)
{
	OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
	const char *name = obs_source_get_name(source);
	const char *id   = obs_source_get_id(source);

	if (strcmp(id, window->id) == 0) {
		OBSBasic *main = reinterpret_cast<OBSBasic*>(
				App()->GetMainWindow());
		OBSScene scene = main->GetCurrentScene();

		obs_sceneitem_t *existing = obs_scene_get_group(scene, name);
		if (!existing)
			window->ui->sourceList->addItem(QT_UTF8(name));
	}

	return true;
}
Esempio n. 13
0
obs_data_t *obs_save_source(obs_source_t *source)
{
	obs_data_t *source_data = obs_data_create();
	obs_data_t *settings    = obs_source_get_settings(source);
	float      volume      = obs_source_get_volume(source);
	const char *name       = obs_source_get_name(source);
	const char *id         = obs_source_get_id(source);

	obs_source_save(source);

	obs_data_set_string(source_data, "name",     name);
	obs_data_set_string(source_data, "id",       id);
	obs_data_set_obj   (source_data, "settings", settings);
	obs_data_set_double(source_data, "volume",   volume);

	obs_data_release(settings);

	return source_data;
}
Esempio n. 14
0
static void scene_save_item(obs_data_array_t *array,
		struct obs_scene_item *item)
{
	obs_data_t *item_data = obs_data_create();
	const char *name     = obs_source_get_name(item->source);

	obs_data_set_string(item_data, "name",         name);
	obs_data_set_bool  (item_data, "visible",      item->user_visible);
	obs_data_set_double(item_data, "rot",          item->rot);
	obs_data_set_vec2 (item_data, "pos",          &item->pos);
	obs_data_set_vec2 (item_data, "scale",        &item->scale);
	obs_data_set_int   (item_data, "align",        (int)item->align);
	obs_data_set_int   (item_data, "bounds_type",  (int)item->bounds_type);
	obs_data_set_int   (item_data, "bounds_align", (int)item->bounds_align);
	obs_data_set_vec2 (item_data, "bounds",       &item->bounds);

	obs_data_array_push_back(array, item_data);
	obs_data_release(item_data);
}
Esempio n. 15
0
void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
{
	int mt = monitoringType->itemData(index).toInt();
	obs_source_set_monitoring_type(source, (obs_monitoring_type)mt);

	const char *type = nullptr;

	switch (mt) {
	case OBS_MONITORING_TYPE_NONE:
		type = "none";
		break;
	case OBS_MONITORING_TYPE_MONITOR_ONLY:
		type = "monitor only";
		break;
	case OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT:
		type = "monitor and output";
		break;
	}

	blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
			obs_source_get_name(source), type);
}
Esempio n. 16
0
static void scene_save_item(obs_data_array_t *array,
		struct obs_scene_item *item)
{
	obs_data_t *item_data = obs_data_create();
	const char *name     = obs_source_get_name(item->source);
	const char *scale_filter;

	obs_data_set_string(item_data, "name",         name);
	obs_data_set_bool  (item_data, "visible",      item->user_visible);
	obs_data_set_double(item_data, "rot",          item->rot);
	obs_data_set_vec2 (item_data, "pos",          &item->pos);
	obs_data_set_vec2 (item_data, "scale",        &item->scale);
	obs_data_set_int   (item_data, "align",        (int)item->align);
	obs_data_set_int   (item_data, "bounds_type",  (int)item->bounds_type);
	obs_data_set_int   (item_data, "bounds_align", (int)item->bounds_align);
	obs_data_set_vec2 (item_data, "bounds",       &item->bounds);
	obs_data_set_int  (item_data, "crop_left",    (int)item->crop.left);
	obs_data_set_int  (item_data, "crop_top",     (int)item->crop.top);
	obs_data_set_int  (item_data, "crop_right",   (int)item->crop.right);
	obs_data_set_int  (item_data, "crop_bottom",  (int)item->crop.bottom);

	if (item->scale_filter == OBS_SCALE_POINT)
		scale_filter = "point";
	else if (item->scale_filter == OBS_SCALE_BILINEAR)
		scale_filter = "bilinear";
	else if (item->scale_filter == OBS_SCALE_BICUBIC)
		scale_filter = "bicubic";
	else if (item->scale_filter == OBS_SCALE_LANCZOS)
		scale_filter = "lanczos";
	else
		scale_filter = "disable";

	obs_data_set_string(item_data, "scale_filter", scale_filter);

	obs_data_array_push_back(array, item_data);
	obs_data_release(item_data);
}
Esempio n. 17
0
OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
	: source(source_)
{
	QHBoxLayout *hlayout;
	signal_handler_t *handler = obs_source_get_signal_handler(source);
	const char *sourceName = obs_source_get_name(source);
	float vol = obs_source_get_volume(source);
	uint32_t flags = obs_source_get_flags(source);
	uint32_t mixers = obs_source_get_audio_mixers(source);

	forceMonoContainer             = new QWidget();
	mixerContainer                 = new QWidget();
	balanceContainer               = new QWidget();
	labelL                         = new QLabel();
	labelR                         = new QLabel();
	nameLabel                      = new QLabel();
	volume                         = new QDoubleSpinBox();
	forceMono                      = new QCheckBox();
	balance                        = new BalanceSlider();
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	monitoringType                 = new QComboBox();
#endif
	syncOffset                     = new QSpinBox();
	mixer1                         = new QCheckBox();
	mixer2                         = new QCheckBox();
	mixer3                         = new QCheckBox();
	mixer4                         = new QCheckBox();
	mixer5                         = new QCheckBox();
	mixer6                         = new QCheckBox();

	volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged,
			this);
	syncOffsetSignal.Connect(handler, "audio_sync", OBSSourceSyncChanged,
			this);
	flagsSignal.Connect(handler, "update_flags", OBSSourceFlagsChanged,
			this);
	mixersSignal.Connect(handler, "audio_mixers", OBSSourceMixersChanged,
			this);

	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	forceMonoContainer->setLayout(hlayout);
	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	mixerContainer->setLayout(hlayout);
	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	balanceContainer->setLayout(hlayout);
	balanceContainer->setMinimumWidth(100);

	labelL->setText("L");

	labelR->setText("R");

	nameLabel->setMinimumWidth(170);
	nameLabel->setText(QT_UTF8(sourceName));
	nameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

	volume->setMinimum(MIN_DB - 0.1);
	volume->setMaximum(MAX_DB);
	volume->setSingleStep(0.1);
	volume->setDecimals(1);
	volume->setSuffix(" dB");
	volume->setValue(obs_mul_to_db(vol));

	if (volume->value() < MIN_DB)
		volume->setSpecialValueText("-inf dB");

	forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0);

	forceMonoContainer->layout()->addWidget(forceMono);
	forceMonoContainer->layout()->setAlignment(forceMono,
			Qt::AlignHCenter | Qt::AlignVCenter);

	balance->setOrientation(Qt::Horizontal);
	balance->setMinimum(0);
	balance->setMaximum(100);
	balance->setTickPosition(QSlider::TicksAbove);
	balance->setTickInterval(50);

	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());

	const char *speakers = config_get_string(main->Config(), "Audio",
			"ChannelSetup");

	if (strcmp(speakers, "Mono") == 0)
		balance->setEnabled(false);
	else
		balance->setEnabled(true);

	float bal = obs_source_get_balance_value(source) * 100.0f;
	balance->setValue((int)bal);

	int64_t cur_sync = obs_source_get_sync_offset(source);
	syncOffset->setMinimum(-950);
	syncOffset->setMaximum(20000);
	syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC));

	int idx;
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"),
			(int)OBS_MONITORING_TYPE_NONE);
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"),
			(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"),
			(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
	int mt = (int)obs_source_get_monitoring_type(source);
	idx = monitoringType->findData(mt);
	monitoringType->setCurrentIndex(idx);
#endif

	mixer1->setText("1");
	mixer1->setChecked(mixers & (1<<0));
	mixer2->setText("2");
	mixer2->setChecked(mixers & (1<<1));
	mixer3->setText("3");
	mixer3->setChecked(mixers & (1<<2));
	mixer4->setText("4");
	mixer4->setChecked(mixers & (1<<3));
	mixer5->setText("5");
	mixer5->setChecked(mixers & (1<<4));
	mixer6->setText("6");
	mixer6->setChecked(mixers & (1<<5));

	speaker_layout sl = obs_source_get_speaker_layout(source);
 
	if (sl == SPEAKERS_STEREO) {
		balanceContainer->layout()->addWidget(labelL);
		balanceContainer->layout()->addWidget(balance);
		balanceContainer->layout()->addWidget(labelR);
		balanceContainer->setMaximumWidth(170);
	}

	mixerContainer->layout()->addWidget(mixer1);
	mixerContainer->layout()->addWidget(mixer2);
	mixerContainer->layout()->addWidget(mixer3);
	mixerContainer->layout()->addWidget(mixer4);
	mixerContainer->layout()->addWidget(mixer5);
	mixerContainer->layout()->addWidget(mixer6);

	QWidget::connect(volume, SIGNAL(valueChanged(double)),
			this, SLOT(volumeChanged(double)));
	QWidget::connect(forceMono, SIGNAL(clicked(bool)),
			this, SLOT(downmixMonoChanged(bool)));
	QWidget::connect(balance, SIGNAL(valueChanged(int)),
			this, SLOT(balanceChanged(int)));
	QWidget::connect(balance, SIGNAL(doubleClicked()),
			this, SLOT(ResetBalance()));
	QWidget::connect(syncOffset, SIGNAL(valueChanged(int)),
			this, SLOT(syncOffsetChanged(int)));
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)),
			this, SLOT(monitoringTypeChanged(int)));
#endif
	QWidget::connect(mixer1, SIGNAL(clicked(bool)),
			this, SLOT(mixer1Changed(bool)));
	QWidget::connect(mixer2, SIGNAL(clicked(bool)),
			this, SLOT(mixer2Changed(bool)));
	QWidget::connect(mixer3, SIGNAL(clicked(bool)),
			this, SLOT(mixer3Changed(bool)));
	QWidget::connect(mixer4, SIGNAL(clicked(bool)),
			this, SLOT(mixer4Changed(bool)));
	QWidget::connect(mixer5, SIGNAL(clicked(bool)),
			this, SLOT(mixer5Changed(bool)));
	QWidget::connect(mixer6, SIGNAL(clicked(bool)),
			this, SLOT(mixer6Changed(bool)));

	setObjectName(sourceName);
}
Esempio n. 18
0
void OBSProjector::UpdateMultiview()
{
	multiviewScenes.clear();
	multiviewLabels.clear();

	struct obs_video_info ovi;
	obs_get_video_info(&ovi);

	uint32_t w  = ovi.base_width;
	uint32_t h  = ovi.base_height;
	fw        = float(w);
	fh        = float(h);
	ratio     = fw / fh;

	struct obs_frontend_source_list scenes = {};
	obs_frontend_get_scenes(&scenes);

	multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Preview"),
			h / 2));
	multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Program"),
			h / 2));

	multiviewLayout = static_cast<MultiviewLayout>(config_get_int(
			GetGlobalConfig(), "BasicWindow", "MultiviewLayout"));

	drawLabel = config_get_bool(GetGlobalConfig(),
			"BasicWindow", "MultiviewDrawNames");

	drawSafeArea = config_get_bool(GetGlobalConfig(), "BasicWindow",
			"MultiviewDrawAreas");

	mouseSwitching = config_get_bool(GetGlobalConfig(), "BasicWindow",
			"MultiviewMouseSwitch");

	transitionOnDoubleClick = config_get_bool(GetGlobalConfig(),
			"BasicWindow", "TransitionOnDoubleClick");

	switch(multiviewLayout) {
	case MultiviewLayout::HORIZONTAL_TOP_24_SCENES:
		pvwprgCX   = fw / 3;
		pvwprgCY   = fh / 3;

		maxSrcs = 24;
		break;
	default:
		pvwprgCX   = fw / 2;
		pvwprgCY   = fh / 2;

		maxSrcs = 8;
	}

	ppiCX     = pvwprgCX - thicknessx2;
	ppiCY     = pvwprgCY - thicknessx2;
	ppiScaleX = (pvwprgCX - thicknessx2) / fw;
	ppiScaleY = (pvwprgCY - thicknessx2) / fh;

	scenesCX = pvwprgCX / 2;
	scenesCY = pvwprgCY / 2;
	siCX      = scenesCX - thicknessx2;
	siCY      = scenesCY - thicknessx2;
	siScaleX  = (scenesCX - thicknessx2) / fw;
	siScaleY  = (scenesCY - thicknessx2) / fh;

	numSrcs = 0;
	size_t i = 0;
	while (i < scenes.sources.num && numSrcs < maxSrcs) {
		obs_source_t *src = scenes.sources.array[i++];
		OBSData data = obs_source_get_private_settings(src);
		obs_data_release(data);

		obs_data_set_default_bool(data, "show_in_multiview", true);
		if (!obs_data_get_bool(data, "show_in_multiview"))
			continue;

		// We have a displayable source.
		numSrcs++;

		multiviewScenes.emplace_back(OBSGetWeakRef(src));
		obs_source_inc_showing(src);

		std::string name = std::to_string(numSrcs) + " - " +
				obs_source_get_name(src);
		multiviewLabels.emplace_back(CreateLabel(name.c_str(), h / 3));
	}

	obs_frontend_source_list_free(&scenes);
}
Esempio n. 19
0
static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
{
	const char            *name = obs_data_get_string(item_data, "name");
	obs_source_t          *source = obs_get_source_by_name(name);
	const char            *scale_filter_str;
	struct obs_scene_item *item;
	bool visible;

	if (!source) {
		blog(LOG_WARNING, "[scene_load_item] Source %s not found!",
				name);
		return;
	}

	item = obs_scene_add(scene, source);
	if (!item) {
		blog(LOG_WARNING, "[scene_load_item] Could not add source '%s' "
		                  "to scene '%s'!",
		                  name, obs_source_get_name(scene->source));
		
		obs_source_release(source);
		return;
	}

	obs_data_set_default_int(item_data, "align",
			OBS_ALIGN_TOP | OBS_ALIGN_LEFT);

	item->rot     = (float)obs_data_get_double(item_data, "rot");
	item->align   = (uint32_t)obs_data_get_int(item_data, "align");
	visible = obs_data_get_bool(item_data, "visible");
	obs_data_get_vec2(item_data, "pos",    &item->pos);
	obs_data_get_vec2(item_data, "scale",  &item->scale);

	set_visibility(item, visible);

	item->bounds_type =
		(enum obs_bounds_type)obs_data_get_int(item_data,
				"bounds_type");
	item->bounds_align =
		(uint32_t)obs_data_get_int(item_data, "bounds_align");
	obs_data_get_vec2(item_data, "bounds", &item->bounds);

	item->crop.left   = (uint32_t)obs_data_get_int(item_data, "crop_left");
	item->crop.top    = (uint32_t)obs_data_get_int(item_data, "crop_top");
	item->crop.right  = (uint32_t)obs_data_get_int(item_data, "crop_right");
	item->crop.bottom = (uint32_t)obs_data_get_int(item_data, "crop_bottom");

	scale_filter_str = obs_data_get_string(item_data, "scale_filter");
	item->scale_filter = OBS_SCALE_DISABLE;

	if (scale_filter_str) {
		if (astrcmpi(scale_filter_str, "point") == 0)
			item->scale_filter = OBS_SCALE_POINT;
		else if (astrcmpi(scale_filter_str, "bilinear") == 0)
			item->scale_filter = OBS_SCALE_BILINEAR;
		else if (astrcmpi(scale_filter_str, "bicubic") == 0)
			item->scale_filter = OBS_SCALE_BICUBIC;
		else if (astrcmpi(scale_filter_str, "lanczos") == 0)
			item->scale_filter = OBS_SCALE_LANCZOS;
	}

	if (item->item_render && !item_texture_enabled(item)) {
		obs_enter_graphics();
		gs_texrender_destroy(item->item_render);
		item->item_render = NULL;
		obs_leave_graphics();

	} else if (!item->item_render && item_texture_enabled(item)) {
		obs_enter_graphics();
		item->item_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
		obs_leave_graphics();
	}

	obs_source_release(source);

	update_item_transform(item);
}