Eliminate all uses of FrameMain via the global app object

This commit is contained in:
Thomas Goyne 2014-03-25 09:51:38 -07:00
parent e596de03c7
commit 39626db787
49 changed files with 198 additions and 195 deletions

View File

@ -39,6 +39,7 @@
#include "ass_file.h" #include "ass_file.h"
#include "audio_timing.h" #include "audio_timing.h"
#include "compat.h" #include "compat.h"
#include "dialog_progress.h"
#include "include/aegisub/audio_player.h" #include "include/aegisub/audio_player.h"
#include "include/aegisub/audio_provider.h" #include "include/aegisub/audio_provider.h"
#include "include/aegisub/context.h" #include "include/aegisub/context.h"
@ -113,7 +114,7 @@ void AudioController::OnComputerResuming(wxPowerEvent &)
{ {
try try
{ {
player = AudioPlayerFactory::GetAudioPlayer(provider.get()); player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent);
} }
catch (...) catch (...)
{ {
@ -133,7 +134,7 @@ void AudioController::OnAudioPlayerChanged()
try try
{ {
player = AudioPlayerFactory::GetAudioPlayer(provider.get()); player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent);
} }
catch (...) catch (...)
{ {
@ -157,7 +158,8 @@ void AudioController::OpenAudio(agi::fs::path const& url)
std::unique_ptr<AudioProvider> new_provider; std::unique_ptr<AudioProvider> new_provider;
try { try {
new_provider = AudioProviderFactory::GetProvider(url); DialogProgress progress(context->parent);
new_provider = AudioProviderFactory::GetProvider(url, &progress);
config::path->SetToken("?audio", url); config::path->SetToken("?audio", url);
} }
catch (agi::UserCancelException const&) { catch (agi::UserCancelException const&) {
@ -173,7 +175,7 @@ void AudioController::OpenAudio(agi::fs::path const& url)
try try
{ {
player = AudioPlayerFactory::GetAudioPlayer(provider.get()); player = AudioPlayerFactory::GetAudioPlayer(provider.get(), context->parent);
} }
catch (...) catch (...)
{ {

View File

@ -47,18 +47,18 @@ AudioPlayer::AudioPlayer(AudioProvider *provider)
{ {
} }
std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *providers); std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *providers, wxWindow *window);
namespace { namespace {
struct factory { struct factory {
const char *name; const char *name;
std::unique_ptr<AudioPlayer> (*create)(AudioProvider *); std::unique_ptr<AudioPlayer> (*create)(AudioProvider *, wxWindow *window);
bool hidden; bool hidden;
}; };
@ -89,7 +89,7 @@ std::vector<std::string> AudioPlayerFactory::GetClasses() {
return ::GetClasses(boost::make_iterator_range(std::begin(factories), std::end(factories))); return ::GetClasses(boost::make_iterator_range(std::begin(factories), std::end(factories)));
} }
std::unique_ptr<AudioPlayer> AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) { std::unique_ptr<AudioPlayer> AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider, wxWindow *window) {
if (std::distance(std::begin(factories), std::end(factories)) == 0) if (std::distance(std::begin(factories), std::end(factories)) == 0)
throw agi::NoAudioPlayersError("No audio players are available.", nullptr); throw agi::NoAudioPlayersError("No audio players are available.", nullptr);
@ -99,7 +99,7 @@ std::unique_ptr<AudioPlayer> AudioPlayerFactory::GetAudioPlayer(AudioProvider *p
std::string error; std::string error;
for (auto factory : sorted) { for (auto factory : sorted) {
try { try {
return factory->create(provider); return factory->create(provider, window);
} }
catch (agi::AudioPlayerOpenError const& err) { catch (agi::AudioPlayerOpenError const& err) {
error += std::string(factory->name) + " factory: " + err.GetChainedMessage() + "\n"; error += std::string(factory->name) + " factory: " + err.GetChainedMessage() + "\n";

View File

@ -461,7 +461,7 @@ void AlsaPlayer::SetVolume(double vol)
} }
} }
std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *provider) std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *provider, wxWindow *)
{ {
return agi::util::make_unique<AlsaPlayer>(provider); return agi::util::make_unique<AlsaPlayer>(provider);
} }

View File

@ -84,7 +84,7 @@ class DirectSoundPlayer final : public AudioPlayer {
DirectSoundPlayerThread *thread = nullptr; DirectSoundPlayerThread *thread = nullptr;
public: public:
DirectSoundPlayer(AudioProvider *provider); DirectSoundPlayer(AudioProvider *provider, wxWindow *parent);
~DirectSoundPlayer(); ~DirectSoundPlayer();
void Play(int64_t start,int64_t count); void Play(int64_t start,int64_t count);
@ -99,7 +99,7 @@ public:
void SetVolume(double vol) { volume = vol; } void SetVolume(double vol) { volume = vol; }
}; };
DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider) DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider, wxWindow *parent)
: AudioPlayer(provider) : AudioPlayer(provider)
{ {
// Initialize the DirectSound object // Initialize the DirectSound object
@ -108,7 +108,7 @@ DirectSoundPlayer::DirectSoundPlayer(AudioProvider *provider)
if (FAILED(res)) throw agi::AudioPlayerOpenError("Failed initializing DirectSound", 0); if (FAILED(res)) throw agi::AudioPlayerOpenError("Failed initializing DirectSound", 0);
// Set DirectSound parameters // Set DirectSound parameters
directSound->SetCooperativeLevel((HWND)wxGetApp().frame->GetHandle(),DSSCL_PRIORITY); directSound->SetCooperativeLevel((HWND)parent->GetHandle(),DSSCL_PRIORITY);
// Create the wave format structure // Create the wave format structure
WAVEFORMATEX waveFormat; WAVEFORMATEX waveFormat;
@ -370,8 +370,8 @@ void DirectSoundPlayerThread::Stop() {
} }
} }
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *provider) { std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *provider, wxWindow *parent) {
return agi::util::make_unique<DirectSoundPlayer>(provider); return agi::util::make_unique<DirectSoundPlayer>(provider, parent);
} }
#endif // WITH_DIRECTSOUND #endif // WITH_DIRECTSOUND

View File

