UI: Allow services to use different outputs

Allows a service to specify the output it needs in order to function as
configured.

NOTE: This functionality should be considered temporary as a seamless
means of implementing support for different output types within the same
service.  Ideally, different services should be used for this
functionality.
master
jp9000 2017-07-13 03:57:42 -07:00
parent 4d1672719f
commit 3491487c71
3 changed files with 106 additions and 59 deletions

View File

@ -157,6 +157,8 @@ static inline void string_depad_key(string &key)
}
}
const char *FindAudioEncoderFromCodec(const char *type);
void AutoConfigTestPage::TestBandwidthThread()
{
bool connected = false;
@ -189,9 +191,6 @@ void AutoConfigTestPage::TestBandwidthThread()
"test_aac", nullptr, 0, nullptr);
OBSService service = obs_service_create(serverType,
"test_service", nullptr, nullptr);
OBSOutput output = obs_output_create("rtmp_output",
"test_stream", nullptr, nullptr);
obs_output_release(output);
obs_encoder_release(vencoder);
obs_encoder_release(aencoder);
obs_service_release(service);
@ -251,19 +250,29 @@ void AutoConfigTestPage::TestBandwidthThread()
servers.resize(1);
/* -----------------------------------*/
/* apply settings */
/* apply service settings */
obs_service_update(service, service_settings);
obs_service_apply_encoder_settings(service,
vencoder_settings, aencoder_settings);
obs_encoder_update(vencoder, vencoder_settings);
obs_encoder_update(aencoder, aencoder_settings);
/* -----------------------------------*/
/* create output */
const char *output_type = obs_service_get_output_type(service);
if (!output_type)
output_type = "rtmp_output";
OBSOutput output = obs_output_create(output_type,
"test_stream", nullptr, nullptr);
obs_output_release(output);
obs_output_update(output, output_settings);
/* -----------------------------------*/
/* connect encoders/services/outputs */
obs_encoder_update(vencoder, vencoder_settings);
obs_encoder_update(aencoder, aencoder_settings);
obs_encoder_set_video(vencoder, obs_get_video());
obs_encoder_set_audio(aencoder, obs_get_audio());

View File

