diff --git a/src/core/imgui_overlays.cpp b/src/core/imgui_overlays.cpp index b0dedd3a7..25cfb43e5 100644 --- a/src/core/imgui_overlays.cpp +++ b/src/core/imgui_overlays.cpp @@ -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) diff --git a/src/core/settings.cpp b/src/core/settings.cpp index bdf684bc2..dc34e6c06 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -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)); diff --git a/src/core/settings.h b/src/core/settings.h index 98dd2b047..3382085e5 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -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. diff --git a/src/core/spu.cpp b/src/core/spu.cpp index 68dfda092..1d93e6665 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -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; diff --git a/src/core/system.cpp b/src/core/system.cpp index ab324f6b3..8df4b9dbf 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -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( diff --git a/src/core/system.h b/src/core/system.h index 93d216e2f..54df35549 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -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(); diff --git a/src/duckstation-qt/graphicssettingswidget.cpp b/src/duckstation-qt/graphicssettingswidget.cpp index 6a82e058b..f3c585191 100644 --- a/src/duckstation-qt/graphicssettingswidget.cpp +++ b/src/duckstation-qt/graphicssettingswidget.cpp @@ -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::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onMediaCaptureContainerChanged); } diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 2c3c0442d..207192760 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -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); }); }