1
0
Fork 0

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 "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<AudioProvider> 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 (...)
{

View File

@ -47,18 +47,18 @@ AudioPlayer::AudioPlayer(AudioProvider *provider)
{
}
std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *providers);
std::unique_ptr<AudioPlayer> CreateAlsaPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateOpenALPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreatePortAudioPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreatePulseAudioPlayer(AudioProvider *providers, wxWindow *window);
std::unique_ptr<AudioPlayer> CreateOSSPlayer(AudioProvider *providers, wxWindow *window);
namespace {
struct factory {
const char *name;
std::unique_ptr<AudioPlayer> (*create)(AudioProvider *);
std::unique_ptr<AudioPlayer> (*create)(AudioProvider *, wxWindow *window);
bool hidden;
};
@ -89,7 +89,7 @@ std::vector<std::string> AudioPlayerFactory::GetClasses() {
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)
throw agi::NoAudioPlayersError("No audio players are available.", nullptr);
@ -99,7 +99,7 @@ std::unique_ptr<AudioPlayer> 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";

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);
}

View File

@ -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<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *provider) {
return agi::util::make_unique<DirectSoundPlayer>(provider);
std::unique_ptr<AudioPlayer> CreateDirectSoundPlayer(AudioProvider *provider, wxWindow *parent) {
return agi::util::make_unique<DirectSoundPlayer>(provider, parent);
}
#endif // WITH_DIRECTSOUND

View File

@ -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<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()
{
struct ReleaseCOMObject {
void operator()(IUnknown *obj) {
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
struct Win32KernelHandle final : public agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> {
/// @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<IDirectSound8> 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<IDirectSound8> 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<AegisubApp*>(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<IDirectSoundBuffer8> 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<IDirectSoundBuffer8> 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<DirectSoundPlayer2Thread>(provider, WantedLatency, BufferLength);
thread = agi::util::make_unique<DirectSoundPlayer2Thread>(provider, WantedLatency, BufferLength, parent);
}
catch (const char *msg)
{
@ -962,8 +941,8 @@ void DirectSoundPlayer2::SetVolume(double vol)
}
}
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *provider) {
return agi::util::make_unique<DirectSoundPlayer2>(provider);
std::unique_ptr<AudioPlayer> CreateDirectSound2Player(AudioProvider *provider, wxWindow *parent) {
return agi::util::make_unique<DirectSoundPlayer2>(provider, parent);
}
#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);
}

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);
}

View File

@ -283,7 +283,7 @@ bool PortAudioPlayer::IsPlaying() {
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);
}

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);
}
#endif // WITH_LIBPULSE

View File

@ -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 <libaegisub/background_runner.h>
#include <libaegisub/fs.h>
#include <libaegisub/log.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> CreatePCMAudioProvider(agi::fs::path const& filename);
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& filename);
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(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, agi::BackgroundRunner *);
std::unique_ptr<AudioProvider> CreateAvisynthAudioProvider(agi::fs::path const& filename, agi::BackgroundRunner *);
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> CreateLockAudioProvider(std::unique_ptr<AudioProvider> source_provider);
@ -117,7 +117,7 @@ std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvi
namespace {
struct factory {
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;
};
@ -137,7 +137,7 @@ std::vector<std::string> AudioProviderFactory::GetClasses() {
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 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) {
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<AudioProvider> 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);
}

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);
}
#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:"))
return {};
return agi::util::make_unique<DummyAudioProvider>(file);

View File

@ -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<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& file) {
return agi::util::make_unique<FFmpegSourceAudioProvider>(file);
std::unique_ptr<AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *br) {
return agi::util::make_unique<FFmpegSourceAudioProvider>(file, br);
}
#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);
br->Run([&] (agi::ProgressSink *ps) {
ps->SetTitle(from_wx(_("Load audio")));
ps->SetMessage(from_wx(_("Reading to Hard Disk cache")));
int64_t block = 65536;

View File

@ -44,4 +44,4 @@ public:
std::unique_ptr<AudioProvider> CreateLockAudioProvider(std::unique_ptr<AudioProvider> 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;
std::string msg;

View File

@ -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();

View File

@ -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<DialogDetachedVideo>();
}
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<DialogDetachedVideo>();
}
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);
}
};

