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
129 changes: 128 additions & 1 deletion app/gui/SettingsView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,133 @@ Flickable {
ToolTip.visible: hovered
ToolTip.text: qsTr("Prevents the screensaver from starting or the display from going to sleep while streaming.")
}

Label {
anchors.left: parent.left
anchors.leftMargin: 10
text: qsTr("Overlays")
font.pointSize: 12
id: uiOverlayLabel
}
Label {
anchors.left: parent.left
anchors.leftMargin: 20
text: qsTr("Text")
font.pointSize: 12
id: uiOverlayTextColor
}

AutoResizingComboBox {
id: uiOverlayTextColorValue
textRole: "text"
anchors.left: parent.left
anchors.leftMargin: 20
model: ListModel {
id: uiOverlayTextColorValueModel
ListElement {
text: qsTr("White")
val: 0
}
ListElement {
text: qsTr("Black")
val: 1
}
ListElement {
text: qsTr("Yellow")
val: 2
}
}
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
StreamingPreferences.uiOverlayTextColor = uiOverlayTextColorValueModel.get(currentIndex).val
}

Component.onCompleted: {
var saved_color = StreamingPreferences.uiOverlayTextColor
currentIndex = 0
for (var i = 0; i < uiOverlayTextColorValueModel.count; i++) {
var el_val = uiOverlayTextColorValueModel.get(i).val;
if (saved_color === el_val) {
currentIndex = i
break
}
}

activated(currentIndex)
}
}

Label {
anchors.left: parent.left
anchors.leftMargin: 20
text: qsTr("Background")
font.pointSize: 12
id: uiOverlayBackgroundColor
}

AutoResizingComboBox {
id: uiOverlayBackgroundColorValue
textRole: "text"
anchors.left: parent.left
anchors.leftMargin: 20
model: ListModel {
id: uiOverlayBackgroundColorValueModel
ListElement {
text: qsTr("Black")
val: 0
}
ListElement {
text: qsTr("White")
val: 1
}
}
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
StreamingPreferences.uiOverlayBackgroundColor = uiOverlayBackgroundColorValueModel.get(currentIndex).val
}

Component.onCompleted: {
var saved_color = StreamingPreferences.uiOverlayBackgroundColor
currentIndex = 0
for (var i = 0; i < uiOverlayBackgroundColorValueModel.count; i++) {
var el_val = uiOverlayBackgroundColorValueModel.get(i).val;
if (saved_color === el_val) {
currentIndex = i
break
}
}

activated(currentIndex)
}
}

Label {
anchors.left: parent.left
anchors.leftMargin: 20
text: qsTr("Opacity: %1\%").arg(StreamingPreferences.uiOverlayOpacityPerc)
font.pointSize: 12
id: uiOverlayOpacityValue
}

