| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 | #include <obs-frontend-api.h>#include <QMainWindow>#include <QAction>#include <obs.hpp>#include "decklink-captions.h"OBS_DECLARE_MODULE()OBS_MODULE_USE_DEFAULT_LOCALE("decklink-captons", "en-US")struct obs_captions {	std::string source_name;	OBSWeakSource source;	void start();	void stop();	obs_captions();	inline ~obs_captions() { stop(); }};obs_captions::obs_captions() {}static obs_captions *captions = nullptr;DecklinkCaptionsUI::DecklinkCaptionsUI(QWidget *parent) : QDialog(parent), ui(new Ui_CaptionsDialog){	ui->setupUi(this);	setSizeGripEnabled(true);	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);	auto cb = [this](obs_source_t *source) {		uint32_t caps = obs_source_get_output_flags(source);		QString name = obs_source_get_name(source);		if (caps & OBS_SOURCE_CEA_708)			ui->source->addItem(name);		OBSWeakSource weak = OBSGetWeakRef(source);		if (weak == captions->source)			ui->source->setCurrentText(name);		return true;	};	using cb_t = decltype(cb);	ui->source->blockSignals(true);	ui->source->addItem(QStringLiteral(""));	ui->source->setCurrentIndex(0);	obs_enum_sources([](void *data, obs_source_t *source) { return (*static_cast<cb_t *>(data))(source); }, &cb);	ui->source->blockSignals(false);}void DecklinkCaptionsUI::on_source_currentIndexChanged(int){	captions->stop();	captions->source_name = ui->source->currentText().toUtf8().constData();	captions->source = GetWeakSourceByName(captions->source_name.c_str());	captions->start();}static void caption_callback(void * /* param */, obs_source_t * /* source */, const struct obs_source_cea_708 *captions){	obs_output *output = obs_frontend_get_streaming_output();	if (output) {		if (obs_frontend_streaming_active() && obs_output_active(output)) {			obs_output_caption(output, captions);		}		obs_output_release(output);	}}void obs_captions::start(){	OBSSource s = OBSGetStrongRef(source);	if (!s) {		//warn("Source invalid");		return;	}	obs_source_add_caption_callback(s, caption_callback, nullptr);}void obs_captions::stop(){	OBSSource s = OBSGetStrongRef(source);	if (s)		obs_source_remove_caption_callback(s, caption_callback, nullptr);}static void save_decklink_caption_data(obs_data_t *save_data, bool saving, void *){	if (saving) {		obs_data_t *obj = obs_data_create();		obs_data_set_string(obj, "source", captions->source_name.c_str());		obs_data_set_obj(save_data, "decklink_captions", obj);		obs_data_release(obj);	} else {		captions->stop();		obs_data_t *obj = obs_data_get_obj(save_data, "decklink_captions");		if (!obj)			obj = obs_data_create();		captions->source_name = obs_data_get_string(obj, "source");		captions->source = GetWeakSourceByName(captions->source_name.c_str());		obs_data_release(obj);		captions->start();	}}void addOutputUI(void){	QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(obs_module_text("Decklink Captions"));	captions = new obs_captions;	auto cb = []() {		obs_frontend_push_ui_translation(obs_module_get_string);		QWidget *window = (QWidget *)obs_frontend_get_main_window();		DecklinkCaptionsUI dialog(window);		dialog.exec();		obs_frontend_pop_ui_translation();	};	obs_frontend_add_save_callback(save_decklink_caption_data, nullptr);	action->connect(action, &QAction::triggered, cb);}bool obs_module_load(void){	return true;}void obs_module_post_load(void){	if (!obs_get_module("decklink"))		return;	addOutputUI();}
 |