@ -77,7 +77,7 @@ class DirectSoundPlayer2 final : public AudioPlayer {
public: public:
/// @brief Constructor /// @brief Constructor
DirectSoundPlayer2(AudioProvider *provider); DirectSoundPlayer2(AudioProvider *provider, wxWindow *parent);
/// @brief Destructor /// @brief Destructor
~DirectSoundPlayer2(); ~DirectSoundPlayer2();
@ -144,40 +144,15 @@ struct COMInitialization {
} }
}; };
/// @class COMObjectRetainer struct ReleaseCOMObject {
/// @brief Simple auto_ptr-like class for COM objects void operator()(IUnknown *obj) {
template<class T>
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()
{
if (obj) obj->Release(); if (obj) obj->Release();
} }
/// @brief Dereference the managed object
/// @return The managed object
T * operator -> ()
{
return obj;
}
}; };
template<typename T>
using COMObjectRetainer = std::unique_ptr<T, ReleaseCOMObject>;
/// @brief RAII wrapper around Win32 HANDLE type /// @brief RAII wrapper around Win32 HANDLE type
struct Win32KernelHandle final : public agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> { struct Win32KernelHandle final : public agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> {
/// @brief Create with a managed handle /// @brief Create with a managed handle
@ -219,6 +194,8 @@ class DirectSoundPlayer2Thread {
/// @brief Check for error state and throw exception if one occurred /// @brief Check for error state and throw exception if one occurred
void CheckError(); void CheckError();
HWND parent;
/// Win32 handle to the thread /// Win32 handle to the thread
Win32KernelHandle thread_handle; Win32KernelHandle thread_handle;
@ -277,7 +254,7 @@ public:
/// @param provider Audio provider to take sample data from /// @param provider Audio provider to take sample data from
/// @param WantedLatency Desired length in milliseconds to write ahead of the playback cursor /// @param WantedLatency Desired length in milliseconds to write ahead of the playback cursor
/// @param BufferLength Multiplier for WantedLatency to get total buffer length /// @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 /// @brief Destructor, waits for thread to have died
~DirectSoundPlayer2Thread(); ~DirectSoundPlayer2Thread();
@ -340,15 +317,15 @@ void DirectSoundPlayer2Thread::Run()
catch (std::exception e) catch (std::exception e)
REPORT_ERROR("Could not initialise COM") REPORT_ERROR("Could not initialise COM")
// Create DirectSound object // Create DirectSound object
COMObjectRetainer<IDirectSound8> ds; IDirectSound8 *ds_raw = nullptr;
if (FAILED(DirectSoundCreate8(&DSDEVID_DefaultPlayback, &ds.obj, nullptr))) if (FAILED(DirectSoundCreate8(&DSDEVID_DefaultPlayback, &ds_raw, nullptr)))
REPORT_ERROR("Cound not create DirectSound object") REPORT_ERROR("Cound not create DirectSound object")
COMObjectRetainer<IDirectSound8> ds(ds_raw);
// Ensure we can get interesting wave formats (unless we have PRIORITY we can only use a standard 8 bit format) // 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<AegisubApp*>(wxApp::GetInstance())->frame->GetHandle(), DSSCL_PRIORITY); ds->SetCooperativeLevel(parent, DSSCL_PRIORITY);
// Describe the wave format // Describe the wave format
WAVEFORMATEX waveFormat; WAVEFORMATEX waveFormat;
@ -379,9 +356,10 @@ void DirectSoundPlayer2Thread::Run()
REPORT_ERROR("Could not create buffer") REPORT_ERROR("Could not create buffer")
// But it's an old version interface we get, query it for the DSound8 interface // But it's an old version interface we get, query it for the DSound8 interface
COMObjectRetainer<IDirectSoundBuffer8> bfr; IDirectSoundBuffer8 *bfr_raw = nullptr;
if (FAILED(bfr7->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&bfr.obj))) if (FAILED(bfr7->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&bfr_raw)))
REPORT_ERROR("Buffer doesn't support version 8 interface") REPORT_ERROR("Buffer doesn't support version 8 interface")
COMObjectRetainer<IDirectSoundBuffer8> bfr(bfr_raw);
bfr7->Release(); bfr7->Release();
bfr7 = 0; bfr7 = 0;
@ -447,7 +425,7 @@ void DirectSoundPlayer2Thread::Run()
// Clear the buffer in case we can't fill it completely // Clear the buffer in case we can't fill it completely
memset(buf, 0, buf_size); 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; buffer_offset += bytes_filled;
if (buffer_offset >= bufSize) buffer_offset -= bufSize; if (buffer_offset >= bufSize) buffer_offset -= bufSize;
@ -575,7 +553,7 @@ do_fill_buffer:
break; 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; buffer_offset += bytes_filled;
if (buffer_offset >= bufSize) buffer_offset -= bufSize; if (buffer_offset >= bufSize) buffer_offset -= bufSize;
@ -694,8 +672,9 @@ void DirectSoundPlayer2Thread::CheckError()
} }
} }
DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength) DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength, wxWindow *parent)
: event_start_playback (CreateEvent(0, FALSE, FALSE, 0)) : parent((HWND)parent->GetHandle())
, event_start_playback (CreateEvent(0, FALSE, FALSE, 0))
, event_stop_playback (CreateEvent(0, FALSE, FALSE, 0)) , event_stop_playback (CreateEvent(0, FALSE, FALSE, 0))
, event_update_end_time (CreateEvent(0, FALSE, FALSE, 0)) , event_update_end_time (CreateEvent(0, FALSE, FALSE, 0))
, event_set_volume (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) : AudioPlayer(provider)
{ {
// The buffer will hold BufferLength times WantedLatency milliseconds of audio // The buffer will hold BufferLength times WantedLatency milliseconds of audio
@ -848,7 +827,7 @@ DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider)
try try
{ {
thread = agi::util::make_unique<DirectSoundPlayer2Thread>(provider, WantedLatency, BufferLength); thread = agi::util::make_unique<DirectSoundPlayer2Thread>(provider, WantedLatency, BufferLength, parent);
} }
catch (const char *msg) catch (const char *msg)
{ {
@ -962,8 +941,8 @@ void DirectSoundPlayer2::SetVolume(double vol)
} }
} }
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *provider) { std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *provider, wxWindow *parent) {
return agi::util::make_unique<DirectSoundPlayer2>(provider); return agi::util::make_unique<DirectSoundPlayer2>(provider, parent);
} }
#endif // WITH_DIRECTSOUND #endif // WITH_DIRECTSOUND

View File

@ -286,7 +286,7 @@ int64_t OpenALPlayer::GetCurrentPosition()
} }
} }
std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *provider) std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *provider, wxWindow *)
{ {
return agi::util::make_unique<OpenALPlayer>(provider); return agi::util::make_unique<OpenALPlayer>(provider);
} }

View File

@ -283,7 +283,7 @@ int64_t OSSPlayer::GetCurrentPosition()
} }
} }
std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *provider) { std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *provider, wxWindow *) {
return agi::util::make_unique<OSSPlayer>(provider); return agi::util::make_unique<OSSPlayer>(provider);
} }

View File

@ -283,7 +283,7 @@ bool PortAudioPlayer::IsPlaying() {
return !!Pa_IsStreamActive(stream); return !!Pa_IsStreamActive(stream);
} }
std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *provider) { std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *provider, wxWindow *) {
return agi::util::make_unique<PortAudioPlayer>(provider); return agi::util::make_unique<PortAudioPlayer>(provider);
} }