View File

@ -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"));
}
};

View File

@ -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);

View File

@ -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);
}
};

View File

@ -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))

View File

@ -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 <libaegisub/background_runner.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/log.h>
@ -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;

View File

@ -40,6 +40,8 @@
#include <libaegisub/fs_fwd.h>
#include <libaegisub/scoped_ptr.h>
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<bool> COMInited; ///< COM initialization state
agi::BackgroundRunner *br;
public:
FFmpegSourceProvider();
FFmpegSourceProvider(agi::BackgroundRunner *br);
/// Logging level constants from avutil/log.h
enum FFMS_LogLevel {

View File

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

View File

@ -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;

View File

@ -40,6 +40,7 @@
#include <vector>
class AudioProvider;
class wxWindow;
class AudioPlayer {
protected:
@ -62,5 +63,5 @@ public:
struct AudioPlayerFactory {
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 {
static std::vector<std::string> GetClasses();
/// Get a provider for the file
/// @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)

View File

@ -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;
};

View File

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

View File

@ -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

View File

@ -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.");
}
});
}

View File

@ -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<AssFile>())
, line(new AssDialogue)
{
@ -131,8 +132,10 @@ void SubtitlesPreview::OnSize(wxSizeEvent &evt) {
bmp = agi::util::make_unique<wxBitmap>(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(

View File

@ -27,7 +27,7 @@ namespace {
struct factory {
std::string name;
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;
};
@ -47,14 +47,14 @@ std::vector<std::string> SubtitlesProviderFactory::GetClasses() {
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 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; }

View File

@ -139,7 +139,7 @@ std::vector<std::string> List() {
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);
}
}

View File

@ -19,8 +19,9 @@
#include <vector>
class SubtitlesProvider;
namespace agi { class BackgroundRunner; }
namespace csri {
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_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 <libaegisub/background_runner.h>
#include <libaegisub/dispatch.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
@ -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<bool>(false);
auto renderer = std::make_shared<ASS_Renderer*>(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<SubtitlesProvider> Create(std::string const&) {
return agi::util::make_unique<LibassSubtitlesProvider>();
std::unique_ptr<SubtitlesProvider> Create(std::string const&, agi::BackgroundRunner *br) {
return agi::util::make_unique<LibassSubtitlesProvider>(br);
}
void CacheFonts() {

View File

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

View File

@ -99,20 +99,20 @@ std::shared_ptr<VideoFrame> ThreadedFrameSource::ProcFrame(int frame_number, dou
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 {
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)
{
}

View File

@ -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();
};

View File

@ -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);

View File

@ -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

View File

@ -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;

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);
}
#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);
}
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"))
return {};
@ -123,4 +124,4 @@ std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const& fil
bool pattern = toks[i] == "c";
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);
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;
@ -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<VideoFrame> FFmpegSourceVideoProvider::GetFrame(int n) {
}
}
std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const& path, std::string const& colormatrix) {
return agi::util::make_unique<FFmpegSourceVideoProvider>(path, 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, br);
}
#endif /* WITH_FFMS2 */

View File

@ -28,17 +28,17 @@
#include <boost/range/iterator_range.hpp>
std::unique_ptr<VideoProvider> CreateDummyVideoProvider(agi::fs::path const&, std::string const&);
std::unique_ptr<VideoProvider> CreateYUV4MPEGVideoProvider(agi::fs::path const&, std::string const&);
std::unique_ptr<VideoProvider> CreateFFmpegSourceVideoProvider(agi::fs::path const&, std::string const&);
std::unique_ptr<VideoProvider> CreateAvisynthVideoProvider(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&, agi::BackgroundRunner *);
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&, agi::BackgroundRunner *);
std::unique_ptr<VideoProvider> CreateCacheVideoProvider(std::unique_ptr<VideoProvider>);
namespace {
struct factory {
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;
};
@ -58,7 +58,7 @@ std::vector<std::string> VideoProviderFactory::GetClasses() {
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 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) {
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);

View File

@ -21,8 +21,9 @@
#include <vector>
class VideoProvider;
namespace agi { class BackgroundRunner; }
struct VideoProviderFactory {
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);
}