@ -313,12 +313,6 @@ void SimpleOutput::LoadRecordingPreset()
SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
{
streamOutput = obs_output_create("rtmp_output", "simple_stream",
nullptr, nullptr);
if (!streamOutput)
throw "Failed to create stream output (simple output)";
obs_output_release(streamOutput);
const char *encoder = config_get_string(main->Config(), "SimpleOutput",
"StreamEncoder");
if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0)
@ -334,16 +328,6 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
"simple_aac", 0))
throw "Failed to create aac streaming encoder (simple output)";
streamDelayStarting.Connect(obs_output_get_signal_handler(streamOutput),
"starting", OBSStreamStarting, this);
streamStopping.Connect(obs_output_get_signal_handler(streamOutput),
"stopping", OBSStreamStopping, this);
startStreaming.Connect(obs_output_get_signal_handler(streamOutput),
"start", OBSStartStreaming, this);
stopStreaming.Connect(obs_output_get_signal_handler(streamOutput),
"stop", OBSStopStreaming, this);
LoadRecordingPreset();
if (!ffmpegOutput) {
@ -650,15 +634,63 @@ inline void SimpleOutput::SetupOutputs()
}
}
const char *FindAudioEncoderFromCodec(const char *type)
{
const char *alt_enc_id = nullptr;
size_t i = 0;
while (obs_enum_encoder_types(i++, &alt_enc_id)) {
const char *codec = obs_get_encoder_codec(alt_enc_id);
if (strcmp(type, codec) == 0) {
return alt_enc_id;
}
}
return nullptr;
}
bool SimpleOutput::StartStreaming(obs_service_t *service)
{
if (!Active())
SetupOutputs();
/* --------------------- */
const char *type = obs_service_get_output_type(service);
if (!type)
type = "rtmp_output";
/* XXX: this is messy and disgusting and should be refactored */
if (outputType != type) {
streamOutput = obs_output_create(type, "simple_stream",
nullptr, nullptr);
if (!streamOutput)
return false;
obs_output_release(streamOutput);
streamDelayStarting.Connect(
obs_output_get_signal_handler(streamOutput),
"starting", OBSStreamStarting, this);
streamStopping.Connect(
obs_output_get_signal_handler(streamOutput),
"stopping", OBSStreamStopping, this);
startStreaming.Connect(
obs_output_get_signal_handler(streamOutput),
"start", OBSStartStreaming, this);
stopStreaming.Connect(
obs_output_get_signal_handler(streamOutput),
"stop", OBSStopStreaming, this);
outputType = type;
}
obs_output_set_video_encoder(streamOutput, h264Streaming);
obs_output_set_audio_encoder(streamOutput, aacStreaming, 0);
obs_output_set_service(streamOutput, service);
/* --------------------- */
bool reconnect = config_get_bool(main->Config(), "Output",
"Reconnect");
int retryDelay = config_get_uint(main->Config(), "Output",
@ -986,12 +1018,6 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
OBSData streamEncSettings = GetDataFromJsonFile("streamEncoder.json");
OBSData recordEncSettings = GetDataFromJsonFile("recordEncoder.json");
streamOutput = obs_output_create("rtmp_output", "adv_stream",
nullptr, nullptr);
if (!streamOutput)
throw "Failed to create stream output (advanced output)";
obs_output_release(streamOutput);
if (ffmpegOutput) {
fileOutput = obs_output_create("ffmpeg_output",
"adv_ffmpeg_output", nullptr, nullptr);
@ -1035,16 +1061,6 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
"(advanced output)";
}
streamDelayStarting.Connect(obs_output_get_signal_handler(streamOutput),
"starting", OBSStreamStarting, this);
streamStopping.Connect(obs_output_get_signal_handler(streamOutput),
"stopping", OBSStreamStopping, this);
startStreaming.Connect(obs_output_get_signal_handler(streamOutput),
"start", OBSStartStreaming, this);
stopStreaming.Connect(obs_output_get_signal_handler(streamOutput),
"stop", OBSStopStreaming, this);
startRecording.Connect(obs_output_get_signal_handler(fileOutput),
"start", OBSStartRecording, this);
stopRecording.Connect(obs_output_get_signal_handler(fileOutput),
@ -1094,12 +1110,6 @@ inline void AdvancedOutput::SetupStreaming()
"Rescale");
const char *rescaleRes = config_get_string(main->Config(), "AdvOut",
"RescaleRes");
bool multitrack = config_get_bool(main->Config(), "AdvOut",
"Multitrack");
int trackIndex = config_get_int(main->Config(), "AdvOut",
"TrackIndex");
int trackCount = config_get_int(main->Config(), "AdvOut",
"TrackCount");
unsigned int cx = 0;
unsigned int cy = 0;
@ -1112,21 +1122,6 @@ inline void AdvancedOutput::SetupStreaming()
obs_encoder_set_scaled_size(h264Streaming, cx, cy);
obs_encoder_set_video(h264Streaming, obs_get_video());
obs_output_set_video_encoder(streamOutput, h264Streaming);
if (multitrack) {
int i = 0;
for (; i < trackCount; i++)
obs_output_set_audio_encoder(streamOutput, aacTrack[i],
i);
for (; i < MAX_AUDIO_MIXES; i++)
obs_output_set_audio_encoder(streamOutput, nullptr, i);
} else {
obs_output_set_audio_encoder(streamOutput,
aacTrack[trackIndex - 1], 0);
}
}
inline void AdvancedOutput::SetupRecording()
@ -1320,6 +1315,45 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
if (!Active())
SetupOutputs();
/* --------------------- */
int trackIndex = config_get_int(main->Config(), "AdvOut",
"TrackIndex");
const char *type = obs_service_get_output_type(service);
if (!type)
type = "rtmp_output";
/* XXX: this is messy and disgusting and should be refactored */
if (outputType != type) {
streamOutput = obs_output_create(type, "adv_stream",
nullptr, nullptr);
if (!streamOutput)
return false;
obs_output_release(streamOutput);
streamDelayStarting.Connect(
obs_output_get_signal_handler(streamOutput),
"starting", OBSStreamStarting, this);
streamStopping.Connect(
obs_output_get_signal_handler(streamOutput),
"stopping", OBSStreamStopping, this);
startStreaming.Connect(
obs_output_get_signal_handler(streamOutput),
"start", OBSStartStreaming, this);
stopStreaming.Connect(
obs_output_get_signal_handler(streamOutput),
"stop", OBSStopStreaming, this);
outputType = type;
}
obs_output_set_video_encoder(streamOutput, h264Streaming);
obs_output_set_audio_encoder(streamOutput, aacTrack[trackIndex - 1], 0);
/* --------------------- */
obs_output_set_service(streamOutput, service);
bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect");

View File

@ -1,5 +1,7 @@
#pragma once
#include <string>
class OBSBasic;
struct BasicOutputHandler {
@ -12,6 +14,8 @@ struct BasicOutputHandler {
bool replayBufferActive = false;
OBSBasic *main;
std::string outputType;
OBSSignal startRecording;
OBSSignal stopRecording;
OBSSignal startReplayBuffer;