View File

@ -335,7 +335,7 @@ void PulseAudioPlayer::pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread)
} }
} }
std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *provider) { std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *provider, wxWindow *) {
return agi::util::make_unique<PulseAudioPlayer>(provider); return agi::util::make_unique<PulseAudioPlayer>(provider);
} }
#endif // WITH_LIBPULSE #endif // WITH_LIBPULSE

View File

@ -37,13 +37,13 @@
#include "include/aegisub/audio_provider.h" #include "include/aegisub/audio_provider.h"
#include "audio_controller.h" #include "audio_controller.h"
#include "dialog_progress.h"
#include "factory_manager.h" #include "factory_manager.h"
#include "frame_main.h" #include "frame_main.h"
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
#include "utils.h" #include "utils.h"
#include <libaegisub/background_runner.h>
#include <libaegisub/fs.h> #include <libaegisub/fs.h>
#include <libaegisub/log.h> #include <libaegisub/log.h>
#include <libaegisub/util.h> #include <libaegisub/util.h>
@ -104,10 +104,10 @@ void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
} }
} }
std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& filename); std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *);
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename); std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *);
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& filename); std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *);
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& filename); std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *);
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider> source_provider); std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider> source_provider);
std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> source_provider); std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> source_provider);
@ -117,7 +117,7 @@ std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvi
namespace { namespace {
struct factory { struct factory {
const char *name; const char *name;
std::unique_ptr<AudioProvider> (*create)(agi::fs::path const&); std::unique_ptr<AudioProvider> (*create)(agi::fs::path const&, agi::BackgroundRunner *);
bool hidden; bool hidden;
}; };
@ -137,7 +137,7 @@ std::vector<std::string> AudioProviderFactory::GetClasses() {
return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers))); return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers)));
} }
std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename) { std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename, agi::BackgroundRunner *br) {
auto preferred = OPT_GET("Audio/Provider")->GetString(); auto preferred = OPT_GET("Audio/Provider")->GetString();
auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred);
@ -148,7 +148,7 @@ std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path c
for (auto const& factory : sorted) { for (auto const& factory : sorted) {
try { try {
provider = factory->create(filename); provider = factory->create(filename, br);
if (!provider) continue; if (!provider) continue;
LOG_I("audio_provider") << "Using audio provider: " << factory->name; LOG_I("audio_provider") << "Using audio provider: " << factory->name;
break; break;
@ -189,13 +189,11 @@ std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path c
if (!cache || !needsCache) if (!cache || !needsCache)
return CreateLockAudioProvider(std::move(provider)); return CreateLockAudioProvider(std::move(provider));
DialogProgress progress(wxGetApp().frame, _("Load audio"));
// Convert to RAM // Convert to RAM
if (cache == 1) return CreateRAMAudioProvider(std::move(provider), &progress); if (cache == 1) return CreateRAMAudioProvider(std::move(provider), br);
// Convert to HD // 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); throw agi::AudioCacheOpenError("Unknown caching method", nullptr);
} }

View File

@ -147,7 +147,7 @@ void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count)
} }
} }
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& file) { std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) {
return agi::util::make_unique<AvisynthAudioProvider>(file); return agi::util::make_unique<AvisynthAudioProvider>(file);
} }
#endif #endif

View File

@ -88,7 +88,7 @@ public:
}; };
} }
std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& file) { std::unique_ptr<AudioProvider> CreateDummyAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) {
if (!boost::starts_with(file.string(), "dummy-audio:")) if (!boost::starts_with(file.string(), "dummy-audio:"))
return {}; return {};
return agi::util::make_unique<DummyAudioProvider>(file); return agi::util::make_unique<DummyAudioProvider>(file);

View File

@ -61,15 +61,16 @@ class FFmpegSourceAudioProvider final : public AudioProvider, FFmpegSourceProvid
} }
public: public:
FFmpegSourceAudioProvider(agi::fs::path const& filename); FFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *br);
bool NeedsCache() const override { return true; } bool NeedsCache() const override { return true; }
}; };
/// @brief Constructor /// @brief Constructor
/// @param filename The filename to open /// @param filename The filename to open
FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename) try FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *br) try
: AudioSource(nullptr, FFMS_DestroyAudioSource) : FFmpegSourceProvider(br)
, AudioSource(nullptr, FFMS_DestroyAudioSource)
{ {
ErrInfo.Buffer = FFMSErrMsg; ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.BufferSize = sizeof(FFMSErrMsg);
@ -206,8 +207,8 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
} }
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& file) { std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *br) {
return agi::util::make_unique<FFmpegSourceAudioProvider>(file); return agi::util::make_unique<FFmpegSourceAudioProvider>(file, br);
} }
#endif /* WITH_FFMS2 */ #endif /* WITH_FFMS2 */

View File