Slider {
id: overlayOpacitySlider
anchors.left: parent.left
anchors.leftMargin: 20
value: StreamingPreferences.uiOverlayOpacityPerc
width: parent.width - 20

stepSize: 5
from : 0
to: 100

snapMode: "SnapOnRelease"

onValueChanged: {
uiOverlayOpacityValue.text = qsTr("Overlay Background Opacity: %1\%").arg(value)
StreamingPreferences.uiOverlayOpacityPerc = value
}

}
}
}
}
Expand Down Expand Up @@ -1738,7 +1865,7 @@ Flickable {
ToolTip.visible: hovered
ToolTip.text: qsTr("Display real-time stream performance information while streaming.") + "\n\n" +
qsTr("You can toggle it at any time while streaming using Ctrl+Alt+Shift+S or Select+L1+R1+X.") + "\n\n" +
qsTr("The performance overlay is not supported on Steam Link or Raspberry Pi.")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this as the stats overlay seems to be working fine on my Pi5 Bookworm

qsTr("The performance overlay is not supported on Steam Link.")
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions app/settings/streamingpreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
#define SER_SWAPFACEBUTTONS "swapfacebuttons"
#define SER_CAPTURESYSKEYS "capturesyskeys"
#define SER_KEEPAWAKE "keepawake"
#define SER_UIOVERLAYOPACITY "uiOverlayOpacityPerc"
#define SER_UIOVERLAYTEXTCOLOR "uiOverlayTextColor"
#define SER_UIOVERLAYBACKGROUNDCOLOR "uiOverlayBackgroundColor"
#define SER_LANGUAGE "language"

#define CURRENT_DEFAULT_VER 2
Expand Down Expand Up @@ -145,7 +148,13 @@ void StreamingPreferences::reload()
reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool();
swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool();
keepAwake = settings.value(SER_KEEPAWAKE, true).toBool();
uiOverlayOpacityPerc = settings.value(SER_UIOVERLAYOPACITY, 50).toInt();
enableHdr = settings.value(SER_HDR, false).toBool();

uiOverlayTextColor = static_cast<UIOverlayTextColor>(settings.value(SER_UIOVERLAYTEXTCOLOR,
static_cast<int>(UIOverlayTextColor::UIOT_WHITE)).toInt());
uiOverlayBackgroundColor = static_cast<UIOverlayBackgroundColor>(settings.value(SER_UIOVERLAYBACKGROUNDCOLOR,
static_cast<int>(UIOverlayBackgroundColor::UIOB_BLACK)).toInt());
captureSysKeysMode = static_cast<CaptureSysKeysMode>(settings.value(SER_CAPTURESYSKEYS,
static_cast<int>(CaptureSysKeysMode::CSK_OFF)).toInt());
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
Expand Down Expand Up @@ -352,6 +361,9 @@ void StreamingPreferences::save()
settings.setValue(SER_SWAPFACEBUTTONS, swapFaceButtons);
settings.setValue(SER_CAPTURESYSKEYS, captureSysKeysMode);
settings.setValue(SER_KEEPAWAKE, keepAwake);
settings.setValue(SER_UIOVERLAYOPACITY, uiOverlayOpacityPerc);
settings.setValue(SER_UIOVERLAYTEXTCOLOR, uiOverlayTextColor);
settings.setValue(SER_UIOVERLAYBACKGROUNDCOLOR, uiOverlayBackgroundColor);
}

int StreamingPreferences::getDefaultBitrate(int width, int height, int fps, bool yuv444)
Expand Down
22 changes: 22 additions & 0 deletions app/settings/streamingpreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ class StreamingPreferences : public QObject
LANG_TA,
};
Q_ENUM(Language);
enum UIOverlayTextColor
{
UIOT_WHITE,
UIOT_BLACK,
UIOT_YELLOW,
};
Q_ENUM(UIOverlayTextColor);
enum UIOverlayBackgroundColor
{
UIOB_BLACK,
UIOB_WHITE,
};
Q_ENUM(UIOverlayBackgroundColor);

enum CaptureSysKeysMode
{
Expand Down Expand Up @@ -142,6 +155,9 @@ class StreamingPreferences : public QObject
Q_PROPERTY(bool reverseScrollDirection MEMBER reverseScrollDirection NOTIFY reverseScrollDirectionChanged)
Q_PROPERTY(bool swapFaceButtons MEMBER swapFaceButtons NOTIFY swapFaceButtonsChanged)
Q_PROPERTY(bool keepAwake MEMBER keepAwake NOTIFY keepAwakeChanged)
Q_PROPERTY(int uiOverlayOpacityPerc MEMBER uiOverlayOpacityPerc NOTIFY uiOverlayOpacityChanged)
Q_PROPERTY(UIOverlayTextColor uiOverlayTextColor MEMBER uiOverlayTextColor NOTIFY uiOverlayTextColorChanged)
Q_PROPERTY(UIOverlayBackgroundColor uiOverlayBackgroundColor MEMBER uiOverlayBackgroundColor NOTIFY uiOverlayBackgroundColorChanged)
Q_PROPERTY(CaptureSysKeysMode captureSysKeysMode MEMBER captureSysKeysMode NOTIFY captureSysKeysModeChanged)
Q_PROPERTY(Language language MEMBER language NOTIFY languageChanged);

Expand Down Expand Up @@ -174,6 +190,9 @@ class StreamingPreferences : public QObject
bool reverseScrollDirection;
bool swapFaceButtons;
bool keepAwake;
int uiOverlayOpacityPerc;
UIOverlayTextColor uiOverlayTextColor;
UIOverlayBackgroundColor uiOverlayBackgroundColor;
int packetSize;
AudioConfig audioConfig;
VideoCodecConfig videoCodecConfig;
Expand Down Expand Up @@ -220,6 +239,9 @@ class StreamingPreferences : public QObject
void swapFaceButtonsChanged();
void captureSysKeysModeChanged();
void keepAwakeChanged();
void uiOverlayOpacityChanged();
void uiOverlayTextColorChanged();
void uiOverlayBackgroundColorChanged();
void languageChanged();

private:
Expand Down
38 changes: 38 additions & 0 deletions app/streaming/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,44 @@ void Session::execInternal()
// Toggle the stats overlay if requested by the user
m_OverlayManager.setOverlayState(Overlay::OverlayDebug, m_Preferences->showPerformanceOverlay);

Uint8 alpha = (255 * ((float)m_Preferences->uiOverlayOpacityPerc / 100));
switch (m_Preferences->uiOverlayBackgroundColor) {
case StreamingPreferences::UIOverlayBackgroundColor::UIOB_BLACK:
m_OverlayManager.setOverlayBackgroundRGBA(0, 0, 0, alpha);
break;
case StreamingPreferences::UIOverlayBackgroundColor::UIOB_WHITE:
m_OverlayManager.setOverlayBackgroundRGBA(255, 255, 255, alpha);
break;
default:
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unknown overlay background color: %d",
m_Preferences->uiOverlayBackgroundColor);
// Default to black
m_OverlayManager.setOverlayBackgroundRGBA(0, 0, 0, alpha);
break;
}


switch (m_Preferences->uiOverlayTextColor) {
case StreamingPreferences::UIOverlayTextColor::UIOT_WHITE:
m_OverlayManager.setOverlayTextColorRGBA(255, 255, 255, 255);
break;
case StreamingPreferences::UIOverlayTextColor::UIOT_BLACK:
m_OverlayManager.setOverlayTextColorRGBA(0, 0, 0, 255);
break;
case StreamingPreferences::UIOverlayTextColor::UIOT_YELLOW:
m_OverlayManager.setOverlayTextColorRGBA(255, 255, 50, 255);
break;
default:
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unknown overlay text color: %d",
m_Preferences->uiOverlayTextColor);
// Default to white
m_OverlayManager.setOverlayTextColorRGBA(255, 255, 255, 255);
break;
}


// Hijack this thread to be the SDL main thread. We have to do this
// because we want to suspend all Qt processing until the stream is over.
SDL_Event event;
Expand Down
2 changes: 1 addition & 1 deletion app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ void updateOverlayOnMainThread(Overlay::OverlayType type)
break;
}

SDL_Color color = Session::get()->getOverlayManager().getOverlayColor(type);
SDL_Color color = Session::get()->getOverlayManager().getOverlayTextColor();
[m_OverlayTextFields[type] setTextColor:[NSColor colorWithSRGBRed:color.r / 255.0 green:color.g / 255.0 blue:color.b / 255.0 alpha:color.a / 255.0]];
[m_OverlayTextFields[type] setFont:[NSFont messageFontOfSize:Session::get()->getOverlayManager().getOverlayFontSize(type)]];

