Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/cmake/ui-dialogs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ target_sources(
dialogs/OBSBasicSourceSelect.hpp
dialogs/OBSBasicTransform.cpp
dialogs/OBSBasicTransform.hpp
dialogs/OBSBasicRBConfig.cpp
dialogs/OBSBasicRBConfig.hpp
dialogs/OBSBasicVCamConfig.cpp
dialogs/OBSBasicVCamConfig.hpp
dialogs/OBSLogViewer.cpp
Expand Down
1 change: 1 addition & 0 deletions frontend/cmake/ui-qt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ target_sources(
forms/OBSBasicProperties.ui
forms/OBSBasicSettings.ui
forms/OBSBasicSourceSelect.ui
forms/OBSBasicRBConfig.ui
forms/OBSBasicVCamConfig.ui
forms/OBSExtraBrowsers.ui
forms/OBSImporter.ui
Expand Down
1 change: 1 addition & 0 deletions frontend/cmake/ui-utility.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ target_sources(
utility/RemuxQueueModel.hpp
utility/RemuxWorker.cpp
utility/RemuxWorker.hpp
utility/ReplayBufferConfig.hpp
utility/SceneRenameDelegate.cpp
utility/SceneRenameDelegate.hpp
utility/ScreenshotObj.cpp
Expand Down
5 changes: 5 additions & 0 deletions frontend/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,11 @@ Basic.VCam.OutputType.Program="Program (Default)"
Basic.VCam.OutputSelection.NoSelection="No selection for this output type"
Basic.VCam.RestartWarning="The virtual camera will be restarted to apply this change"

# replay buffer configuration
Basic.Main.ReplayBufferConfig="Configure Replay Buffer"
Basic.ReplayBuffer.Config="Replay Buffer Configuration"
Basic.ReplayBuffer.OutputType="Output Type"

# basic mode file menu
Basic.MainMenu.File="&File"
Basic.MainMenu.File.Export="&Export"
Expand Down
57 changes: 57 additions & 0 deletions frontend/dialogs/OBSBasicRBConfig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "OBSBasicRBConfig.hpp"

#include <OBSApp.hpp>

#include "moc_OBSBasicRBConfig.cpp"

OBSBasicRBConfig::OBSBasicRBConfig(const ReplayBufferConfig &_config, bool _rbActive, QWidget *parent)
: config(_config),
rbActive(_rbActive),
QDialog(parent),
ui(new Ui::OBSBasicRBConfig)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

ui->setupUi(this);

ui->outputType->addItem(QTStr("Basic.VCam.OutputType.Program"), (int)RBOutputProgramView);
ui->outputType->addItem(QTStr("Basic.Scene"), (int)RBOutputSceneView);

ui->outputType->setCurrentIndex(ui->outputType->findData((int)config.type));
OutputTypeChanged();
connect(ui->outputType, &QComboBox::currentIndexChanged, this, &OBSBasicRBConfig::OutputTypeChanged);

connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &OBSBasicRBConfig::UpdateConfig);
}

void OBSBasicRBConfig::OutputTypeChanged()
{
ReplayBufferOutputType type = (ReplayBufferOutputType)ui->outputType->currentData().toInt();

ui->sceneSelection->clear();

if (type == RBOutputProgramView) {
ui->sceneSelection->setDisabled(true);
ui->sceneSelection->addItem(QTStr("Basic.VCam.OutputSelection.NoSelection"));
} else {
ui->sceneSelection->setDisabled(false);
BPtr<char *> scenes = obs_frontend_get_scene_names();
for (char **temp = scenes; *temp; temp++) {
ui->sceneSelection->addItem(*temp);

if (config.scene.compare(*temp) == 0)
ui->sceneSelection->setCurrentIndex(ui->sceneSelection->count() - 1);
}
}
}

void OBSBasicRBConfig::UpdateConfig()
{
ReplayBufferOutputType type = (ReplayBufferOutputType)ui->outputType->currentData().toInt();

config.type = type;
if (type == RBOutputSceneView)
config.scene = ui->sceneSelection->currentText().toStdString();

emit Accepted(config);
}
27 changes: 27 additions & 0 deletions frontend/dialogs/OBSBasicRBConfig.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "ui_OBSBasicRBConfig.h"

#include <utility/ReplayBufferConfig.hpp>

#include <QDialog>

class OBSBasicRBConfig : public QDialog {
Q_OBJECT

ReplayBufferConfig config;
bool rbActive;

public:
explicit OBSBasicRBConfig(const ReplayBufferConfig &config, bool rbActive, QWidget *parent = 0);

private slots:
void OutputTypeChanged();
void UpdateConfig();

private:
std::unique_ptr<Ui::OBSBasicRBConfig> ui;

signals:
void Accepted(const ReplayBufferConfig &config);
};
26 changes: 26 additions & 0 deletions frontend/forms/OBSBasicControls.ui
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,32 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="replayBufferConfigButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Basic.Main.ReplayBufferConfig</string>
</property>
<property name="accessibleName">
<string>Basic.Main.ReplayBufferConfig</string>
</property>
<property name="icon">
<iconset resource="obs.qrc">
<normaloff>:/settings/images/settings/general.svg</normaloff>:/settings/images/settings/general.svg</iconset>
</property>
<property name="class" stdset="0">
<string>icon-gear</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
Expand Down
97 changes: 97 additions & 0 deletions frontend/forms/OBSBasicRBConfig.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OBSBasicRBConfig</class>
<widget class="QDialog" name="OBSBasicRBConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>150</height>
</rect>
</property>
<property name="windowTitle">
<string>Basic.ReplayBuffer.Config</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="outputTypeLabel">
<property name="text">
<string>Basic.ReplayBuffer.OutputType</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="outputType"/>
</item>
<item>
<widget class="QLabel" name="sceneSelectionLabel">
<property name="text">
<string>Basic.Scene</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="sceneSelection"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>OBSBasicRBConfig</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>OBSBasicRBConfig</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
21 changes: 17 additions & 4 deletions frontend/utility/AdvancedOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,12 @@ inline void AdvancedOutput::SetupRecording()

if (useStreamEncoder) {
obs_output_set_video_encoder(fileOutput, videoStreaming);
if (replayBuffer)
obs_output_set_video_encoder(replayBuffer, videoStreaming);
if (replayBuffer) {
if (replayBufferVideoEncoder)
obs_output_set_video_encoder(replayBuffer, replayBufferVideoEncoder);
else
obs_output_set_video_encoder(replayBuffer, videoStreaming);
}
} else {
if (rescaleFilter != OBS_SCALE_DISABLE && rescaleRes && *rescaleRes) {
if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) {
Expand All @@ -367,8 +371,12 @@ inline void AdvancedOutput::SetupRecording()
obs_encoder_set_scaled_size(videoRecording, cx, cy);
obs_encoder_set_gpu_scale_type(videoRecording, (obs_scale_type)rescaleFilter);
obs_output_set_video_encoder(fileOutput, videoRecording);
if (replayBuffer)
obs_output_set_video_encoder(replayBuffer, videoRecording);
if (replayBuffer) {
if (replayBufferVideoEncoder)
obs_output_set_video_encoder(replayBuffer, replayBufferVideoEncoder);
else
obs_output_set_video_encoder(replayBuffer, videoRecording);
}
}

if (!flv) {
Expand Down Expand Up @@ -552,6 +560,9 @@ void AdvancedOutput::SetupOutputs()
SetupFFmpeg();
else
SetupRecording();

if (replayBufferVideoEncoder && replayBufferVideo)
obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo);
}

int AdvancedOutput::GetAudioBitrate(size_t i, const char *id) const
Expand Down Expand Up @@ -836,6 +847,8 @@ bool AdvancedOutput::StartRecording()

bool AdvancedOutput::StartReplayBuffer()
{
SetupReplayBufferSceneOverride(useStreamEncoder ? videoStreaming : videoRecording);

const char *path;
const char *recFormat;
const char *filenameFormat;
Expand Down
48 changes: 48 additions & 0 deletions frontend/utility/BasicOutputHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,54 @@ void BasicOutputHandler::DestroyVirtualCameraScene()
vCamSourceSceneItem = nullptr;
}

void BasicOutputHandler::SetupReplayBufferView(const std::string &sceneName)
{
DestroyReplayBufferView();

if (sceneName.empty())
return;

OBSSourceAutoRelease source = obs_get_source_by_name(sceneName.c_str());
if (!source)
return;

replayBufferView = obs_view_create();
obs_view_set_source(replayBufferView, 0, source);
replayBufferVideo = obs_view_add(replayBufferView);
}

void BasicOutputHandler::SetupReplayBufferSceneOverride(OBSEncoder baseEncoder)
{
if (main->rbConfig.type != RBOutputSceneView)
return;

SetupReplayBufferView(main->rbConfig.scene);
if (!replayBufferVideo)
return;

replayBufferVideoEncoder =
obs_video_encoder_create(obs_encoder_get_id(baseEncoder), "replay_buffer_video", nullptr, nullptr);

OBSDataAutoRelease settings = obs_encoder_get_settings(baseEncoder);
obs_encoder_update(replayBufferVideoEncoder, settings);
obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo);
}