@ -66,6 +66,7 @@ public:
file = agi::util::make_unique<agi::temp_file_mapping>(cache_dir / filename, num_samples * bps); file = agi::util::make_unique<agi::temp_file_mapping>(cache_dir / filename, num_samples * bps);
br->Run([&] (agi::ProgressSink *ps) { br->Run([&] (agi::ProgressSink *ps) {
ps->SetTitle(from_wx(_("Load audio")));
ps->SetMessage(from_wx(_("Reading to Hard Disk cache"))); ps->SetMessage(from_wx(_("Reading to Hard Disk cache")));
int64_t block = 65536; int64_t block = 65536;

View File

@ -44,4 +44,4 @@ public:
std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> src) { std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> src) {
return agi::util::make_unique<LockAudioProvider>(std::move(src)); return agi::util::make_unique<LockAudioProvider>(std::move(src));
} }

View File

@ -358,7 +358,7 @@ public:
} }
}; };
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename) { std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *) {
bool wrong_file_type = true; bool wrong_file_type = true;
std::string msg; std::string msg;

View File

@ -72,6 +72,7 @@ public:
} }
br->Run([&](agi::ProgressSink *ps) { br->Run([&](agi::ProgressSink *ps) {
ps->SetTitle(from_wx(_("Load audio")));
ps->SetMessage(from_wx(_("Reading into RAM"))); ps->SetMessage(from_wx(_("Reading into RAM")));
int64_t readsize = CacheBlockSize / source->GetBytesPerSample(); int64_t readsize = CacheBlockSize / source->GetBytesPerSample();

View File

@ -76,16 +76,16 @@ struct app_display_audio_subs final : public Command {
STR_HELP("Display audio and the subtitles grid only") STR_HELP("Display audio and the subtitles grid only")
CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO)
void operator()(agi::Context *) override { void operator()(agi::Context *c) override {
wxGetApp().frame->SetDisplayMode(0,1); c->frame->SetDisplayMode(0,1);
} }
bool Validate(const agi::Context *c) override { bool Validate(const agi::Context *c) override {
return c->audioController->IsAudioOpen(); return c->audioController->IsAudioOpen();
} }
bool IsActive(const agi::Context *) override { bool IsActive(const agi::Context *c) override {
return wxGetApp().frame->IsAudioShown() && !wxGetApp().frame->IsVideoShown(); return c->frame->IsAudioShown() && !c->frame->IsVideoShown();
} }
}; };
@ -97,15 +97,15 @@ struct app_display_full final : public Command {
CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO)
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
wxGetApp().frame->SetDisplayMode(1,1); c->frame->SetDisplayMode(1,1);
} }
bool Validate(const agi::Context *c) override { bool Validate(const agi::Context *c) override {
return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>(); return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>();
} }
bool IsActive(const agi::Context *) override { bool IsActive(const agi::Context *c) override {
return wxGetApp().frame->IsAudioShown() && wxGetApp().frame->IsVideoShown(); return c->frame->IsAudioShown() && c->frame->IsVideoShown();
} }
}; };
@ -117,11 +117,11 @@ struct app_display_subs final : public Command {
CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO) CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO)
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
wxGetApp().frame->SetDisplayMode(0,0); c->frame->SetDisplayMode(0,0);
} }
bool IsActive(const agi::Context *) override { bool IsActive(const agi::Context *c) override {
return !wxGetApp().frame->IsAudioShown() && !wxGetApp().frame->IsVideoShown(); 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) CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO)
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
wxGetApp().frame->SetDisplayMode(1,0); c->frame->SetDisplayMode(1,0);
} }
bool Validate(const agi::Context *c) override { bool Validate(const agi::Context *c) override {
return c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>(); return c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>();
} }
bool IsActive(const agi::Context *) override { bool IsActive(const agi::Context *c) override {
return !wxGetApp().frame->IsAudioShown() && wxGetApp().frame->IsVideoShown(); return !c->frame->IsAudioShown() && c->frame->IsVideoShown();
} }
}; };
@ -152,7 +152,7 @@ struct app_exit final : public Command {
STR_HELP("Exit the application") STR_HELP("Exit the application")
void operator()(agi::Context *c) override { 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); 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) { if (result == wxYES) {
// Restart Aegisub // Restart Aegisub
if (wxGetApp().frame->Close()) { if (c->frame->Close()) {
RestartAegisub(); RestartAegisub();
} }
} }
@ -200,7 +200,7 @@ struct app_new_window final : public Command {
STR_DISP("New Window") STR_DISP("New Window")
STR_HELP("Open a new application window") STR_HELP("Open a new application window")
void operator()(agi::Context *) override { void operator()(agi::Context *c) override {
RestartAegisub(); RestartAegisub();
} }
}; };
@ -229,11 +229,11 @@ struct app_toggle_global_hotkeys final : public Command {
STR_HELP("Toggle global hotkey overrides (Medusa Mode)") STR_HELP("Toggle global hotkey overrides (Medusa Mode)")
CMD_TYPE(COMMAND_TOGGLE) 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(); 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"); agi::OptionValue *opt = OPT_SET("Audio/Medusa Timing Hotkeys");
opt->SetBool(!opt->GetBool()); opt->SetBool(!opt->GetBool());
} }
@ -244,17 +244,17 @@ struct app_toggle_toolbar final : public Command {
STR_HELP("Toggle the main toolbar") STR_HELP("Toggle the main toolbar")
CMD_TYPE(COMMAND_DYNAMIC_NAME) 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() ? return OPT_GET("App/Show Toolbar")->GetBool() ?
_("Hide Toolbar") : _("Hide Toolbar") :
_("Show Toolbar"); _("Show Toolbar");
} }
wxString StrDisplay(const agi::Context *) const override { wxString StrDisplay(const agi::Context *c) const override {
return StrMenu(nullptr); return StrMenu(nullptr);
} }
void operator()(agi::Context *) override { void operator()(agi::Context *c) override {
agi::OptionValue *opt = OPT_SET("App/Show Toolbar"); agi::OptionValue *opt = OPT_SET("App/Show Toolbar");
opt->SetBool(!opt->GetBool()); opt->SetBool(!opt->GetBool());
} }
@ -266,7 +266,7 @@ struct app_updates final : public Command {
STR_DISP("Check for Updates") STR_DISP("Check for Updates")
STR_HELP("Check to see if there is a new version of Aegisub available") 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); PerformVersionCheck(true);
} }
}; };

View File

@ -58,7 +58,7 @@ struct reload_all final : public Command {
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
wxGetApp().global_scripts->Reload(); wxGetApp().global_scripts->Reload();
c->local_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 { void operator()(agi::Context *c) override {
wxGetApp().global_scripts->Reload(); wxGetApp().global_scripts->Reload();
StatusTimeout(_("Reloaded autoload Automation scripts")); c->frame->StatusTimeout(_("Reloaded autoload Automation scripts"));
} }
}; };

View File

