diff --git a/src/audio_controller.cpp b/src/audio_controller.cpp index 011a06232..27ec41b7c 100644 --- a/src/audio_controller.cpp +++ b/src/audio_controller.cpp @@ -39,6 +39,7 @@ #include "ass_file.h" #include "audio_timing.h" #include "compat.h" +#include "dialog_progress.h" #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" #include "include/aegisub/context.h" @@ -113,7 +114,7 @@ void AudioController::OnComputerResuming(wxPowerEvent &) { try { - player = AudioPlayerFactory::GetAudioPlayer(provider.get()); + player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent); } catch (...) { @@ -133,7 +134,7 @@ void AudioController::OnAudioPlayerChanged() try { - player = AudioPlayerFactory::GetAudioPlayer(provider.get()); + player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent); } catch (...) { @@ -157,7 +158,8 @@ void AudioController::OpenAudio(agi::fs::path const& url) std::unique_ptr new_provider; try { - new_provider = AudioProviderFactory::GetProvider(url); + DialogProgress progress(context->parent); + new_provider = AudioProviderFactory::GetProvider(url, &progress); config::path->SetToken("?audio", url); } catch (agi::UserCancelException const&) { @@ -173,7 +175,7 @@ void AudioController::OpenAudio(agi::fs::path const& url) try { - player = AudioPlayerFactory::GetAudioPlayer(provider.get()); + player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent); } catch (...) { diff --git a/src/audio_player.cpp b/src/audio_player.cpp index 9c1b6aaa0..47d55bfab 100644 --- a/src/audio_player.cpp +++ b/src/audio_player.cpp @@ -47,18 +47,18 @@ AudioPlayer::AudioPlayer(AudioProvider *provider) { } -std::unique_ptr CreateAlsaPlayer(AudioProvider *providers); -std::unique_ptr CreateDirectSoundPlayer(AudioProvider *providers); -std::unique_ptr CreateDirectSound2Player(AudioProvider *providers); -std::unique_ptr CreateOpenALPlayer(AudioProvider *providers); -std::unique_ptr CreatePortAudioPlayer(AudioProvider *providers); -std::unique_ptr CreatePulseAudioPlayer(AudioProvider *providers); -std::unique_ptr CreateOSSPlayer(AudioProvider *providers); +std::unique_ptr CreateAlsaPlayer(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreateDirectSoundPlayer(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreateDirectSound2Player(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreateOpenALPlayer(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreatePortAudioPlayer(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreatePulseAudioPlayer(AudioProvider *providers, wxWindow *window); +std::unique_ptr CreateOSSPlayer(AudioProvider *providers, wxWindow *window); namespace { struct factory { const char *name; - std::unique_ptr (*create)(AudioProvider *); + std::unique_ptr (*create)(AudioProvider *, wxWindow *window); bool hidden; }; @@ -89,7 +89,7 @@ std::vector AudioPlayerFactory::GetClasses() { return ::GetClasses(boost::make_iterator_range(std::begin(factories), std::end(factories))); } -std::unique_ptr AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) { +std::unique_ptr AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider, wxWindow *window) { if (std::distance(std::begin(factories), std::end(factories)) == 0) throw agi::NoAudioPlayersError("No audio players are available.", nullptr); @@ -99,7 +99,7 @@ std::unique_ptr AudioPlayerFactory::GetAudioPlayer(AudioProvider *p std::string error; for (auto factory : sorted) { try { - return factory->create(provider); + return factory->create(provider, window); } catch (agi::AudioPlayerOpenError const& err) { error += std::string(factory->name) + " factory: " + err.GetChainedMessage() + "\n"; diff --git a/src/audio_player_alsa.cpp b/src/audio_player_alsa.cpp index 61f009f07..338fecfe6 100644 --- a/src/audio_player_alsa.cpp +++ b/src/audio_player_alsa.cpp @@ -461,7 +461,7 @@ void AlsaPlayer::SetVolume(double vol) } } -std::unique_ptr CreateAlsaPlayer(AudioProvider *provider) +std::unique_ptr CreateAlsaPlayer(AudioProvider *provider, wxWindow *) { return agi::util::make_unique(provider); } diff --git a/src/audio_player_dsound.cpp b/src/audio_player_dsound.cpp index f5844f294..77334ba93 100644 --- a/src/audio_player_dsound.cpp +++ b/src/audio_player_dsound.cpp @@ -84,7 +84,7 @@ class DirectSoundPlayer final : public AudioPlayer { DirectSoundPlayerThread *thread = nullptr; public: - DirectSoundPlayer(AudioProvider *provider); + DirectSoundPlayer(AudioProvider *provider, wxWindow *parent); ~DirectSoundPlayer(); void Play(int64_t start,int64_t count); @@ -99,7 +99,7 @@ public: void SetVolume(double vol) { volume = vol; } }; -DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider) +DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider, wxWindow *parent) : AudioPlayer(provider) { // Initialize the DirectSound object @@ -108,7 +108,7 @@ DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider) if (FAILED(res)) throw agi::AudioPlayerOpenError("Failed initializing DirectSound", 0); // Set DirectSound parameters - directSound->SetCooperativeLevel((HWND)wxGetApp().frame->GetHandle(),DSSCL_PRIORITY); + directSound->SetCooperativeLevel((HWND)parent->GetHandle(),DSSCL_PRIORITY); // Create the wave format structure WAVEFORMATEX waveFormat; @@ -370,8 +370,8 @@ void DirectSoundPlayerThread::Stop() { } } -std::unique_ptr CreateDirectSoundPlayer(AudioProvider *provider) { - return agi::util::make_unique(provider); +std::unique_ptr CreateDirectSoundPlayer(AudioProvider *provider, wxWindow *parent) { + return agi::util::make_unique(provider, parent); } #endif // WITH_DIRECTSOUND diff --git a/src/audio_player_dsound2.cpp b/src/audio_player_dsound2.cpp index 9952b4d62..ca36e6236 100644 --- a/src/audio_player_dsound2.cpp +++ b/src/audio_player_dsound2.cpp @@ -77,7 +77,7 @@ class DirectSoundPlayer2 final : public AudioPlayer { public: /// @brief Constructor - DirectSoundPlayer2(AudioProvider *provider); + DirectSoundPlayer2(AudioProvider *provider, wxWindow *parent); /// @brief Destructor ~DirectSoundPlayer2(); @@ -144,40 +144,15 @@ struct COMInitialization { } }; -/// @class COMObjectRetainer -/// @brief Simple auto_ptr-like class for COM objects -template -struct COMObjectRetainer { - /// Managed object - T *obj; - - /// @brief Constructor for null object - COMObjectRetainer() - { - obj = 0; - } - - /// @brief Constructor to take object immediately - /// @param _obj Object to manage - COMObjectRetainer(T *_obj) - { - obj = _obj; - } - - /// @brief Destructor, releases object if there is one - ~COMObjectRetainer() - { +struct ReleaseCOMObject { + void operator()(IUnknown *obj) { if (obj) obj->Release(); } - - /// @brief Dereference the managed object - /// @return The managed object - T * operator -> () - { - return obj; - } }; +template +using COMObjectRetainer = std::unique_ptr; + /// @brief RAII wrapper around Win32 HANDLE type struct Win32KernelHandle final : public agi::scoped_holder { /// @brief Create with a managed handle @@ -219,6 +194,8 @@ class DirectSoundPlayer2Thread { /// @brief Check for error state and throw exception if one occurred void CheckError(); + HWND parent; + /// Win32 handle to the thread Win32KernelHandle thread_handle; @@ -277,7 +254,7 @@ public: /// @param provider Audio provider to take sample data from /// @param WantedLatency Desired length in milliseconds to write ahead of the playback cursor /// @param BufferLength Multiplier for WantedLatency to get total buffer length - DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength); + DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength, wxWindow *parent); /// @brief Destructor, waits for thread to have died ~DirectSoundPlayer2Thread(); @@ -340,15 +317,15 @@ void DirectSoundPlayer2Thread::Run() catch (std::exception e) REPORT_ERROR("Could not initialise COM") - // Create DirectSound object - COMObjectRetainer ds; - if (FAILED(DirectSoundCreate8(&DSDEVID_DefaultPlayback, &ds.obj, nullptr))) + IDirectSound8 *ds_raw = nullptr; + if (FAILED(DirectSoundCreate8(&DSDEVID_DefaultPlayback, &ds_raw, nullptr))) REPORT_ERROR("Cound not create DirectSound object") + COMObjectRetainer ds(ds_raw); // Ensure we can get interesting wave formats (unless we have PRIORITY we can only use a standard 8 bit format) - ds->SetCooperativeLevel((HWND)static_cast(wxApp::GetInstance())->frame->GetHandle(), DSSCL_PRIORITY); + ds->SetCooperativeLevel(parent, DSSCL_PRIORITY); // Describe the wave format WAVEFORMATEX waveFormat; @@ -379,9 +356,10 @@ void DirectSoundPlayer2Thread::Run() REPORT_ERROR("Could not create buffer") // But it's an old version interface we get, query it for the DSound8 interface - COMObjectRetainer bfr; - if (FAILED(bfr7->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&bfr.obj))) + IDirectSoundBuffer8 *bfr_raw = nullptr; + if (FAILED(bfr7->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&bfr_raw))) REPORT_ERROR("Buffer doesn't support version 8 interface") + COMObjectRetainer bfr(bfr_raw); bfr7->Release(); bfr7 = 0; @@ -447,7 +425,7 @@ void DirectSoundPlayer2Thread::Run() // Clear the buffer in case we can't fill it completely memset(buf, 0, buf_size); - DWORD bytes_filled = FillAndUnlockBuffers(buf, buf_size, 0, 0, next_input_frame, bfr.obj); + DWORD bytes_filled = FillAndUnlockBuffers(buf, buf_size, 0, 0, next_input_frame, bfr.get()); buffer_offset += bytes_filled; if (buffer_offset >= bufSize) buffer_offset -= bufSize; @@ -575,7 +553,7 @@ do_fill_buffer: break; } - DWORD bytes_filled = FillAndUnlockBuffers(buf1, buf1sz, buf2, buf2sz, next_input_frame, bfr.obj); + DWORD bytes_filled = FillAndUnlockBuffers(buf1, buf1sz, buf2, buf2sz, next_input_frame, bfr.get()); buffer_offset += bytes_filled; if (buffer_offset >= bufSize) buffer_offset -= bufSize; @@ -694,8 +672,9 @@ void DirectSoundPlayer2Thread::CheckError() } } -DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength) -: event_start_playback (CreateEvent(0, FALSE, FALSE, 0)) +DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength, wxWindow *parent) +: parent((HWND)parent->GetHandle()) +, event_start_playback (CreateEvent(0, FALSE, FALSE, 0)) , event_stop_playback (CreateEvent(0, FALSE, FALSE, 0)) , event_update_end_time (CreateEvent(0, FALSE, FALSE, 0)) , event_set_volume (CreateEvent(0, FALSE, FALSE, 0)) @@ -833,7 +812,7 @@ bool DirectSoundPlayer2Thread::IsDead() } } -DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider) +DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider, wxWindow *parent) : AudioPlayer(provider) { // The buffer will hold BufferLength times WantedLatency milliseconds of audio @@ -848,7 +827,7 @@ DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider) try { - thread = agi::util::make_unique(provider, WantedLatency, BufferLength); + thread = agi::util::make_unique(provider, WantedLatency, BufferLength, parent); } catch (const char *msg) { @@ -962,8 +941,8 @@ void DirectSoundPlayer2::SetVolume(double vol) } } -std::unique_ptr CreateDirectSound2Player(AudioProvider *provider) { - return agi::util::make_unique(provider); +std::unique_ptr CreateDirectSound2Player(AudioProvider *provider, wxWindow *parent) { + return agi::util::make_unique(provider, parent); } #endif // WITH_DIRECTSOUND diff --git a/src/audio_player_openal.cpp b/src/audio_player_openal.cpp index b44cb3cd0..253ed2289 100644 --- a/src/audio_player_openal.cpp +++ b/src/audio_player_openal.cpp @@ -286,7 +286,7 @@ int64_t OpenALPlayer::GetCurrentPosition() } } -std::unique_ptr CreateOpenALPlayer(AudioProvider *provider) +std::unique_ptr CreateOpenALPlayer(AudioProvider *provider, wxWindow *) { return agi::util::make_unique(provider); } diff --git a/src/audio_player_oss.cpp b/src/audio_player_oss.cpp index 0b7d4f156..bef741ded 100644 --- a/src/audio_player_oss.cpp +++ b/src/audio_player_oss.cpp @@ -283,7 +283,7 @@ int64_t OSSPlayer::GetCurrentPosition() } } -std::unique_ptr CreateOSSPlayer(AudioProvider *provider) { +std::unique_ptr CreateOSSPlayer(AudioProvider *provider, wxWindow *) { return agi::util::make_unique(provider); } diff --git a/src/audio_player_portaudio.cpp b/src/audio_player_portaudio.cpp index 822705fb8..ec7e88af6 100644 --- a/src/audio_player_portaudio.cpp +++ b/src/audio_player_portaudio.cpp @@ -283,7 +283,7 @@ bool PortAudioPlayer::IsPlaying() { return !!Pa_IsStreamActive(stream); } -std::unique_ptr CreatePortAudioPlayer(AudioProvider *provider) { +std::unique_ptr CreatePortAudioPlayer(AudioProvider *provider, wxWindow *) { return agi::util::make_unique(provider); } diff --git a/src/audio_player_pulse.cpp b/src/audio_player_pulse.cpp index 2d601e48d..15a4f262a 100644 --- a/src/audio_player_pulse.cpp +++ b/src/audio_player_pulse.cpp @@ -335,7 +335,7 @@ void PulseAudioPlayer::pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread) } } -std::unique_ptr CreatePulseAudioPlayer(AudioProvider *provider) { +std::unique_ptr CreatePulseAudioPlayer(AudioProvider *provider, wxWindow *) { return agi::util::make_unique(provider); } #endif // WITH_LIBPULSE diff --git a/src/audio_provider.cpp b/src/audio_provider.cpp index 50c717749..41e3da0b5 100644 --- a/src/audio_provider.cpp +++ b/src/audio_provider.cpp @@ -37,13 +37,13 @@ #include "include/aegisub/audio_provider.h" #include "audio_controller.h" -#include "dialog_progress.h" #include "factory_manager.h" #include "frame_main.h" #include "main.h" #include "options.h" #include "utils.h" +#include #include #include #include @@ -104,10 +104,10 @@ void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { } } -std::unique_ptr CreateDummyAudioProvider(agi::fs::path const& filename); -std::unique_ptr CreatePCMAudioProvider(agi::fs::path const& filename); -std::unique_ptr CreateAvisynthAudioProvider(agi::fs::path const& filename); -std::unique_ptr CreateFFmpegSourceAudioProvider(agi::fs::path const& filename); +std::unique_ptr CreateDummyAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *); +std::unique_ptr CreatePCMAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *); +std::unique_ptr CreateAvisynthAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *); +std::unique_ptr CreateFFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *); std::unique_ptr CreateConvertAudioProvider(std::unique_ptr source_provider); std::unique_ptr CreateLockAudioProvider(std::unique_ptr source_provider); @@ -117,7 +117,7 @@ std::unique_ptr CreateRAMAudioProvider(std::unique_ptr (*create)(agi::fs::path const&); + std::unique_ptr (*create)(agi::fs::path const&, agi::BackgroundRunner *); bool hidden; }; @@ -137,7 +137,7 @@ std::vector AudioProviderFactory::GetClasses() { return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers))); } -std::unique_ptr AudioProviderFactory::GetProvider(agi::fs::path const& filename) { +std::unique_ptr AudioProviderFactory::GetProvider(agi::fs::path const& filename, agi::BackgroundRunner *br) { auto preferred = OPT_GET("Audio/Provider")->GetString(); auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); @@ -148,7 +148,7 @@ std::unique_ptr AudioProviderFactory::GetProvider(agi::fs::path c for (auto const& factory : sorted) { try { - provider = factory->create(filename); + provider = factory->create(filename, br); if (!provider) continue; LOG_I("audio_provider") << "Using audio provider: " << factory->name; break; @@ -189,13 +189,11 @@ std::unique_ptr AudioProviderFactory::GetProvider(agi::fs::path c if (!cache || !needsCache) return CreateLockAudioProvider(std::move(provider)); - DialogProgress progress(wxGetApp().frame, _("Load audio")); - // Convert to RAM - if (cache == 1) return CreateRAMAudioProvider(std::move(provider), &progress); + if (cache == 1) return CreateRAMAudioProvider(std::move(provider), br); // Convert to HD - if (cache == 2) return CreateHDAudioProvider(std::move(provider), &progress); + if (cache == 2) return CreateHDAudioProvider(std::move(provider), br); throw agi::AudioCacheOpenError("Unknown caching method", nullptr); } diff --git a/src/audio_provider_avs.cpp b/src/audio_provider_avs.cpp index a46d6d123..06fdd6be2 100644 --- a/src/audio_provider_avs.cpp +++ b/src/audio_provider_avs.cpp @@ -147,7 +147,7 @@ void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) } } -std::unique_ptr CreateAvisynthAudioProvider(agi::fs::path const& file) { +std::unique_ptr CreateAvisynthAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) { return agi::util::make_unique(file); } #endif diff --git a/src/audio_provider_dummy.cpp b/src/audio_provider_dummy.cpp index f308ece72..a68bd7f36 100644 --- a/src/audio_provider_dummy.cpp +++ b/src/audio_provider_dummy.cpp @@ -88,7 +88,7 @@ public: }; } -std::unique_ptr CreateDummyAudioProvider(agi::fs::path const& file) { +std::unique_ptr CreateDummyAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) { if (!boost::starts_with(file.string(), "dummy-audio:")) return {}; return agi::util::make_unique(file); diff --git a/src/audio_provider_ffmpegsource.cpp b/src/audio_provider_ffmpegsource.cpp index 1cf95f93c..85077897d 100644 --- a/src/audio_provider_ffmpegsource.cpp +++ b/src/audio_provider_ffmpegsource.cpp @@ -61,15 +61,16 @@ class FFmpegSourceAudioProvider final : public AudioProvider, FFmpegSourceProvid } public: - FFmpegSourceAudioProvider(agi::fs::path const& filename); + FFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *br); bool NeedsCache() const override { return true; } }; /// @brief Constructor /// @param filename The filename to open -FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename) try -: AudioSource(nullptr, FFMS_DestroyAudioSource) +FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *br) try +: FFmpegSourceProvider(br) +, AudioSource(nullptr, FFMS_DestroyAudioSource) { ErrInfo.Buffer = FFMSErrMsg; ErrInfo.BufferSize = sizeof(FFMSErrMsg); @@ -206,8 +207,8 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) { } -std::unique_ptr CreateFFmpegSourceAudioProvider(agi::fs::path const& file) { - return agi::util::make_unique(file); +std::unique_ptr CreateFFmpegSourceAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *br) { + return agi::util::make_unique(file, br); } #endif /* WITH_FFMS2 */ diff --git a/src/audio_provider_hd.cpp b/src/audio_provider_hd.cpp index 4c7f31e25..defea3b1d 100644 --- a/src/audio_provider_hd.cpp +++ b/src/audio_provider_hd.cpp @@ -66,6 +66,7 @@ public: file = agi::util::make_unique(cache_dir / filename, num_samples * bps); br->Run([&] (agi::ProgressSink *ps) { + ps->SetTitle(from_wx(_("Load audio"))); ps->SetMessage(from_wx(_("Reading to Hard Disk cache"))); int64_t block = 65536; diff --git a/src/audio_provider_lock.cpp b/src/audio_provider_lock.cpp index ed82755e9..8e6825640 100644 --- a/src/audio_provider_lock.cpp +++ b/src/audio_provider_lock.cpp @@ -44,4 +44,4 @@ public: std::unique_ptr CreateLockAudioProvider(std::unique_ptr src) { return agi::util::make_unique(std::move(src)); -} \ No newline at end of file +} diff --git a/src/audio_provider_pcm.cpp b/src/audio_provider_pcm.cpp index 15cc664ef..10702dd4b 100644 --- a/src/audio_provider_pcm.cpp +++ b/src/audio_provider_pcm.cpp @@ -358,7 +358,7 @@ public: } }; -std::unique_ptr CreatePCMAudioProvider(agi::fs::path const& filename) { +std::unique_ptr CreatePCMAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *) { bool wrong_file_type = true; std::string msg; diff --git a/src/audio_provider_ram.cpp b/src/audio_provider_ram.cpp index 72450b059..9b0df16d8 100644 --- a/src/audio_provider_ram.cpp +++ b/src/audio_provider_ram.cpp @@ -72,6 +72,7 @@ public: } br->Run([&](agi::ProgressSink *ps) { + ps->SetTitle(from_wx(_("Load audio"))); ps->SetMessage(from_wx(_("Reading into RAM"))); int64_t readsize = CacheBlockSize / source->GetBytesPerSample(); diff --git a/src/command/app.cpp b/src/command/app.cpp index 3242f6676..6e0a1f57f 100644 --- a/src/command/app.cpp +++ b/src/command/app.cpp @@ -76,16 +76,16 @@ struct app_display_audio_subs final : public Command { STR_HELP("Display audio and the subtitles grid only") CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) - void operator()(agi::Context *) override { - wxGetApp().frame->SetDisplayMode(0,1); + void operator()(agi::Context *c) override { + c->frame->SetDisplayMode(0,1); } bool Validate(const agi::Context *c) override { return c->audioController->IsAudioOpen(); } - bool IsActive(const agi::Context *) override { - return wxGetApp().frame->IsAudioShown() && !wxGetApp().frame->IsVideoShown(); + bool IsActive(const agi::Context *c) override { + return c->frame->IsAudioShown() && !c->frame->IsVideoShown(); } }; @@ -97,15 +97,15 @@ struct app_display_full final : public Command { CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) void operator()(agi::Context *c) override { - wxGetApp().frame->SetDisplayMode(1,1); + c->frame->SetDisplayMode(1,1); } bool Validate(const agi::Context *c) override { return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->dialog->Get(); } - bool IsActive(const agi::Context *) override { - return wxGetApp().frame->IsAudioShown() && wxGetApp().frame->IsVideoShown(); + bool IsActive(const agi::Context *c) override { + return c->frame->IsAudioShown() && c->frame->IsVideoShown(); } }; @@ -117,11 +117,11 @@ struct app_display_subs final : public Command { CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) void operator()(agi::Context *c) override { - wxGetApp().frame->SetDisplayMode(0,0); + c->frame->SetDisplayMode(0,0); } - bool IsActive(const agi::Context *) override { - return !wxGetApp().frame->IsAudioShown() && !wxGetApp().frame->IsVideoShown(); + bool IsActive(const agi::Context *c) override { + return !c->frame->IsAudioShown() && !c->frame->IsVideoShown(); } }; @@ -133,15 +133,15 @@ struct app_display_video_subs final : public Command { CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) void operator()(agi::Context *c) override { - wxGetApp().frame->SetDisplayMode(1,0); + c->frame->SetDisplayMode(1,0); } bool Validate(const agi::Context *c) override { return c->videoController->IsLoaded() && !c->dialog->Get(); } - bool IsActive(const agi::Context *) override { - return !wxGetApp().frame->IsAudioShown() && wxGetApp().frame->IsVideoShown(); + bool IsActive(const agi::Context *c) override { + return !c->frame->IsAudioShown() && c->frame->IsVideoShown(); } }; @@ -152,7 +152,7 @@ struct app_exit final : public Command { STR_HELP("Exit the application") void operator()(agi::Context *c) override { - wxGetApp().frame->Close(); + c->frame->Close(); } }; @@ -174,7 +174,7 @@ struct app_language final : public Command { int result = wxMessageBox("Aegisub needs to be restarted so that the new language can be applied. Restart now?", "Restart Aegisub?", wxYES_NO | wxICON_QUESTION | wxCENTER); if (result == wxYES) { // Restart Aegisub - if (wxGetApp().frame->Close()) { + if (c->frame->Close()) { RestartAegisub(); } } @@ -200,7 +200,7 @@ struct app_new_window final : public Command { STR_DISP("New Window") STR_HELP("Open a new application window") - void operator()(agi::Context *) override { + void operator()(agi::Context *c) override { RestartAegisub(); } }; @@ -229,11 +229,11 @@ struct app_toggle_global_hotkeys final : public Command { STR_HELP("Toggle global hotkey overrides (Medusa Mode)") CMD_TYPE(COMMAND_TOGGLE) - bool IsActive(const agi::Context *) override { + bool IsActive(const agi::Context *c) override { return OPT_GET("Audio/Medusa Timing Hotkeys")->GetBool(); } - void operator()(agi::Context *) override { + void operator()(agi::Context *c) override { agi::OptionValue *opt = OPT_SET("Audio/Medusa Timing Hotkeys"); opt->SetBool(!opt->GetBool()); } @@ -244,17 +244,17 @@ struct app_toggle_toolbar final : public Command { STR_HELP("Toggle the main toolbar") CMD_TYPE(COMMAND_DYNAMIC_NAME) - wxString StrMenu(const agi::Context *) const override { + wxString StrMenu(const agi::Context *c) const override { return OPT_GET("App/Show Toolbar")->GetBool() ? _("Hide Toolbar") : _("Show Toolbar"); } - wxString StrDisplay(const agi::Context *) const override { + wxString StrDisplay(const agi::Context *c) const override { return StrMenu(nullptr); } - void operator()(agi::Context *) override { + void operator()(agi::Context *c) override { agi::OptionValue *opt = OPT_SET("App/Show Toolbar"); opt->SetBool(!opt->GetBool()); } @@ -266,7 +266,7 @@ struct app_updates final : public Command { STR_DISP("Check for Updates") STR_HELP("Check to see if there is a new version of Aegisub available") - void operator()(agi::Context *) override { + void operator()(agi::Context *c) override { PerformVersionCheck(true); } }; diff --git a/src/command/automation.cpp b/src/command/automation.cpp index abdedbf11..a298c01de 100644 --- a/src/command/automation.cpp +++ b/src/command/automation.cpp @@ -58,7 +58,7 @@ struct reload_all final : public Command { void operator()(agi::Context *c) override { wxGetApp().global_scripts->Reload(); c->local_scripts->Reload(); - StatusTimeout(_("Reloaded all Automation scripts")); + c->frame->StatusTimeout(_("Reloaded all Automation scripts")); } }; @@ -70,7 +70,7 @@ struct reload_autoload final : public Command { void operator()(agi::Context *c) override { wxGetApp().global_scripts->Reload(); - StatusTimeout(_("Reloaded autoload Automation scripts")); + c->frame->StatusTimeout(_("Reloaded autoload Automation scripts")); } }; diff --git a/src/command/grid.cpp b/src/command/grid.cpp index 0b89dbe84..af6fb3690 100644 --- a/src/command/grid.cpp +++ b/src/command/grid.cpp @@ -37,6 +37,7 @@ #include "../ass_file.h" #include "../audio_controller.h" #include "../audio_timing.h" +#include "../frame_main.h" #include "../include/aegisub/context.h" #include "../libresrc/libresrc.h" #include "../options.h" @@ -257,7 +258,7 @@ struct grid_tag_cycle_hiding final : public Command { STR_DISP("Cycle Tag Hiding Mode") STR_HELP("Cycle through tag hiding modes") - void operator()(agi::Context *) override { + void operator()(agi::Context *c) override { int tagMode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt(); // Cycle to next @@ -268,7 +269,7 @@ struct grid_tag_cycle_hiding final : public Command { if (tagMode == 0) message = _("ASS Override Tag mode set to show full tags."); if (tagMode == 1) message = _("ASS Override Tag mode set to simplify tags."); if (tagMode == 2) message = _("ASS Override Tag mode set to hide tags."); - StatusTimeout(message,10000); + c->frame->StatusTimeout(message,10000); // Set option OPT_SET("Subtitle/Grid/Hide Overrides")->SetInt(tagMode); diff --git a/src/command/video.cpp b/src/command/video.cpp index 5cb4d9910..91321f7b7 100644 --- a/src/command/video.cpp +++ b/src/command/video.cpp @@ -99,7 +99,7 @@ struct video_aspect_cinematic final : public validator_video_loaded { void operator()(agi::Context *c) override { c->videoController->Stop(); c->videoController->SetAspectRatio(AspectRatio::Cinematic); - wxGetApp().frame->SetDisplayMode(1,-1); + c->frame->SetDisplayMode(1,-1); } }; @@ -141,7 +141,7 @@ struct video_aspect_custom final : public validator_video_loaded { wxMessageBox(_("Invalid value! Aspect ratio must be between 0.5 and 5.0."),_("Invalid Aspect Ratio"),wxOK | wxICON_ERROR | wxCENTER); else { c->videoController->SetAspectRatio(numval); - wxGetApp().frame->SetDisplayMode(1,-1); + c->frame->SetDisplayMode(1,-1); } } }; @@ -160,7 +160,7 @@ struct video_aspect_default final : public validator_video_loaded { void operator()(agi::Context *c) override { c->videoController->Stop(); c->videoController->SetAspectRatio(AspectRatio::Default); - wxGetApp().frame->SetDisplayMode(1,-1); + c->frame->SetDisplayMode(1,-1); } }; @@ -178,7 +178,7 @@ struct video_aspect_full final : public validator_video_loaded { void operator()(agi::Context *c) override { c->videoController->Stop(); c->videoController->SetAspectRatio(AspectRatio::Fullscreen); - wxGetApp().frame->SetDisplayMode(1,-1); + c->frame->SetDisplayMode(1,-1); } }; @@ -196,7 +196,7 @@ struct video_aspect_wide final : public validator_video_loaded { void operator()(agi::Context *c) override { c->videoController->Stop(); c->videoController->SetAspectRatio(AspectRatio::Widescreen); - wxGetApp().frame->SetDisplayMode(1,-1); + c->frame->SetDisplayMode(1,-1); } }; @@ -238,7 +238,7 @@ struct video_cycle_subtitles_provider final : public cmd::Command { if (it == end(providers)) it = begin(providers); OPT_SET("Subtitle/Provider")->SetString(*it); - StatusTimeout(wxString::Format(_("Subtitles provider set to %s"), to_wx(*it)), 5000); + c->frame->StatusTimeout(wxString::Format(_("Subtitles provider set to %s"), to_wx(*it)), 5000); } }; diff --git a/src/dialog_selection.cpp b/src/dialog_selection.cpp index 1222d9390..fb22f522a 100644 --- a/src/dialog_selection.cpp +++ b/src/dialog_selection.cpp @@ -26,6 +26,7 @@ #include "ass_dialogue.h" #include "ass_file.h" #include "compat.h" +#include "frame_main.h" #include "help_button.h" #include "include/aegisub/context.h" #include "libresrc/libresrc.h" @@ -223,7 +224,7 @@ void DialogSelection::Process(wxCommandEvent&) { if (count == 0) wxMessageBox(message, _("Selection"), wxOK | wxCENTER, this); else - StatusTimeout(message); + con->frame->StatusTimeout(message); AssDialogue *new_active = con->selectionController->GetActiveLine(); if (new_sel.size() && !new_sel.count(new_active)) diff --git a/src/ffmpegsource_common.cpp b/src/ffmpegsource_common.cpp index 868b1e7b5..d8761975e 100644 --- a/src/ffmpegsource_common.cpp +++ b/src/ffmpegsource_common.cpp @@ -38,12 +38,12 @@ #include "ffmpegsource_common.h" #include "compat.h" -#include "dialog_progress.h" #include "frame_main.h" #include "main.h" #include "options.h" #include "utils.h" +#include #include #include #include @@ -66,8 +66,9 @@ static void deinit_com(bool) { static void deinit_com(bool) { } #endif -FFmpegSourceProvider::FFmpegSourceProvider() +FFmpegSourceProvider::FFmpegSourceProvider(agi::BackgroundRunner *br) : COMInited(false, deinit_com) +, br(br) { #ifdef _WIN32 HRESULT res = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); @@ -85,9 +86,6 @@ FFmpegSourceProvider::FFmpegSourceProvider() /// @param Indexer A pointer to the indexer object representing the file to be indexed /// @param CacheName The filename of the output index file /// @param Trackmask A binary mask of the track numbers to index -/// @param IgnoreDecodeErrors True if audio decoding errors will be tolerated, false otherwise -/// @return Returns the index object on success, nullptr otherwise -/// FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, agi::fs::path const& CacheName, int Trackmask, FFMS_IndexErrorHandling IndexEH) { char FFMSErrMsg[1024]; FFMS_ErrorInfo ErrInfo; @@ -97,12 +95,11 @@ FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, agi::fs::pat ErrInfo.SubType = FFMS_ERROR_SUCCESS; std::string MsgString; - // set up progress dialog callback - DialogProgress Progress(wxGetApp().frame, _("Indexing"), _("Reading timecodes and frame/sample data")); - // index all audio tracks FFMS_Index *Index; - Progress.Run([&](agi::ProgressSink *ps) { + br->Run([&](agi::ProgressSink *ps) { + ps->SetTitle(from_wx(_("Indexing"))); + ps->SetMessage(from_wx(_("Reading timecodes and frame/sample data"))); struct progress { agi::ProgressSink *ps; int calls; diff --git a/src/ffmpegsource_common.h b/src/ffmpegsource_common.h index 46f21948f..5ef44b6ec 100644 --- a/src/ffmpegsource_common.h +++ b/src/ffmpegsource_common.h @@ -40,6 +40,8 @@ #include #include +namespace agi { class BackgroundRunner; } + /// Index all tracks #define FFMS_TRACKMASK_ALL -1 /// Index no tracks @@ -50,9 +52,10 @@ class FFmpegSourceProvider { friend class FFmpegSourceCacheCleaner; agi::scoped_holder COMInited; ///< COM initialization state + agi::BackgroundRunner *br; public: - FFmpegSourceProvider(); + FFmpegSourceProvider(agi::BackgroundRunner *br); /// Logging level constants from avutil/log.h enum FFMS_LogLevel { diff --git a/src/frame_main.cpp b/src/frame_main.cpp index 3b60b1e55..bf1a902fe 100644 --- a/src/frame_main.cpp +++ b/src/frame_main.cpp @@ -229,6 +229,7 @@ FrameMain::FrameMain() StartupLog("Initializing context frames"); context->parent = this; + context->frame = this; context->previousFocus = nullptr; StartupLog("Install PNG handler"); diff --git a/src/frame_main.h b/src/frame_main.h index f19e18fd9..497e75e28 100644 --- a/src/frame_main.h +++ b/src/frame_main.h @@ -49,7 +49,7 @@ class VideoBox; namespace agi { struct Context; class OptionValue; } -class FrameMain: public wxFrame { +class FrameMain : public wxFrame { friend class AegisubApp; friend class AegisubFileDropTarget; diff --git a/src/include/aegisub/audio_player.h b/src/include/aegisub/audio_player.h index 0a5ac9693..7638633f8 100644 --- a/src/include/aegisub/audio_player.h +++ b/src/include/aegisub/audio_player.h @@ -40,6 +40,7 @@ #include class AudioProvider; +class wxWindow; class AudioPlayer { protected: @@ -62,5 +63,5 @@ public: struct AudioPlayerFactory { static std::vector GetClasses(); - static std::unique_ptr GetAudioPlayer(AudioProvider *provider); + static std::unique_ptr GetAudioPlayer(AudioProvider *provider, wxWindow *window); }; diff --git a/src/include/aegisub/audio_provider.h b/src/include/aegisub/audio_provider.h index 0de3e45de..28eba2fcb 100644 --- a/src/include/aegisub/audio_provider.h +++ b/src/include/aegisub/audio_provider.h @@ -88,12 +88,14 @@ public: } }; +namespace agi { class BackgroundRunner; } + struct AudioProviderFactory { static std::vector GetClasses(); /// Get a provider for the file /// @param filename URI to open - static std::unique_ptr GetProvider(agi::fs::path const& filename); + static std::unique_ptr GetProvider(agi::fs::path const& filename, agi::BackgroundRunner *br); }; DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception) diff --git a/src/include/aegisub/context.h b/src/include/aegisub/context.h index 2afdd77e5..4f037ba21 100644 --- a/src/include/aegisub/context.h +++ b/src/include/aegisub/context.h @@ -4,6 +4,7 @@ class AudioController; class AssDialogue; class AudioKaraoke; class DialogManager; +class FrameMain; class SearchReplaceEngine; class InitialLineState; class SelectionController; @@ -41,8 +42,9 @@ struct Context { // Views (i.e. things that should eventually not be here at all) AudioBox *audioBox; AudioKaraoke *karaoke; - DialogManager *dialog; BaseGrid *subsGrid; + DialogManager *dialog; + FrameMain *frame; VideoDisplay *videoDisplay; }; diff --git a/src/include/aegisub/subtitles_provider.h b/src/include/aegisub/subtitles_provider.h index e1041d336..e10b97752 100644 --- a/src/include/aegisub/subtitles_provider.h +++ b/src/include/aegisub/subtitles_provider.h @@ -48,7 +48,9 @@ public: virtual void DrawSubtitles(VideoFrame &dst, double time)=0; }; +namespace agi { class BackgroundRunner; } + struct SubtitlesProviderFactory { - static std::unique_ptr GetProvider(); + static std::unique_ptr GetProvider(agi::BackgroundRunner *br); static std::vector GetClasses(); }; diff --git a/src/main.h b/src/main.h index 622dccd46..b28231e13 100644 --- a/src/main.h +++ b/src/main.h @@ -44,7 +44,9 @@ class FrameMain; namespace Automation4 { class AutoloadScriptManager; } -class AegisubApp: public wxApp { +class AegisubApp : public wxApp { + friend class FrameMain; + bool OnInit() override; int OnExit() override; int OnRun() override; @@ -65,10 +67,10 @@ class AegisubApp: public wxApp { // our ticket to catch exceptions happening in event handlers. void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const override; + FrameMain *frame; public: AegisubApp(); AegisubLocale locale; - FrameMain *frame; Automation4::AutoloadScriptManager *global_scripts; // Apple events diff --git a/src/subs_controller.cpp b/src/subs_controller.cpp index 497eb97e1..94ed5ad4c 100644 --- a/src/subs_controller.cpp +++ b/src/subs_controller.cpp @@ -26,6 +26,7 @@ #include "charset_detect.h" #include "compat.h" #include "command/command.h" +#include "Frame_main.h" #include "include/aegisub/context.h" #include "options.h" #include "selection_controller.h" @@ -138,13 +139,13 @@ SubsController::SubsController(agi::Context *context) try { auto fn = AutoSave(); if (!fn.empty()) - StatusTimeout(wxString::Format(_("File backup saved as \"%s\"."), fn.wstring())); + context->frame->StatusTimeout(wxString::Format(_("File backup saved as \"%s\"."), fn.wstring())); } catch (const agi::Exception& err) { - StatusTimeout(to_wx("Exception when attempting to autosave file: " + err.GetMessage())); + context->frame->StatusTimeout(to_wx("Exception when attempting to autosave file: " + err.GetMessage())); } catch (...) { - StatusTimeout("Unhandled exception when attempting to autosave file."); + context->frame->StatusTimeout("Unhandled exception when attempting to autosave file."); } }); } diff --git a/src/subs_preview.cpp b/src/subs_preview.cpp index 33d62ab46..85371e7a1 100644 --- a/src/subs_preview.cpp +++ b/src/subs_preview.cpp @@ -38,6 +38,7 @@ #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" +#include "dialog_progress.h" #include "subs_preview.h" #include "include/aegisub/subtitles_provider.h" #include "video_frame.h" @@ -51,7 +52,7 @@ SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle, agi::Color col) : wxWindow(parent, -1, wxDefaultPosition, size, winStyle) , style(new AssStyle) -, back_color(std::move(col)) +, back_color(col) , sub_file(agi::util::make_unique()) , line(new AssDialogue) { @@ -131,8 +132,10 @@ void SubtitlesPreview::OnSize(wxSizeEvent &evt) { bmp = agi::util::make_unique(w, h, -1); vid.reset(new DummyVideoProvider(0.0, 10, w, h, back_color, true)); try { - if (!provider) - provider = SubtitlesProviderFactory::GetProvider(); + if (!provider) { + DialogProgress progress(this); + provider = SubtitlesProviderFactory::GetProvider(&progress); + } } catch (...) { wxMessageBox( diff --git a/src/subtitles_provider.cpp b/src/subtitles_provider.cpp index 4468ae7a5..42d03ef2d 100644 --- a/src/subtitles_provider.cpp +++ b/src/subtitles_provider.cpp @@ -27,7 +27,7 @@ namespace { struct factory { std::string name; std::string subtype; - std::unique_ptr (*create)(std::string const& subtype); + std::unique_ptr (*create)(std::string const& subtype, agi::BackgroundRunner *br); bool hidden; }; @@ -47,14 +47,14 @@ std::vector SubtitlesProviderFactory::GetClasses() { return ::GetClasses(factories()); } -std::unique_ptr SubtitlesProviderFactory::GetProvider() { +std::unique_ptr SubtitlesProviderFactory::GetProvider(agi::BackgroundRunner *br) { auto preferred = OPT_GET("Subtitle/Provider")->GetString(); auto sorted = GetSorted(factories(), preferred); std::string error; for (auto factory : sorted) { try { - auto provider = factory->create(factory->subtype); + auto provider = factory->create(factory->subtype, br); if (provider) return provider; } catch (agi::UserCancelException const&) { throw; } diff --git a/src/subtitles_provider_csri.cpp b/src/subtitles_provider_csri.cpp index 69f93c885..4d7b5fad1 100644 --- a/src/subtitles_provider_csri.cpp +++ b/src/subtitles_provider_csri.cpp @@ -139,7 +139,7 @@ std::vector List() { return final; } -std::unique_ptr Create(std::string const& name) { +std::unique_ptr Create(std::string const& name, agi::BackgroundRunner *) { return agi::util::make_unique(name); } } diff --git a/src/subtitles_provider_csri.h b/src/subtitles_provider_csri.h index 6fe2f8728..ef5026f04 100644 --- a/src/subtitles_provider_csri.h +++ b/src/subtitles_provider_csri.h @@ -19,8 +19,9 @@ #include class SubtitlesProvider; +namespace agi { class BackgroundRunner; } namespace csri { std::vector List(); - std::unique_ptr Create(std::string const& subtype); + std::unique_ptr Create(std::string const& subtype, agi::BackgroundRunner *br); } diff --git a/src/subtitles_provider_libass.cpp b/src/subtitles_provider_libass.cpp index ed163bd2b..404274089 100644 --- a/src/subtitles_provider_libass.cpp +++ b/src/subtitles_provider_libass.cpp @@ -40,13 +40,11 @@ #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" -#include "dialog_progress.h" -#include "frame_main.h" +#include "compat.h" #include "include/aegisub/subtitles_provider.h" -#include "main.h" -#include "utils.h" #include "video_frame.h" +#include #include #include #include @@ -95,14 +93,14 @@ class LibassSubtitlesProvider final : public SubtitlesProvider { ASS_Track* ass_track = nullptr; public: - LibassSubtitlesProvider(); + LibassSubtitlesProvider(agi::BackgroundRunner *br); ~LibassSubtitlesProvider(); void LoadSubtitles(AssFile *subs) override; void DrawSubtitles(VideoFrame &dst, double time) override; }; -LibassSubtitlesProvider::LibassSubtitlesProvider() { +LibassSubtitlesProvider::LibassSubtitlesProvider(agi::BackgroundRunner *br) { auto done = std::make_shared(false); auto renderer = std::make_shared(nullptr); cache_queue->Async([=]{ @@ -115,8 +113,9 @@ LibassSubtitlesProvider::LibassSubtitlesProvider() { *renderer = ass_renderer; }); - DialogProgress progress(wxGetApp().frame, _("Updating font index"), _("This may take several minutes")); - progress.Run([=](agi::ProgressSink *ps) { + br->Run([=](agi::ProgressSink *ps) { + ps->SetTitle(from_wx(_("Updating font index"))); + ps->SetMessage(from_wx(_("This may take several minutes"))); ps->SetIndeterminate(); while (!*done && !ps->IsCancelled()) agi::util::sleep_for(250); @@ -205,8 +204,8 @@ void LibassSubtitlesProvider::DrawSubtitles(VideoFrame &frame,double time) { } namespace libass { -std::unique_ptr Create(std::string const&) { - return agi::util::make_unique(); +std::unique_ptr Create(std::string const&, agi::BackgroundRunner *br) { + return agi::util::make_unique(br); } void CacheFonts() { diff --git a/src/subtitles_provider_libass.h b/src/subtitles_provider_libass.h index e5dbd57b5..8df333595 100644 --- a/src/subtitles_provider_libass.h +++ b/src/subtitles_provider_libass.h @@ -18,8 +18,9 @@ #include class SubtitlesProvider; +namespace agi { class BackgroundRunner; } namespace libass { - std::unique_ptr Create(std::string const&); + std::unique_ptr Create(std::string const&, agi::BackgroundRunner *br); void CacheFonts(); } diff --git a/src/threaded_frame_source.cpp b/src/threaded_frame_source.cpp index 99f8850fb..428cf6d56 100644 --- a/src/threaded_frame_source.cpp +++ b/src/threaded_frame_source.cpp @@ -99,20 +99,20 @@ std::shared_ptr ThreadedFrameSource::ProcFrame(int frame_number, dou return frame; } -static std::unique_ptr get_subs_provider(wxEvtHandler *parent) { +static std::unique_ptr get_subs_provider(wxEvtHandler *evt_handler, agi::BackgroundRunner *br) { try { - return SubtitlesProviderFactory::GetProvider(); + return SubtitlesProviderFactory::GetProvider(br); } catch (std::string const& err) { - parent->AddPendingEvent(SubtitlesProviderErrorEvent(err)); + evt_handler->AddPendingEvent(SubtitlesProviderErrorEvent(err)); return nullptr; } } -ThreadedFrameSource::ThreadedFrameSource(agi::fs::path const& video_filename, std::string const& colormatrix, wxEvtHandler *parent) +ThreadedFrameSource::ThreadedFrameSource(agi::fs::path const& video_filename, std::string const& colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br) : worker(agi::dispatch::Create()) -, subs_provider(get_subs_provider(parent)) -, video_provider(VideoProviderFactory::GetProvider(video_filename, colormatrix)) +, subs_provider(get_subs_provider(parent, br)) +, video_provider(VideoProviderFactory::GetProvider(video_filename, colormatrix, br)) , parent(parent) { } diff --git a/src/threaded_frame_source.h b/src/threaded_frame_source.h index f7f366833..d8a4c813f 100644 --- a/src/threaded_frame_source.h +++ b/src/threaded_frame_source.h @@ -35,7 +35,10 @@ class SubtitlesProvider; class VideoProvider; class VideoProviderError; struct VideoFrame; -namespace agi { namespace dispatch { class Queue; } } +namespace agi { + class BackgroundRunner; + namespace dispatch { class Queue; } +} /// @class ThreadedFrameSource /// @brief An asynchronous video decoding and subtitle rendering wrapper @@ -106,7 +109,7 @@ public: /// @brief Constructor /// @param videoFileName File to open /// @param parent Event handler to send FrameReady events to - ThreadedFrameSource(agi::fs::path const& filename, std::string const& colormatrix, wxEvtHandler *parent); + ThreadedFrameSource(agi::fs::path const& filename, std::string const& colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br); ~ThreadedFrameSource(); }; diff --git a/src/utils.cpp b/src/utils.cpp index 2936ea9bf..b7efb64a8 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -97,10 +97,6 @@ std::string float_to_string(double val) { return s; } -void StatusTimeout(wxString const& msg, int ms) { - wxGetApp().frame->StatusTimeout(msg, ms); -} - int SmallestPowerOf2(int x) { x--; x |= (x >> 1); diff --git a/src/utils.h b/src/utils.h index 2cbfb555f..9fe35e8a9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -55,8 +55,6 @@ wxString PrettySize(int bytes); std::string float_to_string(double val); -void StatusTimeout(wxString const& msg, int ms = 10000); - /// @brief Get the smallest power of two that is greater or equal to x /// /// Algorithm from http://bob.allegronetwork.com/prog/tricks.html diff --git a/src/video_context.cpp b/src/video_context.cpp index 31da0be64..2a17c9396 100644 --- a/src/video_context.cpp +++ b/src/video_context.cpp @@ -41,6 +41,7 @@ #include "ass_time.h" #include "audio_controller.h" #include "compat.h" +#include "dialog_progress.h" #include "include/aegisub/context.h" #include "include/aegisub/video_provider.h" #include "mkv_wrap.h" @@ -122,8 +123,9 @@ void VideoContext::SetVideo(const agi::fs::path &filename) { bool commit_subs = false; try { + DialogProgress progress(context->parent); auto old_matrix = context->ass->GetScriptInfo("YCbCr Matrix"); - provider.reset(new ThreadedFrameSource(filename, old_matrix, this)); + provider.reset(new ThreadedFrameSource(filename, old_matrix, this, &progress)); video_provider = provider->GetVideoProvider(); video_filename = filename; diff --git a/src/video_provider_avs.cpp b/src/video_provider_avs.cpp index e9bd50ce5..e992805c4 100644 --- a/src/video_provider_avs.cpp +++ b/src/video_provider_avs.cpp @@ -310,7 +310,8 @@ std::shared_ptr AvisynthVideoProvider::GetFrame(int n) { } } -std::unique_ptr CreateAvisynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix) { +namespace agi { class BackgroundRunner; } +std::unique_ptr CreateAvisynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *) { return agi::util::make_unique(path, colormatrix); } #endif // HAVE_AVISYNTH diff --git a/src/video_provider_dummy.cpp b/src/video_provider_dummy.cpp index 3c70357ae..9bb18a0e0 100644 --- a/src/video_provider_dummy.cpp +++ b/src/video_provider_dummy.cpp @@ -97,7 +97,8 @@ std::shared_ptr DummyVideoProvider::GetFrame(int) { return std::make_shared(data.data(), width, height, width * 4, false); } -std::unique_ptr CreateDummyVideoProvider(agi::fs::path const& filename, std::string const&) { +namespace agi { class BackgroundRunner; } +std::unique_ptr CreateDummyVideoProvider(agi::fs::path const& filename, std::string const&, agi::BackgroundRunner *) { if (!boost::starts_with(filename.string(), "?dummy")) return {}; @@ -123,4 +124,4 @@ std::unique_ptr CreateDummyVideoProvider(agi::fs::path const& fil bool pattern = toks[i] == "c"; return agi::util::make_unique(fps, frames, width, height, agi::Color(red, green, blue), pattern); -} \ No newline at end of file +} diff --git a/src/video_provider_ffmpegsource.cpp b/src/video_provider_ffmpegsource.cpp index 7a43ee348..794714218 100644 --- a/src/video_provider_ffmpegsource.cpp +++ b/src/video_provider_ffmpegsource.cpp @@ -71,7 +71,7 @@ class FFmpegSourceVideoProvider final : public VideoProvider, FFmpegSourceProvid void LoadVideo(agi::fs::path const& filename, std::string const& colormatrix); public: - FFmpegSourceVideoProvider(agi::fs::path const& filename, std::string const& colormatrix); + FFmpegSourceVideoProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br); std::shared_ptr GetFrame(int n) override; @@ -108,8 +108,9 @@ std::string colormatrix_description(int cs, int cr) { } } -FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(agi::fs::path const& filename, std::string const& colormatrix) try -: VideoSource(nullptr, FFMS_DestroyVideoSource) +FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) try +: FFmpegSourceProvider(br) +, VideoSource(nullptr, FFMS_DestroyVideoSource) { ErrInfo.Buffer = FFMSErrMsg; ErrInfo.BufferSize = sizeof(FFMSErrMsg); @@ -285,8 +286,8 @@ std::shared_ptr FFmpegSourceVideoProvider::GetFrame(int n) { } } -std::unique_ptr CreateFFmpegSourceVideoProvider(agi::fs::path const& path, std::string const& colormatrix) { - return agi::util::make_unique(path, colormatrix); +std::unique_ptr CreateFFmpegSourceVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *br) { + return agi::util::make_unique(path, colormatrix, br); } #endif /* WITH_FFMS2 */ diff --git a/src/video_provider_manager.cpp b/src/video_provider_manager.cpp index 73550b50f..468d66b6c 100644 --- a/src/video_provider_manager.cpp +++ b/src/video_provider_manager.cpp @@ -28,17 +28,17 @@ #include -std::unique_ptr CreateDummyVideoProvider(agi::fs::path const&, std::string const&); -std::unique_ptr CreateYUV4MPEGVideoProvider(agi::fs::path const&, std::string const&); -std::unique_ptr CreateFFmpegSourceVideoProvider(agi::fs::path const&, std::string const&); -std::unique_ptr CreateAvisynthVideoProvider(agi::fs::path const&, std::string const&); +std::unique_ptr CreateDummyVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *); +std::unique_ptr CreateYUV4MPEGVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *); +std::unique_ptr CreateFFmpegSourceVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *); +std::unique_ptr CreateAvisynthVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *); std::unique_ptr CreateCacheVideoProvider(std::unique_ptr); namespace { struct factory { const char *name; - std::unique_ptr (*create)(agi::fs::path const&, std::string const&); + std::unique_ptr (*create)(agi::fs::path const&, std::string const&, agi::BackgroundRunner *); bool hidden; }; @@ -58,7 +58,7 @@ std::vector VideoProviderFactory::GetClasses() { return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers))); } -std::unique_ptr VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix) { +std::unique_ptr VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) { auto preferred = OPT_GET("Video/Provider")->GetString(); auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); @@ -70,7 +70,7 @@ std::unique_ptr VideoProviderFactory::GetProvider(agi::fs::path c for (auto factory : sorted) { std::string err; try { - auto provider = factory->create(filename, colormatrix); + auto provider = factory->create(filename, colormatrix, br); if (!provider) continue; LOG_I("manager/video/provider") << factory->name << ": opened " << filename; return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider); diff --git a/src/video_provider_manager.h b/src/video_provider_manager.h index 718401e73..0e4ddfcb3 100644 --- a/src/video_provider_manager.h +++ b/src/video_provider_manager.h @@ -21,8 +21,9 @@ #include class VideoProvider; +namespace agi { class BackgroundRunner; } struct VideoProviderFactory { static std::vector GetClasses(); - static std::unique_ptr GetProvider(agi::fs::path const& video_file, std::string const& colormatrix); + static std::unique_ptr GetProvider(agi::fs::path const& video_file, std::string const& colormatrix, agi::BackgroundRunner *br); }; diff --git a/src/video_provider_yuv4mpeg.cpp b/src/video_provider_yuv4mpeg.cpp index 3bed2812e..08bd0626b 100644 --- a/src/video_provider_yuv4mpeg.cpp +++ b/src/video_provider_yuv4mpeg.cpp @@ -448,6 +448,7 @@ std::shared_ptr YUV4MPEGVideoProvider::GetFrame(int n) { } } -std::unique_ptr CreateYUV4MPEGVideoProvider(agi::fs::path const& path, std::string const&) { +namespace agi { class BackgroundRunner; } +std::unique_ptr CreateYUV4MPEGVideoProvider(agi::fs::path const& path, std::string const&, agi::BackgroundRunner *) { return agi::util::make_unique(path); }