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; }
/** * 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; }
/** 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; }
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]; }
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; }
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; }
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); }
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); }
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); }
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); }
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); }
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); }