1
0

decklink-captions.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <obs-frontend-api.h>
  2. #include <QMainWindow>
  3. #include <QAction>
  4. #include <obs.hpp>
  5. #include "decklink-captions.h"
  6. OBS_DECLARE_MODULE()
  7. OBS_MODULE_USE_DEFAULT_LOCALE("decklink-captons", "en-US")
  8. struct obs_captions {
  9. std::string source_name;
  10. OBSWeakSource source;
  11. void start();
  12. void stop();
  13. obs_captions();
  14. inline ~obs_captions() { stop(); }
  15. };
  16. obs_captions::obs_captions() {}
  17. static obs_captions *captions = nullptr;
  18. DecklinkCaptionsUI::DecklinkCaptionsUI(QWidget *parent)
  19. : QDialog(parent), ui(new Ui_CaptionsDialog)
  20. {
  21. ui->setupUi(this);
  22. setSizeGripEnabled(true);
  23. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  24. auto cb = [this](obs_source_t *source) {
  25. uint32_t caps = obs_source_get_output_flags(source);
  26. QString name = obs_source_get_name(source);
  27. if (caps & OBS_SOURCE_CEA_708)
  28. ui->source->addItem(name);
  29. OBSWeakSource weak = OBSGetWeakRef(source);
  30. if (weak == captions->source)
  31. ui->source->setCurrentText(name);
  32. return true;
  33. };
  34. using cb_t = decltype(cb);
  35. ui->source->blockSignals(true);
  36. ui->source->addItem(QStringLiteral(""));
  37. ui->source->setCurrentIndex(0);
  38. obs_enum_sources(
  39. [](void *data, obs_source_t *source) {
  40. return (*static_cast<cb_t *>(data))(source);
  41. },
  42. &cb);
  43. ui->source->blockSignals(false);
  44. }
  45. void DecklinkCaptionsUI::on_source_currentIndexChanged(int)
  46. {
  47. captions->stop();
  48. captions->source_name = ui->source->currentText().toUtf8().constData();
  49. captions->source = GetWeakSourceByName(captions->source_name.c_str());
  50. captions->start();
  51. }
  52. static void caption_callback(void *param, obs_source_t *source,
  53. const struct obs_source_cea_708 *captions)
  54. {
  55. UNUSED_PARAMETER(param);
  56. UNUSED_PARAMETER(source);
  57. obs_output *output = obs_frontend_get_streaming_output();
  58. if (output) {
  59. if (obs_frontend_streaming_active() &&
  60. obs_output_active(output)) {
  61. obs_output_caption(output, captions);
  62. }
  63. obs_output_release(output);
  64. }
  65. }
  66. void obs_captions::start()
  67. {
  68. OBSSource s = OBSGetStrongRef(source);
  69. if (!s) {
  70. //warn("Source invalid");
  71. return;
  72. }
  73. obs_source_add_caption_callback(s, caption_callback, nullptr);
  74. }
  75. void obs_captions::stop()
  76. {
  77. OBSSource s = OBSGetStrongRef(source);
  78. if (s)
  79. obs_source_remove_caption_callback(s, caption_callback,
  80. nullptr);
  81. }
  82. static void save_decklink_caption_data(obs_data_t *save_data, bool saving,
  83. void *)
  84. {
  85. if (saving) {
  86. obs_data_t *obj = obs_data_create();
  87. obs_data_set_string(obj, "source",
  88. captions->source_name.c_str());
  89. obs_data_set_obj(save_data, "decklink_captions", obj);
  90. obs_data_release(obj);
  91. } else {
  92. captions->stop();
  93. obs_data_t *obj =
  94. obs_data_get_obj(save_data, "decklink_captions");
  95. if (!obj)
  96. obj = obs_data_create();
  97. captions->source_name = obs_data_get_string(obj, "source");
  98. captions->source =
  99. GetWeakSourceByName(captions->source_name.c_str());
  100. obs_data_release(obj);
  101. captions->start();
  102. }
  103. }
  104. void addOutputUI(void)
  105. {
  106. QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
  107. obs_module_text("Decklink Captions"));
  108. captions = new obs_captions;
  109. auto cb = []() {
  110. obs_frontend_push_ui_translation(obs_module_get_string);
  111. QWidget *window = (QWidget *)obs_frontend_get_main_window();
  112. DecklinkCaptionsUI dialog(window);
  113. dialog.exec();
  114. obs_frontend_pop_ui_translation();
  115. };
  116. obs_frontend_add_save_callback(save_decklink_caption_data, nullptr);
  117. action->connect(action, &QAction::triggered, cb);
  118. }
  119. bool obs_module_load(void)
  120. {
  121. return true;
  122. }
  123. void obs_module_post_load(void)
  124. {
  125. if (!obs_get_module("decklink"))
  126. return;
  127. addOutputUI();
  128. }