void BasicOutputHandler::DestroyReplayBufferView()
{
replayBufferVideoEncoder = nullptr;

if (!replayBufferView)
return;

obs_view_remove(replayBufferView);
obs_view_set_source(replayBufferView, 0, nullptr);
replayBufferVideo = nullptr;

obs_view_destroy(replayBufferView);
replayBufferView = nullptr;
}

const char *FindAudioEncoderFromCodec(const char *type)
{
const char *alt_enc_id = nullptr;
Expand Down
10 changes: 9 additions & 1 deletion frontend/utility/BasicOutputHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ struct BasicOutputHandler {
obs_scene_t *vCamSourceScene = nullptr;
obs_sceneitem_t *vCamSourceSceneItem = nullptr;

obs_view_t *replayBufferView = nullptr;
video_t *replayBufferVideo = nullptr;
OBSEncoder replayBufferVideoEncoder;

std::unique_ptr<WHIPSimulcastEncoders> whipSimulcastEncoders;

std::string outputType;
Expand All @@ -68,7 +72,7 @@ struct BasicOutputHandler {

BasicOutputHandler(OBSBasic *main_);

virtual ~BasicOutputHandler() {};
virtual ~BasicOutputHandler() { DestroyReplayBufferView(); }

virtual std::shared_future<void> SetupStreaming(obs_service_t *service,
SetupStreamingContinuation_t continuation) = 0;
Expand All @@ -92,6 +96,10 @@ struct BasicOutputHandler {
virtual void DestroyVirtualCamView();
virtual void DestroyVirtualCameraScene();

void SetupReplayBufferView(const std::string &sceneName);
void SetupReplayBufferSceneOverride(OBSEncoder baseEncoder);
void DestroyReplayBufferView();

inline bool Active() const
{
return streamingActive || recordingActive || delayActive || replayBufferActive || virtualCamActive ||
Expand Down
Loading