Eliminate all uses of FrameMain via the global app object
This commit is contained in:
parent
e596de03c7
commit
39626db787
49 changed files with 198 additions and 195 deletions
|
@ -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 (...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue