System: Look up media capture settings on-demand

No need to store them, save some memory.
This commit is contained in:
Stenzek 2024-08-18 14:12:42 +10:00
parent e2ea0bfec2
commit 3772706603
No known key found for this signature in database
8 changed files with 81 additions and 78 deletions

View File

@ -369,12 +369,14 @@ void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, float
DRAW_LINE(fixed_font, text, IM_COL32(255, 255, 255, 255));
}
#ifndef __ANDROID__
if (MediaCapture* cap = System::GetMediaCapture())
{
text.assign("CAP: ");
FormatProcessorStat(text, cap->GetCaptureThreadUsage(), cap->GetCaptureThreadTime());
DRAW_LINE(fixed_font, text, IM_COL32(255, 255, 255, 255));
}
#endif
}
if (g_settings.display_show_gpu_usage && g_gpu_device->IsGPUTimingEnabled())
@ -499,6 +501,7 @@ void ImGuiManager::DrawEnhancementsOverlay()
void ImGuiManager::DrawMediaCaptureOverlay(float& position_y, float scale, float margin, float spacing)
{
#ifndef __ANDROID__
MediaCapture* const cap = System::GetMediaCapture();
if (!cap || FullscreenUI::HasActiveWindow())
return;
@ -533,6 +536,7 @@ void ImGuiManager::DrawMediaCaptureOverlay(float& position_y, float scale, float
IM_COL32(255, 255, 255, 255), text_msg.c_str(), text_msg.end_ptr());
position_y += box_size.y + spacing;
#endif
}
void ImGuiManager::DrawFrameTimeOverlay(float& position_y, float scale, float margin, float spacing)

View File

@ -412,27 +412,6 @@ void Settings::Load(SettingsInterface& si)
achievements_leaderboard_duration =
si.GetIntValue("Cheevos", "LeaderboardsDuration", DEFAULT_LEADERBOARD_NOTIFICATION_TIME);
#ifndef __ANDROID__
media_capture_backend =
MediaCapture::ParseBackendName(
si.GetStringValue("MediaCapture", "Backend", MediaCapture::GetBackendName(DEFAULT_MEDIA_CAPTURE_BACKEND)).c_str())
.value_or(DEFAULT_MEDIA_CAPTURE_BACKEND);
media_capture_container = si.GetStringValue("MediaCapture", "Container", "mp4");
media_capture_video = si.GetBoolValue("MediaCapture", "VideoCapture", true);
media_capture_video_width = si.GetUIntValue("MediaCapture", "VideoWidth", 640);
media_capture_video_height = si.GetUIntValue("MediaCapture", "VideoHeight", 480);
media_capture_video_auto_size = si.GetBoolValue("MediaCapture", "VideoAutoSize", false);
media_capture_video_bitrate = si.GetUIntValue("MediaCapture", "VideoBitrate", 6000);
media_capture_video_codec = si.GetStringValue("MediaCapture", "VideoCodec");
media_capture_video_codec_use_args = si.GetBoolValue("MediaCapture", "VideoCodecUseArgs", false);
media_capture_video_codec_args = si.GetStringValue("MediaCapture", "AudioCodecArgs");
media_capture_audio = si.GetBoolValue("MediaCapture", "AudioCapture", true);
media_capture_audio_bitrate = si.GetUIntValue("MediaCapture", "AudioBitrate", 128);
media_capture_audio_codec = si.GetStringValue("MediaCapture", "AudioCodec");
media_capture_audio_codec_use_args = si.GetBoolValue("MediaCapture", "AudioCodecUseArgs", false);
media_capture_audio_codec_args = si.GetStringValue("MediaCapture", "AudioCodecArgs");
#endif
log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str())
.value_or(DEFAULT_LOG_LEVEL);
log_filter = si.GetStringValue("Logging", "LogFilter", "");
@ -685,24 +664,6 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
si.SetIntValue("Cheevos", "NotificationsDuration", achievements_notification_duration);
si.SetIntValue("Cheevos", "LeaderboardsDuration", achievements_leaderboard_duration);
#ifndef __ANDROID__
si.SetStringValue("MediaCapture", "Backend", MediaCapture::GetBackendName(media_capture_backend));
si.SetStringValue("MediaCapture", "Container", media_capture_container.c_str());
si.SetBoolValue("MediaCapture", "VideoCapture", media_capture_video);
si.SetUIntValue("MediaCapture", "VideoWidth", media_capture_video_width);
si.SetUIntValue("MediaCapture", "VideoHeight", media_capture_video_height);
si.SetBoolValue("MediaCapture", "VideoAutoSize", media_capture_video_auto_size);
si.SetUIntValue("MediaCapture", "VideoBitrate", media_capture_video_bitrate);
si.SetStringValue("MediaCapture", "VideoCodec", media_capture_video_codec.c_str());
si.SetBoolValue("MediaCapture", "VideoCodecUseArgs", media_capture_video_codec_use_args);
si.SetStringValue("MediaCapture", "AudioCodecArgs", media_capture_video_codec_args.c_str());
si.SetBoolValue("MediaCapture", "AudioCapture", media_capture_audio);
si.SetUIntValue("MediaCapture", "AudioBitrate", media_capture_audio_bitrate);
si.SetStringValue("MediaCapture", "AudioCodec", media_capture_audio_codec.c_str());
si.SetBoolValue("MediaCapture", "AudioCodecUseArgs", media_capture_audio_codec_use_args);
si.SetStringValue("MediaCapture", "AudioCodecArgs", media_capture_audio_codec_args.c_str());
#endif
if (!ignore_base)
{
si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level));

View File

@ -224,25 +224,6 @@ struct Settings
s32 achievements_notification_duration = DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME;
s32 achievements_leaderboard_duration = DEFAULT_LEADERBOARD_NOTIFICATION_TIME;
#ifndef __ANDROID__
// media capture
std::string media_capture_container;
std::string media_capture_audio_codec;
std::string media_capture_audio_codec_args;
std::string media_capture_video_codec;
std::string media_capture_video_codec_args;
u32 media_capture_video_width = 640;
u32 media_capture_video_height = 480;
u32 media_capture_video_bitrate = 6000;
u32 media_capture_audio_bitrate = 128;
MediaCaptureBackend media_capture_backend = DEFAULT_MEDIA_CAPTURE_BACKEND;
bool media_capture_video : 1 = true;
bool media_capture_video_codec_use_args : 1 = true;
bool media_capture_video_auto_size : 1 = false;
bool media_capture_audio : 1 = true;
bool media_capture_audio_codec_use_args : 1 = true;
#endif
struct DebugSettings
{
bool show_vram : 1 = false;
@ -540,6 +521,10 @@ struct Settings
#ifndef __ANDROID__
static const MediaCaptureBackend DEFAULT_MEDIA_CAPTURE_BACKEND;
static constexpr const char* DEFAULT_MEDIA_CAPTURE_CONTAINER = "mp4";
static constexpr u32 DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH = 640;
static constexpr u32 DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT = 480;
static constexpr u32 DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE = 6000;
static constexpr u32 DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE = 128;
#endif
// Enable console logging by default on Linux platforms.

View File

@ -2433,11 +2433,13 @@ void SPU::Execute(void* param, TickCount ticks, TickCount ticks_late)
}
}
#ifndef __ANDROID__
if (MediaCapture* cap = System::GetMediaCapture()) [[unlikely]]
{
if (!cap->DeliverAudioFrames(output_frame_start, frames_in_this_batch))
System::StopMediaCapture();
}
#endif
output_stream->EndWrite(frames_in_this_batch);
remaining_frames -= frames_in_this_batch;

View File

@ -1278,6 +1278,24 @@ void System::SetDefaultSettings(SettingsInterface& si)
temp.controller_types[i] = g_settings.controller_types[i];
temp.Save(si, false);
#ifndef __ANDROID__
si.SetStringValue("MediaCapture", "Backend", MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND));
si.SetStringValue("MediaCapture", "Container", Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER);
si.SetBoolValue("MediaCapture", "VideoCapture", true);
si.SetUIntValue("MediaCapture", "VideoWidth", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
si.SetUIntValue("MediaCapture", "VideoHeight", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT);
si.SetBoolValue("MediaCapture", "VideoAutoSize", false);
si.SetUIntValue("MediaCapture", "VideoBitrate", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE);
si.SetStringValue("MediaCapture", "VideoCodec", "");
si.SetBoolValue("MediaCapture", "VideoCodecUseArgs", false);
si.SetStringValue("MediaCapture", "AudioCodecArgs", "");
si.SetBoolValue("MediaCapture", "AudioCapture", true);
si.SetUIntValue("MediaCapture", "AudioBitrate", Settings::DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE);
si.SetStringValue("MediaCapture", "AudioCodec", "");
si.SetBoolValue("MediaCapture", "AudioCodecUseArgs", false);
si.SetStringValue("MediaCapture", "AudioCodecArgs", "");
#endif
}
void System::ApplySettings(bool display_osd_messages)
@ -5012,6 +5030,13 @@ std::string System::GetNewMediaCapturePath(const std::string_view title, const s
return path;
}
bool System::StartMediaCapture(std::string path)
{
const bool capture_video = Host::GetBoolSettingValue("MediaCapture", "VideoCapture", true);
const bool capture_audio = Host::GetBoolSettingValue("MediaCapture", "AudioCapture", true);
return StartMediaCapture(std::move(path), capture_video, capture_audio);
}
bool System::StartMediaCapture(std::string path, bool capture_video, bool capture_audio)
{
if (!IsValid())
@ -5021,15 +5046,17 @@ bool System::StartMediaCapture(std::string path, bool capture_video, bool captur
StopMediaCapture();
// Need to work out the size.
u32 capture_width = g_settings.media_capture_video_width;
u32 capture_height = g_settings.media_capture_video_height;
u32 capture_width =
Host::GetUIntSettingValue("MediaCapture", "VideoWidth", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
u32 capture_height =
Host::GetUIntSettingValue("MediaCapture", "VideoHeight", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT);
const GPUTexture::Format capture_format =
g_gpu_device->HasSurface() ? g_gpu_device->GetWindowFormat() : GPUTexture::Format::RGBA8;
const float fps = System::GetThrottleFrequency();
if (capture_video)
{
// TODO: This will be a mess with GPU thread.
if (g_settings.media_capture_video_auto_size)
if (Host::GetBoolSettingValue("MediaCapture", "VideoAutoSize", false))
{
GSVector4i unused_display_rect, unused_draw_rect;
g_gpu->CalculateScreenshotSize(DisplayScreenshotMode::InternalResolution, &capture_width, &capture_height,
@ -5043,19 +5070,34 @@ bool System::StartMediaCapture(std::string path, bool capture_video, bool captur
constexpr float aspect = 1.0f;
if (path.empty())
path = GetNewMediaCapturePath(GetGameTitle(), g_settings.media_capture_container);
{
path =
GetNewMediaCapturePath(GetGameTitle(), Host::GetStringSettingValue("MediaCapture", "Container",
Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER));
}
const MediaCaptureBackend backend =
MediaCapture::ParseBackendName(
Host::GetStringSettingValue("MediaCapture", "Backend",
MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND))
.c_str())
.value_or(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND);
Error error;
s_media_capture = MediaCapture::Create(g_settings.media_capture_backend, &error);
s_media_capture = MediaCapture::Create(backend, &error);
if (!s_media_capture ||
!s_media_capture->BeginCapture(
fps, aspect, capture_width, capture_height, capture_format, SPU::SAMPLE_RATE, std::move(path), capture_video,
g_settings.media_capture_video_codec, g_settings.media_capture_video_bitrate,
g_settings.media_capture_video_codec_use_args ? std::string_view(g_settings.media_capture_video_codec_args) :
std::string_view(),
capture_audio, g_settings.media_capture_audio_codec, g_settings.media_capture_audio_bitrate,
g_settings.media_capture_audio_codec_use_args ? std::string_view(g_settings.media_capture_audio_codec_args) :
std::string_view(),
Host::GetSmallStringSettingValue("MediaCapture", "VideoCodec"),
Host::GetUIntSettingValue("MediaCapture", "VideoBitrate", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE),
Host::GetBoolSettingValue("MediaCapture", "VideoCodecUseArgs", false) ?
Host::GetStringSettingValue("MediaCapture", "AudioCodecArgs") :
std::string(),
capture_audio, Host::GetSmallStringSettingValue("MediaCapture", "AudioCodec"),
Host::GetUIntSettingValue("MediaCapture", "AudioBitrate", Settings::DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE),
Host::GetBoolSettingValue("MediaCapture", "AudioCodecUseArgs", false) ?
Host::GetStringSettingValue("MediaCapture", "AudioCodecArgs") :
std::string(),
&error))
{
Host::AddIconOSDMessage(

View File

@ -389,6 +389,8 @@ bool SaveScreenshot(const char* filename = nullptr, DisplayScreenshotMode mode =
DisplayScreenshotFormat format = g_settings.display_screenshot_format,
u8 quality = g_settings.display_screenshot_quality, bool compress_on_thread = true);
#ifndef __ANDROID__
/// Returns the path that a new media capture would be saved to by default. Safe to call from any thread.
std::string GetNewMediaCapturePath(const std::string_view title, const std::string_view container);
@ -396,10 +398,12 @@ std::string GetNewMediaCapturePath(const std::string_view title, const std::stri
MediaCapture* GetMediaCapture();
/// Media capture (video and/or audio). If no path is provided, one will be generated automatically.
bool StartMediaCapture(std::string path = {}, bool capture_video = g_settings.media_capture_video,
bool capture_audio = g_settings.media_capture_audio);
bool StartMediaCapture(std::string path = {});
bool StartMediaCapture(std::string path, bool capture_video, bool capture_audio);
void StopMediaCapture();
#endif
/// Loads the cheat list for the current game title from the user directory.
bool LoadCheatList();

View File

@ -208,16 +208,20 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
&MediaCapture::ParseBackendName, &MediaCapture::GetBackendName,
Settings::DEFAULT_MEDIA_CAPTURE_BACKEND);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCapture, "MediaCapture", "VideoCapture", true);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureWidth, "MediaCapture", "VideoWidth", 640);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureHeight, "MediaCapture", "VideoHeight", 480);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureWidth, "MediaCapture", "VideoWidth",
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureHeight, "MediaCapture", "VideoHeight",
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.videoCaptureResolutionAuto, "MediaCapture", "VideoAutoSize",
false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureBitrate, "MediaCapture", "VideoBitrate", 6000);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureBitrate, "MediaCapture", "VideoBitrate",
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture",
"VideoCodecUseArgs", false);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureArguments, "MediaCapture", "AudioCodecArgs");
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableAudioCapture, "MediaCapture", "AudioCapture", true);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.audioCaptureBitrate, "MediaCapture", "AudioBitrate", 128);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.audioCaptureBitrate, "MediaCapture", "AudioBitrate",
Settings::DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture",
"VideoCodecUseArgs", false);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.audioCaptureArguments, "MediaCapture", "AudioCodecArgs");
@ -1024,7 +1028,8 @@ void GraphicsSettingsWidget::onMediaCaptureBackendChanged()
m_ui.captureContainer->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname);
}
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.captureContainer, "MediaCapture", "Container", "mp4");
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.captureContainer, "MediaCapture", "Container",
Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER);
connect(m_ui.captureContainer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onMediaCaptureContainerChanged);
}

View File

@ -2806,7 +2806,7 @@ void MainWindow::onToolsMediaCaptureToggled(bool checked)
QString path =
QString::fromStdString(System::GetNewMediaCapturePath(QtHost::GetCurrentGameTitle().toStdString(), container));
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter));
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Media Capture"), path, filter));
if (path.isEmpty())
{
// uncheck it again
@ -2816,7 +2816,7 @@ void MainWindow::onToolsMediaCaptureToggled(bool checked)
}
Host::RunOnCPUThread([path = path.toStdString()]() {
System::StartMediaCapture(path, g_settings.media_capture_video, g_settings.media_capture_audio);
System::StartMediaCapture(path);
});
}