Expand Down
57 changes: 45 additions & 12 deletions app/streaming/video/overlaymanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ OverlayManager::OverlayManager() :
m_FontData(Path::readDataFile("ModeSeven.ttf"))
{
memset(m_Overlays, 0, sizeof(m_Overlays));

m_Overlays[OverlayType::OverlayDebug].color = {0xD0, 0xD0, 0x00, 0xFF};
m_Overlays[OverlayType::OverlayDebug].fontSize = 20;

m_Overlays[OverlayType::OverlayStatusUpdate].color = {0xCC, 0x00, 0x00, 0xFF};
m_Overlays[OverlayType::OverlayStatusUpdate].fontSize = 36;

// While TTF will usually not be initialized here, it is valid for that not to
Expand Down Expand Up @@ -92,6 +88,26 @@ void OverlayManager::setOverlayTextUpdated(OverlayType type)
}
}

SDL_Color OverlayManager::getOverlayTextColor()
{
return m_overlayTextColor;
}

void OverlayManager::setOverlayBackgroundRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
m_overlayBackgroundColor.r = r;
m_overlayBackgroundColor.g = g;
m_overlayBackgroundColor.b = b;
m_overlayBackgroundColor.a = a;
}
void OverlayManager::setOverlayTextColorRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
m_overlayTextColor.r = r;
m_overlayTextColor.g = g;
m_overlayTextColor.b = b;
m_overlayTextColor.a = a;
}

void OverlayManager::setOverlayState(OverlayType type, bool enabled)
{
bool stateChanged = m_Overlays[type].enabled != enabled;
Expand All @@ -108,11 +124,6 @@ void OverlayManager::setOverlayState(OverlayType type, bool enabled)
}
}

SDL_Color OverlayManager::getOverlayColor(OverlayType type)
{
return m_Overlays[type].color;
}

void OverlayManager::setOverlayRenderer(IOverlayRenderer* renderer)
{
m_Renderer = renderer;
Expand Down Expand Up @@ -155,11 +166,33 @@ void OverlayManager::notifyOverlayUpdated(OverlayType type)

if (m_Overlays[type].enabled) {
// The _Wrapped variant is required for line breaks to work
SDL_Surface* surface = TTF_RenderText_Blended_Wrapped(m_Overlays[type].font,
SDL_Surface* textSurface = TTF_RenderText_Blended_Wrapped(m_Overlays[type].font,
m_Overlays[type].text,
m_Overlays[type].color,
m_overlayTextColor,
1024);
SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, surface);
if (textSurface != nullptr) { // it worked
// create new surface with a background and blit them together
SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0,
textSurface->w,
textSurface->h,
32,
textSurface->format->format);

SDL_FillRect(surface, nullptr, SDL_MapRGBA(surface->format,
m_overlayBackgroundColor.r,
m_overlayBackgroundColor.g,
m_overlayBackgroundColor.b,
m_overlayBackgroundColor.a));

SDL_SetSurfaceBlendMode(textSurface, SDL_BLENDMODE_BLEND);
SDL_BlitSurface(textSurface, nullptr, surface, nullptr);
SDL_FreeSurface(textSurface);
SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, surface);

} else {
SDL_AtomicSetPtr((void**)&m_Overlays[type].surface, textSurface);
}

}

// Notify the renderer
Expand Down
7 changes: 5 additions & 2 deletions app/streaming/video/overlaymanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,27 @@ class OverlayManager
int getOverlayMaxTextLength();
void setOverlayTextUpdated(OverlayType type);
void setOverlayState(OverlayType type, bool enabled);
SDL_Color getOverlayColor(OverlayType type);
SDL_Color getOverlayTextColor();
int getOverlayFontSize(OverlayType type);
SDL_Surface* getUpdatedOverlaySurface(OverlayType type);

void setOverlayRenderer(IOverlayRenderer* renderer);
void setOverlayBackgroundRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
void setOverlayTextColorRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a);

private:
void notifyOverlayUpdated(OverlayType type);

struct {
bool enabled;
int fontSize;
SDL_Color color;
char text[512];

TTF_Font* font;
SDL_Surface* surface;
} m_Overlays[OverlayMax];
SDL_Color m_overlayBackgroundColor = {0, 0, 0, 128}; // See through grey background
SDL_Color m_overlayTextColor = {255, 255, 255, 255}; // White text
IOverlayRenderer* m_Renderer;
QByteArray m_FontData;
};
Expand Down