@ -37,6 +37,7 @@
#include "../ass_file.h" #include "../ass_file.h"
#include "../audio_controller.h" #include "../audio_controller.h"
#include "../audio_timing.h" #include "../audio_timing.h"
#include "../frame_main.h"
#include "../include/aegisub/context.h" #include "../include/aegisub/context.h"
#include "../libresrc/libresrc.h" #include "../libresrc/libresrc.h"
#include "../options.h" #include "../options.h"
@ -257,7 +258,7 @@ struct grid_tag_cycle_hiding final : public Command {
STR_DISP("Cycle Tag Hiding Mode") STR_DISP("Cycle Tag Hiding Mode")
STR_HELP("Cycle through tag hiding modes") 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(); int tagMode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt();
// Cycle to next // 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 == 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 == 1) message = _("ASS Override Tag mode set to simplify tags.");
if (tagMode == 2) message = _("ASS Override Tag mode set to hide tags."); if (tagMode == 2) message = _("ASS Override Tag mode set to hide tags.");
StatusTimeout(message,10000); c->frame->StatusTimeout(message,10000);
// Set option // Set option
OPT_SET("Subtitle/Grid/Hide Overrides")->SetInt(tagMode); OPT_SET("Subtitle/Grid/Hide Overrides")->SetInt(tagMode);

View File

@ -99,7 +99,7 @@ struct video_aspect_cinematic final : public validator_video_loaded {
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
c->videoController->Stop(); c->videoController->Stop();
c->videoController->SetAspectRatio(AspectRatio::Cinematic); 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); wxMessageBox(_("Invalid value! Aspect ratio must be between 0.5 and 5.0."),_("Invalid Aspect Ratio"),wxOK | wxICON_ERROR | wxCENTER);
else { else {
c->videoController->SetAspectRatio(numval); 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 { void operator()(agi::Context *c) override {
c->videoController->Stop(); c->videoController->Stop();
c->videoController->SetAspectRatio(AspectRatio::Default); 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 { void operator()(agi::Context *c) override {
c->videoController->Stop(); c->videoController->Stop();
c->videoController->SetAspectRatio(AspectRatio::Fullscreen); 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 { void operator()(agi::Context *c) override {
c->videoController->Stop(); c->videoController->Stop();
c->videoController->SetAspectRatio(AspectRatio::Widescreen); 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); if (it == end(providers)) it = begin(providers);
OPT_SET("Subtitle/Provider")->SetString(*it); 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);
} }
}; };

View File

@ -26,6 +26,7 @@
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_file.h" #include "ass_file.h"
#include "compat.h" #include "compat.h"
#include "frame_main.h"
#include "help_button.h" #include "help_button.h"
#include "include/aegisub/context.h" #include "include/aegisub/context.h"
#include "libresrc/libresrc.h" #include "libresrc/libresrc.h"
@ -223,7 +224,7 @@ void DialogSelection::Process(wxCommandEvent&) {
if (count == 0) if (count == 0)
wxMessageBox(message, _("Selection"), wxOK | wxCENTER, this); wxMessageBox(message, _("Selection"), wxOK | wxCENTER, this);
else else
StatusTimeout(message); con->frame->StatusTimeout(message);
AssDialogue *new_active = con->selectionController->GetActiveLine(); AssDialogue *new_active = con->selectionController->GetActiveLine();
if (new_sel.size() && !new_sel.count(new_active)) if (new_sel.size() && !new_sel.count(new_active))

View File

@ -38,12 +38,12 @@
#include "ffmpegsource_common.h" #include "ffmpegsource_common.h"
#include "compat.h" #include "compat.h"
#include "dialog_progress.h"
#include "frame_main.h" #include "frame_main.h"
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
#include "utils.h" #include "utils.h"
#include <libaegisub/background_runner.h>
#include <libaegisub/fs.h> #include <libaegisub/fs.h>
#include <libaegisub/path.h> #include <libaegisub/path.h>
#include <libaegisub/log.h> #include <libaegisub/log.h>
@ -66,8 +66,9 @@ static void deinit_com(bool) {
static void deinit_com(bool) { } static void deinit_com(bool) { }
#endif #endif
FFmpegSourceProvider::FFmpegSourceProvider() FFmpegSourceProvider::FFmpegSourceProvider(agi::BackgroundRunner *br)
: COMInited(false, deinit_com) : COMInited(false, deinit_com)
, br(br)
{ {
#ifdef _WIN32 #ifdef _WIN32
HRESULT res = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 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 Indexer A pointer to the indexer object representing the file to be indexed
/// @param CacheName The filename of the output index file /// @param CacheName The filename of the output index file
/// @param Trackmask A binary mask of the track numbers to index /// @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) { FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, agi::fs::path const& CacheName, int Trackmask, FFMS_IndexErrorHandling IndexEH) {
char FFMSErrMsg[1024]; char FFMSErrMsg[1024];
FFMS_ErrorInfo ErrInfo; FFMS_ErrorInfo ErrInfo;
@ -97,12 +95,11 @@ FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, agi::fs::pat
ErrInfo.SubType = FFMS_ERROR_SUCCESS; ErrInfo.SubType = FFMS_ERROR_SUCCESS;
std::string MsgString; std::string MsgString;
// set up progress dialog callback
DialogProgress Progress(wxGetApp().frame, _("Indexing"), _("Reading timecodes and frame/sample data"));
// index all audio tracks // index all audio tracks
FFMS_Index *Index; 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 { struct progress {
agi::ProgressSink *ps; agi::ProgressSink *ps;
int calls; int calls;

View File

@ -40,6 +40,8 @@
#include <libaegisub/fs_fwd.h> #include <libaegisub/fs_fwd.h>
#include <libaegisub/scoped_ptr.h> #include <libaegisub/scoped_ptr.h>
namespace agi { class BackgroundRunner; }
/// Index all tracks /// Index all tracks
#define FFMS_TRACKMASK_ALL -1 #define FFMS_TRACKMASK_ALL -1
/// Index no tracks /// Index no tracks
@ -50,9 +52,10 @@
class FFmpegSourceProvider { class FFmpegSourceProvider {
friend class FFmpegSourceCacheCleaner; friend class FFmpegSourceCacheCleaner;
agi::scoped_holder<bool> COMInited; ///< COM initialization state agi::scoped_holder<bool> COMInited; ///< COM initialization state
agi::BackgroundRunner *br;
public: public:
FFmpegSourceProvider(); FFmpegSourceProvider(agi::BackgroundRunner *br);
/// Logging level constants from avutil/log.h /// Logging level constants from avutil/log.h
enum FFMS_LogLevel { enum FFMS_LogLevel {

View File

@ -229,6 +229,7 @@ FrameMain::FrameMain()
StartupLog("Initializing context frames"); StartupLog("Initializing context frames");
context->parent = this; context->parent = this;
context->frame = this;
context->previousFocus = nullptr; context->previousFocus = nullptr;
StartupLog("Install PNG handler"); StartupLog("Install PNG handler");

View File

@ -49,7 +49,7 @@ class VideoBox;
namespace agi { struct Context; class OptionValue; } namespace agi { struct Context; class OptionValue; }
class FrameMain: public wxFrame { class FrameMain : public wxFrame {
friend class AegisubApp; friend class AegisubApp;
friend class AegisubFileDropTarget; friend class AegisubFileDropTarget;

View File

@ -40,6 +40,7 @@
#include <vector> #include <vector>
class AudioProvider; class AudioProvider;
class wxWindow;
class AudioPlayer { class AudioPlayer {
protected: protected:
@ -62,5 +63,5 @@ public:
struct AudioPlayerFactory { struct AudioPlayerFactory {
static std::vector<std::string> GetClasses(); static std::vector<std::string> GetClasses();
static std::unique_ptr<AudioPlayer> GetAudioPlayer(AudioProvider *provider); static std::unique_ptr<AudioPlayer> GetAudioPlayer(AudioProvider *provider, wxWindow *window);
}; };

View File

@ -88,12 +88,14 @@ public:
} }
}; };
namespace agi { class BackgroundRunner; }
struct AudioProviderFactory { struct AudioProviderFactory {
static std::vector<std::string> GetClasses(); static std::vector<std::string> GetClasses();
/// Get a provider for the file /// Get a provider for the file
/// @param filename URI to open /// @param filename URI to open
static std::unique_ptr<AudioProvider> GetProvider(agi::fs::path const& filename); static std::unique_ptr<AudioProvider> GetProvider(agi::fs::path const& filename, agi::BackgroundRunner *br);
}; };
DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception) DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception)

View File

@ -4,6 +4,7 @@ class AudioController;
class AssDialogue; class AssDialogue;
class AudioKaraoke; class AudioKaraoke;
class DialogManager; class DialogManager;
class FrameMain;
class SearchReplaceEngine; class SearchReplaceEngine;
class InitialLineState; class InitialLineState;
class SelectionController; class SelectionController;
@ -41,8 +42,9 @@ struct Context {
// Views (i.e. things that should eventually not be here at all) // Views (i.e. things that should eventually not be here at all)
AudioBox *audioBox; AudioBox *audioBox;
AudioKaraoke *karaoke; AudioKaraoke *karaoke;
DialogManager *dialog;
BaseGrid *subsGrid; BaseGrid *subsGrid;
DialogManager *dialog;
FrameMain *frame;
VideoDisplay *videoDisplay; VideoDisplay *videoDisplay;
}; };

View File

@ -48,7 +48,9 @@ public:
virtual void DrawSubtitles(VideoFrame &dst, double time)=0; virtual void DrawSubtitles(VideoFrame &dst, double time)=0;
}; };
namespace agi { class BackgroundRunner; }
struct SubtitlesProviderFactory { struct SubtitlesProviderFactory {
static std::unique_ptr<SubtitlesProvider> GetProvider(); static std::unique_ptr<SubtitlesProvider> GetProvider(agi::BackgroundRunner *br);
static std::vector<std::string> GetClasses(); static std::vector<std::string> GetClasses();
}; };

View File

@ -44,7 +44,9 @@ class FrameMain;
namespace Automation4 { class AutoloadScriptManager; } namespace Automation4 { class AutoloadScriptManager; }
class AegisubApp: public wxApp { class AegisubApp : public wxApp {
friend class FrameMain;
bool OnInit() override; bool OnInit() override;
int OnExit() override; int OnExit() override;
int OnRun() override; int OnRun() override;
@ -65,10 +67,10 @@ class AegisubApp: public wxApp {
// our ticket to catch exceptions happening in event handlers. // our ticket to catch exceptions happening in event handlers.
void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const override; void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const override;
FrameMain *frame;
public: public:
AegisubApp(); AegisubApp();
AegisubLocale locale; AegisubLocale locale;
FrameMain *frame;
Automation4::AutoloadScriptManager *global_scripts; Automation4::AutoloadScriptManager *global_scripts;
// Apple events // Apple events

View File

@ -26,6 +26,7 @@
#include "charset_detect.h" #include "charset_detect.h"
#include "compat.h" #include "compat.h"
#include "command/command.h" #include "command/command.h"
#include "Frame_main.h"
#include "include/aegisub/context.h" #include "include/aegisub/context.h"
#include "options.h" #include "options.h"
#include "selection_controller.h" #include "selection_controller.h"
@ -138,13 +139,13 @@ SubsController::SubsController(agi::Context *context)
try { try {
auto fn = AutoSave(); auto fn = AutoSave();
if (!fn.empty()) 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) { 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 (...) { catch (...) {
StatusTimeout("Unhandled exception when attempting to autosave file."); context->frame->StatusTimeout("Unhandled exception when attempting to autosave file.");
} }
}); });
} }

View File

@ -38,6 +38,7 @@
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_style.h" #include "ass_style.h"
#include "dialog_progress.h"
#include "subs_preview.h" #include "subs_preview.h"
#include "include/aegisub/subtitles_provider.h" #include "include/aegisub/subtitles_provider.h"
#include "video_frame.h" #include "video_frame.h"
@ -51,7 +52,7 @@
SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle, agi::Color col) SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle, agi::Color col)
: wxWindow(parent, -1, wxDefaultPosition, size, winStyle) : wxWindow(parent, -1, wxDefaultPosition, size, winStyle)
, style(new AssStyle) , style(new AssStyle)
, back_color(std::move(col)) , back_color(col)
, sub_file(agi::util::make_unique<AssFile>()) , sub_file(agi::util::make_unique<AssFile>())
, line(new AssDialogue) , line(new AssDialogue)
{ {
@ -131,8 +132,10 @@ void SubtitlesPreview::OnSize(wxSizeEvent &evt) {
bmp = agi::util::make_unique<wxBitmap>(w, h, -1); bmp = agi::util::make_unique<wxBitmap>(w, h, -1);
vid.reset(new DummyVideoProvider(0.0, 10, w, h, back_color, true)); vid.reset(new DummyVideoProvider(0.0, 10, w, h, back_color, true));
try { try {
if (!provider) if (!provider) {
provider = SubtitlesProviderFactory::GetProvider(); DialogProgress progress(this);
provider = SubtitlesProviderFactory::GetProvider(&progress);
}
} }
catch (...) { catch (...) {
wxMessageBox( wxMessageBox(

View File

@ -27,7 +27,7 @@ namespace {
struct factory { struct factory {
std::string name; std::string name;
std::string subtype; std::string subtype;
std::unique_ptr<SubtitlesProvider> (*create)(std::string const& subtype); std::unique_ptr<SubtitlesProvider> (*create)(std::string const& subtype, agi::BackgroundRunner *br);
bool hidden; bool hidden;
}; };
@ -47,14 +47,14 @@ std::vector<std::string> SubtitlesProviderFactory::GetClasses() {
return ::GetClasses(factories()); return ::GetClasses(factories());
} }
std::unique_ptr<SubtitlesProvider> SubtitlesProviderFactory::GetProvider() { std::unique_ptr<SubtitlesProvider> SubtitlesProviderFactory::GetProvider(agi::BackgroundRunner *br) {
auto preferred = OPT_GET("Subtitle/Provider")->GetString(); auto preferred = OPT_GET("Subtitle/Provider")->GetString();
auto sorted = GetSorted(factories(), preferred); auto sorted = GetSorted(factories(), preferred);
std::string error; std::string error;
for (auto factory : sorted) { for (auto factory : sorted) {
try { try {
auto provider = factory->create(factory->subtype); auto provider = factory->create(factory->subtype, br);
if (provider) return provider; if (provider) return provider;
} }
catch (agi::UserCancelException const&) { throw; } catch (agi::UserCancelException const&) { throw; }

View File

@ -139,7 +139,7 @@ std::vector<std::string> List() {
return final; return final;
} }
std::unique_ptr<SubtitlesProvider> Create(std::string const& name) { std::unique_ptr<SubtitlesProvider> Create(std::string const& name, agi::BackgroundRunner *) {
return agi::util::make_unique<CSRISubtitlesProvider>(name); return agi::util::make_unique<CSRISubtitlesProvider>(name);
} }
} }

View File

@ -19,8 +19,9 @@
#include <vector> #include <vector>
class SubtitlesProvider; class SubtitlesProvider;
namespace agi { class BackgroundRunner; }
namespace csri { namespace csri {
std::vector<std::string> List(); std::vector<std::string> List();
std::unique_ptr<SubtitlesProvider> Create(std::string const& subtype); std::unique_ptr<SubtitlesProvider> Create(std::string const& subtype, agi::BackgroundRunner *br);
} }

View File

@ -40,13 +40,11 @@
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_style.h" #include "ass_style.h"
#include "dialog_progress.h" #include "compat.h"
#include "frame_main.h"
#include "include/aegisub/subtitles_provider.h" #include "include/aegisub/subtitles_provider.h"
#include "main.h"
#include "utils.h"
#include "video_frame.h" #include "video_frame.h"
#include <libaegisub/background_runner.h>
#include <libaegisub/dispatch.h> #include <libaegisub/dispatch.h>
#include <libaegisub/log.h> #include <libaegisub/log.h>
#include <libaegisub/util.h> #include <libaegisub/util.h>
@ -95,14 +93,14 @@ class LibassSubtitlesProvider final : public SubtitlesProvider {
ASS_Track* ass_track = nullptr; ASS_Track* ass_track = nullptr;
public: public:
LibassSubtitlesProvider(); LibassSubtitlesProvider(agi::BackgroundRunner *br);
~LibassSubtitlesProvider(); ~LibassSubtitlesProvider();
void LoadSubtitles(AssFile *subs) override; void LoadSubtitles(AssFile *subs) override;
void DrawSubtitles(VideoFrame &dst, double time) override; void DrawSubtitles(VideoFrame &dst, double time) override;
}; };
LibassSubtitlesProvider::LibassSubtitlesProvider() { LibassSubtitlesProvider::LibassSubtitlesProvider(agi::BackgroundRunner *br) {
auto done = std::make_shared<bool>(false); auto done = std::make_shared<bool>(false);
auto renderer = std::make_shared<ASS_Renderer*>(nullptr); auto renderer = std::make_shared<ASS_Renderer*>(nullptr);
cache_queue->Async([=]{ cache_queue->Async([=]{
@ -115,8 +113,9 @@ LibassSubtitlesProvider::LibassSubtitlesProvider() {
*renderer = ass_renderer; *renderer = ass_renderer;
}); });
DialogProgress progress(wxGetApp().frame, _("Updating font index"), _("This may take several minutes")); br->Run([=](agi::ProgressSink *ps) {
progress.Run([=](agi::ProgressSink *ps) { ps->SetTitle(from_wx(_("Updating font index")));
ps->SetMessage(from_wx(_("This may take several minutes")));
ps->SetIndeterminate(); ps->SetIndeterminate();
while (!*done && !ps->IsCancelled()) while (!*done && !ps->IsCancelled())
agi::util::sleep_for(250); agi::util::sleep_for(250);
@ -205,8 +204,8 @@ void LibassSubtitlesProvider::DrawSubtitles(VideoFrame &frame,double time) {
} }
namespace libass { namespace libass {
std::unique_ptr<SubtitlesProvider> Create(std::string const&) { std::unique_ptr<SubtitlesProvider> Create(std::string const&, agi::BackgroundRunner *br) {
return agi::util::make_unique<LibassSubtitlesProvider>(); return agi::util::make_unique<LibassSubtitlesProvider>(br);
} }
void CacheFonts() { void CacheFonts() {

View File

@ -18,8 +18,9 @@
#include <string> #include <string>
class SubtitlesProvider; class SubtitlesProvider;
namespace agi { class BackgroundRunner; }
namespace libass { namespace libass {
std::unique_ptr<SubtitlesProvider> Create(std::string const&); std::unique_ptr<SubtitlesProvider> Create(std::string const&, agi::BackgroundRunner *br);
void CacheFonts(); void CacheFonts();
} }

View File

@ -99,20 +99,20 @@ std::shared_ptr<VideoFrame> ThreadedFrameSource::ProcFrame(int frame_number, dou
return frame; return frame;
} }
static std::unique_ptr<SubtitlesProvider> get_subs_provider(wxEvtHandler *parent) { static std::unique_ptr<SubtitlesProvider> get_subs_provider(wxEvtHandler *evt_handler, agi::BackgroundRunner *br) {
try { try {
return SubtitlesProviderFactory::GetProvider(); return SubtitlesProviderFactory::GetProvider(br);
} }
catch (std::string const& err) { catch (std::string const& err) {
parent->AddPendingEvent(SubtitlesProviderErrorEvent(err)); evt_handler->AddPendingEvent(SubtitlesProviderErrorEvent(err));
return nullptr; 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()) : worker(agi::dispatch::Create())
, subs_provider(get_subs_provider(parent)) , subs_provider(get_subs_provider(parent, br))
, video_provider(VideoProviderFactory::GetProvider(video_filename, colormatrix)) , video_provider(VideoProviderFactory::GetProvider(video_filename, colormatrix, br))
, parent(parent) , parent(parent)
{ {
} }

View File

@ -35,7 +35,10 @@ class SubtitlesProvider;
class VideoProvider; class VideoProvider;
class VideoProviderError; class VideoProviderError;
struct VideoFrame; struct VideoFrame;
namespace agi { namespace dispatch { class Queue; } } namespace agi {
class BackgroundRunner;
namespace dispatch { class Queue; }
}
/// @class ThreadedFrameSource /// @class ThreadedFrameSource
/// @brief An asynchronous video decoding and subtitle rendering wrapper /// @brief An asynchronous video decoding and subtitle rendering wrapper
@ -106,7 +109,7 @@ public:
/// @brief Constructor /// @brief Constructor
/// @param videoFileName File to open /// @param videoFileName File to open
/// @param parent Event handler to send FrameReady events to /// @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(); ~ThreadedFrameSource();
}; };

View File

@ -97,10 +97,6 @@ std::string float_to_string(double val) {
return s; return s;
} }
void StatusTimeout(wxString const& msg, int ms) {
wxGetApp().frame->StatusTimeout(msg, ms);
}
int SmallestPowerOf2(int x) { int SmallestPowerOf2(int x) {
x--; x--;
x |= (x >> 1); x |= (x >> 1);

View File

@ -55,8 +55,6 @@ wxString PrettySize(int bytes);
std::string float_to_string(double val); 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 /// @brief Get the smallest power of two that is greater or equal to x
/// ///
/// Algorithm from http://bob.allegronetwork.com/prog/tricks.html /// Algorithm from http://bob.allegronetwork.com/prog/tricks.html

View File

@ -41,6 +41,7 @@
#include "ass_time.h" #include "ass_time.h"
#include "audio_controller.h" #include "audio_controller.h"
#include "compat.h" #include "compat.h"
#include "dialog_progress.h"
#include "include/aegisub/context.h" #include "include/aegisub/context.h"
#include "include/aegisub/video_provider.h" #include "include/aegisub/video_provider.h"
#include "mkv_wrap.h" #include "mkv_wrap.h"
@ -122,8 +123,9 @@ void VideoContext::SetVideo(const agi::fs::path &filename) {
bool commit_subs = false; bool commit_subs = false;
try { try {
DialogProgress progress(context->parent);
auto old_matrix = context->ass->GetScriptInfo("YCbCr Matrix"); 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_provider = provider->GetVideoProvider();
video_filename = filename; video_filename = filename;

View File

@ -310,7 +310,8 @@ std::shared_ptr<VideoFrame> AvisynthVideoProvider::GetFrame(int n) {
} }
} }
std::unique_ptr<VideoProvider> CreateAvisynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix) { namespace agi { class BackgroundRunner; }
std::unique_ptr<VideoProvider> CreateAvisynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *) {
return agi::util::make_unique<AvisynthVideoProvider>(path, colormatrix); return agi::util::make_unique<AvisynthVideoProvider>(path, colormatrix);
} }
#endif // HAVE_AVISYNTH #endif // HAVE_AVISYNTH

View File

@ -97,7 +97,8 @@ std::shared_ptr<VideoFrame> DummyVideoProvider::GetFrame(int) {
return std::make_shared<VideoFrame>(data.data(), width, height, width * 4, false); return std::make_shared<VideoFrame>(data.data(), width, height, width * 4, false);
} }
std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const& filename, std::string const&) { namespace agi { class BackgroundRunner; }
std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const& filename, std::string const&, agi::BackgroundRunner *) {
if (!boost::starts_with(filename.string(), "?dummy")) if (!boost::starts_with(filename.string(), "?dummy"))
return {}; return {};
@ -123,4 +124,4 @@ std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const& fil
bool pattern = toks[i] == "c"; bool pattern = toks[i] == "c";
return agi::util::make_unique<DummyVideoProvider>(fps, frames, width, height, agi::Color(red, green, blue), pattern); return agi::util::make_unique<DummyVideoProvider>(fps, frames, width, height, agi::Color(red, green, blue), pattern);
} }

View File

@ -71,7 +71,7 @@ class FFmpegSourceVideoProvider final : public VideoProvider, FFmpegSourceProvid
void LoadVideo(agi::fs::path const& filename, std::string const& colormatrix); void LoadVideo(agi::fs::path const& filename, std::string const& colormatrix);
public: 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<VideoFrame> GetFrame(int n) override; std::shared_ptr<VideoFrame> 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 FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) try
: VideoSource(nullptr, FFMS_DestroyVideoSource) : FFmpegSourceProvider(br)
, VideoSource(nullptr, FFMS_DestroyVideoSource)
{ {
ErrInfo.Buffer = FFMSErrMsg; ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.BufferSize = sizeof(FFMSErrMsg);
@ -285,8 +286,8 @@ std::shared_ptr<VideoFrame> FFmpegSourceVideoProvider::GetFrame(int n) {
} }
} }
std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const& path, std::string const& colormatrix) { std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *br) {
return agi::util::make_unique<FFmpegSourceVideoProvider>(path, colormatrix); return agi::util::make_unique<FFmpegSourceVideoProvider>(path, colormatrix, br);
} }
#endif /* WITH_FFMS2 */ #endif /* WITH_FFMS2 */

View File

@ -28,17 +28,17 @@
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const&, std::string const&); std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *);
std::unique_ptr<VideoProvider> CreateYUV4MPEGVideoProvider(agi::fs::path const&, std::string const&); std::unique_ptr<VideoProvider> CreateYUV4MPEGVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *);
std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const&, std::string const&); std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *);
std::unique_ptr<VideoProvider> CreateAvisynthVideoProvider(agi::fs::path const&, std::string const&); std::unique_ptr<VideoProvider> CreateAvisynthVideoProvider(agi::fs::path const&, std::string const&, agi::BackgroundRunner *);
std::unique_ptr<VideoProvider> CreateCacheVideoProvider(std::unique_ptr<VideoProvider>); std::unique_ptr<VideoProvider> CreateCacheVideoProvider(std::unique_ptr<VideoProvider>);
namespace { namespace {
struct factory { struct factory {
const char *name; const char *name;
std::unique_ptr<VideoProvider> (*create)(agi::fs::path const&, std::string const&); std::unique_ptr<VideoProvider> (*create)(agi::fs::path const&, std::string const&, agi::BackgroundRunner *);
bool hidden; bool hidden;
}; };
@ -58,7 +58,7 @@ std::vector<std::string> VideoProviderFactory::GetClasses() {
return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers))); return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers)));
} }
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix) { std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) {
auto preferred = OPT_GET("Video/Provider")->GetString(); auto preferred = OPT_GET("Video/Provider")->GetString();
auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred);
@ -70,7 +70,7 @@ std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path c
for (auto factory : sorted) { for (auto factory : sorted) {
std::string err; std::string err;
try { try {
auto provider = factory->create(filename, colormatrix); auto provider = factory->create(filename, colormatrix, br);
if (!provider) continue; if (!provider) continue;
LOG_I("manager/video/provider") << factory->name << ": opened " << filename; LOG_I("manager/video/provider") << factory->name << ": opened " << filename;
return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider); return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider);

View File

@ -21,8 +21,9 @@
#include <vector> #include <vector>
class VideoProvider; class VideoProvider;
namespace agi { class BackgroundRunner; }
struct VideoProviderFactory { struct VideoProviderFactory {
static std::vector<std::string> GetClasses(); static std::vector<std::string> GetClasses();
static std::unique_ptr<VideoProvider> GetProvider(agi::fs::path const& video_file, std::string const& colormatrix); static std::unique_ptr<VideoProvider> GetProvider(agi::fs::path const& video_file, std::string const& colormatrix, agi::BackgroundRunner *br);
}; };

View File

@ -448,6 +448,7 @@ std::shared_ptr<VideoFrame> YUV4MPEGVideoProvider::GetFrame(int n) {
} }
} }
std::unique_ptr<VideoProvider> CreateYUV4MPEGVideoProvider(agi::fs::path const& path, std::string const&) { namespace agi { class BackgroundRunner; }
std::unique_ptr<VideoProvider> CreateYUV4MPEGVideoProvider(agi::fs::path const& path, std::string const&, agi::BackgroundRunner *) {
return agi::util::make_unique<YUV4MPEGVideoProvider>(path); return agi::util::make_unique<YUV4MPEGVideoProvider>(path);
} }