From c10e9e3a5b13f2b3acbfe37244a5a62bfa044515 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Mon, 2 Aug 2010 06:32:01 +0000 Subject: [PATCH] Make video and audio providers throw typed exceptions. Don't display error messages and try other providers when the user cancels loading a file. Remove files from the MRU lists if they can't be found. Closes #717. Originally committed to SVN as r4717. --- aegisub/src/aegisub_endian.h | 24 +- aegisub/src/agi_pre.cpp | 2 - aegisub/src/agi_pre.h | 2 +- aegisub/src/ass_export_filter.h | 15 - aegisub/src/ass_exporter.cpp | 25 -- aegisub/src/ass_file.cpp | 10 +- aegisub/src/audio_display.cpp | 10 + aegisub/src/audio_karaoke.cpp | 52 ---- aegisub/src/audio_player_alsa.cpp | 3 - aegisub/src/audio_player_alsa.h | 8 - aegisub/src/audio_player_dsound.cpp | 31 --- aegisub/src/audio_player_dsound.h | 16 -- aegisub/src/audio_player_openal.cpp | 36 --- aegisub/src/audio_player_openal.h | 7 - aegisub/src/audio_player_oss.cpp | 28 -- aegisub/src/audio_player_oss.h | 3 - aegisub/src/audio_player_portaudio.h | 6 +- aegisub/src/audio_player_pulse.h | 5 - aegisub/src/audio_provider.cpp | 87 +++--- aegisub/src/audio_provider_avs.cpp | 123 +++------ aegisub/src/audio_provider_avs.h | 10 +- aegisub/src/audio_provider_convert.cpp | 35 +-- aegisub/src/audio_provider_convert.h | 17 +- aegisub/src/audio_provider_downmix.cpp | 27 +- aegisub/src/audio_provider_downmix.h | 14 +- aegisub/src/audio_provider_dummy.cpp | 9 - aegisub/src/audio_provider_dummy.h | 6 - aegisub/src/audio_provider_ffmpegsource.cpp | 74 ++--- aegisub/src/audio_provider_ffmpegsource.h | 4 +- aegisub/src/audio_provider_hd.cpp | 36 +-- aegisub/src/audio_provider_hd.h | 5 - aegisub/src/audio_provider_pcm.cpp | 186 ++++--------- aegisub/src/audio_provider_ram.cpp | 21 +- aegisub/src/audio_renderer_spectrum.cpp | 2 +- aegisub/src/auto4_base.cpp | 9 - aegisub/src/auto4_lua.h | 7 - aegisub/src/avisynth_wrap.cpp | 2 + aegisub/src/compat.h | 2 +- aegisub/src/ffmpegsource_common.cpp | 16 +- aegisub/src/ffmpegsource_common.h | 10 - aegisub/src/frame_main.cpp | 17 +- aegisub/src/hotkeys.cpp | 42 --- aegisub/src/include/aegisub/audio_provider.h | 10 + aegisub/src/include/aegisub/video_provider.h | 10 + aegisub/src/mkv_wrap.cpp | 37 +-- aegisub/src/mkv_wrap.h | 8 - aegisub/src/spellchecker_hunspell.cpp | 22 -- aegisub/src/subtitles_provider_csri.cpp | 1 + aegisub/src/text_file_reader.cpp | 3 - aegisub/src/threaded_frame_source.cpp | 12 +- aegisub/src/threaded_frame_source.h | 3 +- aegisub/src/video_box.cpp | 4 - aegisub/src/video_context.cpp | 11 +- aegisub/src/video_context.h | 10 +- aegisub/src/video_provider_avs.cpp | 272 +++++++++---------- aegisub/src/video_provider_avs.h | 5 +- aegisub/src/video_provider_cache.h | 2 - aegisub/src/video_provider_dummy.cpp | 18 +- aegisub/src/video_provider_ffmpegsource.cpp | 88 +++--- aegisub/src/video_provider_ffmpegsource.h | 1 - aegisub/src/video_provider_manager.cpp | 73 +++-- aegisub/src/video_provider_yuv4mpeg.cpp | 204 ++++++-------- aegisub/src/video_provider_yuv4mpeg.h | 5 - aegisub/src/visual_tool.cpp | 6 - aegisub/src/visual_tool_vector_clip.cpp | 4 - 65 files changed, 574 insertions(+), 1279 deletions(-) diff --git a/aegisub/src/aegisub_endian.h b/aegisub/src/aegisub_endian.h index 74e16ecb2..85a040cd1 100644 --- a/aegisub/src/aegisub_endian.h +++ b/aegisub/src/aegisub_endian.h @@ -131,16 +131,13 @@ namespace Endian { #ifndef HAVE_DYNAMIC_ENDIAN - - // Regular, fast, templatized conditional reversing - template - /// @brief DOCME /// @param val /// @return /// + template inline T LittleToMachine(T val) { #ifdef HAVE_BIG_ENDIAN @@ -152,12 +149,11 @@ namespace Endian { #endif } - template - /// @brief DOCME /// @param val /// @return /// + template inline T BigToMachine(T val) { #ifdef HAVE_LITTLE_ENDIAN @@ -169,12 +165,11 @@ namespace Endian { #endif } - template - /// @brief DOCME /// @param val /// @return /// + template inline T MachineToLittle(T val) { #ifdef HAVE_BIG_ENDIAN @@ -186,12 +181,11 @@ namespace Endian { #endif } - template - /// @brief DOCME /// @param val /// @return /// + template inline T MachineToBig(T val) { #ifdef HAVE_LITTLE_ENDIAN @@ -203,10 +197,8 @@ namespace Endian { #endif } - #else // HAVE_DYNAMIC_ENDIAN - // Dynamic endianness handling // Exploit that bit-shifting operations always can put bytes into @@ -216,13 +208,11 @@ namespace Endian { // the endianness of the machine we are on, but it's the same // code for any platform! - // Unions to pack together ints and get their physical bytes /// DOCME union bytes16 { - /// DOCME uint8_t byte[2]; @@ -232,7 +222,6 @@ namespace Endian { /// DOCME union bytes32 { - /// DOCME uint8_t byte[4]; @@ -242,7 +231,6 @@ namespace Endian { /// DOCME union bytes64 { - /// DOCME uint8_t byte[8]; @@ -250,7 +238,6 @@ namespace Endian { uint64_t word; }; - // 16 bit words @@ -456,8 +443,5 @@ namespace Endian { uint64_t(pack.byte[0]); } - #endif - }; - diff --git a/aegisub/src/agi_pre.cpp b/aegisub/src/agi_pre.cpp index 5f153cc20..5b42fc4e5 100644 --- a/aegisub/src/agi_pre.cpp +++ b/aegisub/src/agi_pre.cpp @@ -50,7 +50,5 @@ // So unless we protect it by this, it gets included twice during production of precompiled // headers, which can cause problems with local includes. #ifndef AGI_PRE -#include "config.h" - #include "agi_pre.h" #endif diff --git a/aegisub/src/agi_pre.h b/aegisub/src/agi_pre.h index 1475ce476..9e48368f0 100644 --- a/aegisub/src/agi_pre.h +++ b/aegisub/src/agi_pre.h @@ -43,7 +43,7 @@ #ifndef AGI_PRE_H /// @brief Inclusion guard. -/// @todo Why is this even nessicary? GCC seems to include agi_pre.h twice for no reason. +/// @todo Why is this even necessary? GCC seems to include agi_pre.h twice for no reason. #define AGI_PRE_H // C++ only diff --git a/aegisub/src/ass_export_filter.h b/aegisub/src/ass_export_filter.h index 406f88096..d310d486d 100644 --- a/aegisub/src/ass_export_filter.h +++ b/aegisub/src/ass_export_filter.h @@ -34,12 +34,8 @@ /// @ingroup export /// - #pragma once - -/////////// -// Headers #ifndef AGI_PRE #include #include @@ -48,21 +44,14 @@ #include #endif - -////////////// -// Prototypes class AssFile; class AssExportFilter; class DialogExport; class AssExporter; - - /// DOCME typedef std::list FilterList; - - /// DOCME /// @class AssExportFilterChain /// @brief DOCME @@ -80,7 +69,6 @@ private: /// DOCME FilterList Unprepared; - /// DOCME static std::auto_ptr instance; static FilterList *GetFilterList(); @@ -90,8 +78,6 @@ public: static void PrepareFilters(); }; - - /// DOCME /// @class AssExportFilter /// @brief DOCME @@ -139,4 +125,3 @@ public: virtual void LoadSettings(bool IsDefault); // Config dialog is done - extract data now. }; - diff --git a/aegisub/src/ass_exporter.cpp b/aegisub/src/ass_exporter.cpp index ccfc8be77..e74d69c14 100644 --- a/aegisub/src/ass_exporter.cpp +++ b/aegisub/src/ass_exporter.cpp @@ -36,16 +36,11 @@ #include "config.h" -#ifndef AGI_PRE -#include -#endif - #include "ass_export_filter.h" #include "ass_exporter.h" #include "ass_file.h" #include "frame_main.h" - /// @brief Constructor /// @param subs /// @@ -54,15 +49,11 @@ AssExporter::AssExporter (AssFile *subs) { IsDefault = true; } - - /// @brief Destructor /// AssExporter::~AssExporter () { } - - /// @brief Draw control settings /// @param parent /// @param AddTo @@ -90,8 +81,6 @@ void AssExporter::DrawSettings(wxWindow *parent,wxSizer *AddTo) { } } - - /// @brief Add filter to chain /// @param name /// @@ -113,8 +102,6 @@ void AssExporter::AddFilter(wxString name) { Filters.push_back(filter); } - - /// @brief Adds all autoexporting filters to chain /// void AssExporter::AddAutoFilters() { @@ -127,8 +114,6 @@ void AssExporter::AddAutoFilters() { } } - - /// @brief Get name of all filters /// @return /// @@ -142,8 +127,6 @@ wxArrayString AssExporter::GetAllFilterNames() { return names; } - - /// @brief Transform for export /// @param export_dialog /// @return @@ -162,8 +145,6 @@ AssFile *AssExporter::ExportTransform(wxWindow *export_dialog) { return Subs; } - - /// @brief Export /// @param filename /// @param charset @@ -174,8 +155,6 @@ void AssExporter::Export(wxString filename, wxString charset, wxWindow *export_d Subs->Save(filename,false,false,charset); } - - /// @brief Get window associated with name /// @param name /// @return @@ -186,8 +165,6 @@ wxSizer *AssExporter::GetSettingsSizer(wxString name) { else return pos->second; } - - /// @brief Get description of filter /// @param name /// @@ -201,5 +178,3 @@ wxString AssExporter::GetDescription(wxString name) { } throw wxString::Format(_T("Filter not found: %s"), name.c_str()); } - - diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index c048e43ae..875231ef9 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -70,6 +70,7 @@ namespace std { /// @brief AssFile constructor AssFile::AssFile () : loaded(false) +, commitId(-1) { } @@ -109,16 +110,17 @@ void AssFile::Load (const wxString &_filename,wxString charset,bool addToRecent) // Read file if (reader) { - reader->SetTarget(this); + AssFile temp; + reader->SetTarget(&temp); reader->ReadFile(_filename,charset); + swap(temp); ok = true; } // Couldn't find a type else throw _T("Unknown file type."); } - - // String error + catch (agi::UserCancelException const&) { } catch (const wchar_t *except) { wxMessageBox(except,_T("Error loading file"),wxICON_ERROR | wxOK); } @@ -154,7 +156,7 @@ void AssFile::Load (const wxString &_filename,wxString charset,bool addToRecent) savedCommitId = commitId; // Add to recent - if (addToRecent) AddToRecent(_filename); + if (addToRecent && ok) AddToRecent(_filename); } void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wxString encoding) { diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index 2768162bc..a238c1161 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -920,6 +920,16 @@ void AudioDisplay::SetFile(wxString file) { // Update UpdateImage(); } + catch (agi::UserCancelException const&) { + return; + } + catch (agi::FileNotFoundError const& e) { + config::mru->Remove("Audio", STD_STR(file)); + wxMessageBox(lagi_wxString(e.GetMessage()), L"Error loading audio",wxICON_ERROR | wxOK); + } + catch (AudioOpenError const& e) { + wxMessageBox(lagi_wxString(e.GetMessage()), L"Error loading audio",wxICON_ERROR | wxOK); + } catch (const wxChar *e) { if (player) { delete player; player = 0; } if (provider) { delete provider; provider = 0; } diff --git a/aegisub/src/audio_karaoke.cpp b/aegisub/src/audio_karaoke.cpp index 25dbac678..1d8ca4c6d 100644 --- a/aegisub/src/audio_karaoke.cpp +++ b/aegisub/src/audio_karaoke.cpp @@ -34,16 +34,12 @@ /// @ingroup audio_ui /// - -/////////// -// Headers #include "config.h" #ifndef AGI_PRE #include #include -#include #include #include #include @@ -56,7 +52,6 @@ #include "audio_display.h" #include "audio_karaoke.h" - /// @brief Empty constructor /// AudioKaraokeSyllable::AudioKaraokeSyllable() @@ -66,7 +61,6 @@ AudioKaraokeSyllable::AudioKaraokeSyllable() { } - /// @brief Copy-from-base constructor /// @param base /// @@ -77,9 +71,6 @@ AudioKaraokeSyllable::AudioKaraokeSyllable(const AssKaraokeSyllable &base) { } - - - /// @brief Constructor /// @param parent /// @@ -95,16 +86,12 @@ AudioKaraoke::AudioKaraoke(wxWindow *parent) workDiag = 0; } - - /// @brief Destructor /// AudioKaraoke::~AudioKaraoke() { delete workDiag; } - - /// @brief Load from dialogue /// @param _diag /// @return @@ -149,8 +136,6 @@ bool AudioKaraoke::LoadFromDialogue(AssDialogue *_diag) { return !hasKar; } - - /// @brief Writes line back /// @return /// @@ -196,8 +181,6 @@ void AudioKaraoke::Commit() { LOG_D("karaoke/audio") << "returning"; } - - /// @brief Autosplit line /// @return /// @@ -253,8 +236,6 @@ void AudioKaraoke::AutoSplit() { LOG_D("karaoke/audio") << "returning"; } - - /// @brief Parses text to extract karaoke /// @param curDiag /// @return @@ -287,8 +268,6 @@ bool AudioKaraoke::ParseDialogue(AssDialogue *curDiag) { return found_kara; } - - /// @brief Set syllable /// @param n /// @return @@ -304,7 +283,6 @@ void AudioKaraoke::SetSyllable(int n) { LOG_D("karaoke/audio") << "returning"; } - /////////////// // Event table BEGIN_EVENT_TABLE(AudioKaraoke,wxWindow) @@ -313,8 +291,6 @@ BEGIN_EVENT_TABLE(AudioKaraoke,wxWindow) EVT_MOUSE_EVENTS(AudioKaraoke::OnMouse) END_EVENT_TABLE() - - /// @brief Paint event /// @param event /// @@ -425,8 +401,6 @@ void AudioKaraoke::OnPaint(wxPaintEvent &event) { event.Skip(); } - - /// @brief Size event /// @param event /// @@ -434,8 +408,6 @@ void AudioKaraoke::OnSize(wxSizeEvent &event) { Refresh(false); } - - /// @brief Mouse event /// @param event /// @return @@ -571,8 +543,6 @@ void AudioKaraoke::OnMouse(wxMouseEvent &event) { } } - - /// @brief Get Syllable at position X /// @param x /// @return @@ -590,8 +560,6 @@ int AudioKaraoke::GetSylAtX(int x) { return -1; } - - /// @brief Set selection /// @param start /// @param end @@ -628,8 +596,6 @@ void AudioKaraoke::SetSelection(int start,int end) { box->SetKaraokeButtons(); } - - /// @brief Join syllables /// @return /// @@ -675,8 +641,6 @@ void AudioKaraoke::Join() { LOG_D("karaoke/audio") << "returning"; } - - /// @brief Enter splitting-mode /// void AudioKaraoke::BeginSplit() { @@ -688,8 +652,6 @@ void AudioKaraoke::BeginSplit() { Refresh(false); } - - /// @brief Leave splitting-mode, committing changes /// @param commit /// @return @@ -727,8 +689,6 @@ void AudioKaraoke::EndSplit(bool commit) { LOG_D("karaoke/audio") << "returning"; } - - /// @brief Split a syllable using the pending_slits data /// @param n /// @return @@ -799,8 +759,6 @@ int AudioKaraoke::SplitSyl (unsigned int n) { return numsplits; } - - /// @brief Apply delta length to syllable /// @param n /// @param delta @@ -855,8 +813,6 @@ bool AudioKaraoke::SyllableDelta(int n,int delta,int mode) { return false; } - - /// @brief Karaoke tag menu constructor /// @param _kara /// @@ -884,22 +840,17 @@ AudioKaraokeTagMenu::AudioKaraokeTagMenu(AudioKaraoke *_kara) } } - - /// @brief Karaoke tag menu destructor /// AudioKaraokeTagMenu::~AudioKaraokeTagMenu() { } - /////////////// // Event table BEGIN_EVENT_TABLE(AudioKaraokeTagMenu,wxMenu) EVT_MENU_RANGE(10001, 10003, AudioKaraokeTagMenu::OnSelectItem) END_EVENT_TABLE() - - /// @brief Karaoke tag menu event handler /// @param event /// @@ -934,6 +885,3 @@ void AudioKaraokeTagMenu::OnSelectItem(wxCommandEvent &event) { kara->SetSelection(firstsel, lastsel); } - - - diff --git a/aegisub/src/audio_player_alsa.cpp b/aegisub/src/audio_player_alsa.cpp index 64bff84fe..68726ec31 100644 --- a/aegisub/src/audio_player_alsa.cpp +++ b/aegisub/src/audio_player_alsa.cpp @@ -34,10 +34,8 @@ /// @ingroup audio_output /// - #include "config.h" - #ifdef WITH_ALSA #include @@ -48,7 +46,6 @@ #include "frame_main.h" #include "utils.h" - /// @brief Constructor /// AlsaPlayer::AlsaPlayer() diff --git a/aegisub/src/audio_player_alsa.h b/aegisub/src/audio_player_alsa.h index 595473a92..72b3bf65c 100644 --- a/aegisub/src/audio_player_alsa.h +++ b/aegisub/src/audio_player_alsa.h @@ -34,16 +34,12 @@ /// @ingroup audio_output /// - #ifdef WITH_ALSA #include #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" - - /// DOCME /// @class AlsaPlayer @@ -62,7 +58,6 @@ private: /// DOCME volatile float volume; - /// DOCME volatile unsigned long start_frame; // first frame of playback @@ -75,7 +70,6 @@ private: /// DOCME unsigned long bpf; // bytes per frame - /// DOCME AudioProvider *provider; @@ -88,7 +82,6 @@ private: /// DOCME snd_async_handler_t *pcm_callback; - /// DOCME snd_pcm_format_t sample_format; @@ -132,7 +125,6 @@ public: void SetEndPosition(int64_t pos); void SetCurrentPosition(int64_t pos); - /// @brief DOCME /// @param vol /// @return diff --git a/aegisub/src/audio_player_dsound.cpp b/aegisub/src/audio_player_dsound.cpp index f8d9b959a..2fe021c1b 100644 --- a/aegisub/src/audio_player_dsound.cpp +++ b/aegisub/src/audio_player_dsound.cpp @@ -34,9 +34,6 @@ /// @ingroup audio_output /// - -/////////// -// Headers #include "config.h" #ifdef WITH_DIRECTSOUND @@ -48,7 +45,6 @@ #include "main.h" #include "utils.h" - /// @brief Constructor /// DirectSoundPlayer::DirectSoundPlayer() { @@ -64,16 +60,12 @@ DirectSoundPlayer::DirectSoundPlayer() { thread = NULL; } - - /// @brief Destructor /// DirectSoundPlayer::~DirectSoundPlayer() { CloseStream(); } - - /// @brief Open stream /// void DirectSoundPlayer::OpenStream() { @@ -125,8 +117,6 @@ void DirectSoundPlayer::OpenStream() { offset = 0; } - - /// @brief Close stream /// void DirectSoundPlayer::CloseStream() { @@ -146,8 +136,6 @@ void DirectSoundPlayer::CloseStream() { } } - - /// @brief Fill buffer /// @param fill /// @return @@ -237,8 +225,6 @@ RetryLock: return playPos < endPos; } - - /// @brief Play /// @param start /// @param count @@ -281,8 +267,6 @@ void DirectSoundPlayer::Play(int64_t start,int64_t count) { if (displayTimer && !displayTimer->IsRunning()) displayTimer->Start(15); } - - /// @brief Stop /// @param timerToo /// @@ -313,8 +297,6 @@ void DirectSoundPlayer::Stop(bool timerToo) { } } - - /// @brief Set end /// @param pos /// @@ -322,8 +304,6 @@ void DirectSoundPlayer::SetEndPosition(int64_t pos) { if (playing) endPos = pos; } - - /// @brief Set current position /// @param pos /// @@ -332,8 +312,6 @@ void DirectSoundPlayer::SetCurrentPosition(int64_t pos) { startTime = GetTickCount(); } - - /// @brief Get current position /// @return /// @@ -348,8 +326,6 @@ int64_t DirectSoundPlayer::GetCurrentPosition() { return startPos + tdiff * provider->GetSampleRate() / 1000; } - - /// @brief Thread constructor /// @param par /// @@ -358,16 +334,12 @@ DirectSoundPlayerThread::DirectSoundPlayerThread(DirectSoundPlayer *par) : wxThr stopnotify = CreateEvent(NULL, true, false, NULL); } - - /// @brief Thread destructor /// DirectSoundPlayerThread::~DirectSoundPlayerThread() { CloseHandle(stopnotify); } - - /// @brief Thread entry point /// @return /// @@ -418,8 +390,6 @@ wxThread::ExitCode DirectSoundPlayerThread::Entry() { return 0; } - - /// @brief Stop playback thread /// void DirectSoundPlayerThread::Stop() { @@ -429,4 +399,3 @@ void DirectSoundPlayerThread::Stop() { #endif // WITH_DIRECTSOUND - diff --git a/aegisub/src/audio_player_dsound.h b/aegisub/src/audio_player_dsound.h index 47aec34d1..9a9c86182 100644 --- a/aegisub/src/audio_player_dsound.h +++ b/aegisub/src/audio_player_dsound.h @@ -34,9 +34,6 @@ /// @ingroup audio_output /// - -/////////// -// Headers #ifdef WITH_DIRECTSOUND #ifndef AGI_PRE @@ -47,15 +44,9 @@ #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" - -////////////// -// Prototypes class DirectSoundPlayer; - - /// DOCME /// @class DirectSoundPlayerThread /// @brief DOCME @@ -93,8 +84,6 @@ detect which were actually changed and act accordingly. All but GetPosition() set appropriate fields and then raise the parameters changed event. */ - - /// DOCME /// @class DirectSoundPlayer /// @brief DOCME @@ -117,7 +106,6 @@ private: /// DOCME DWORD bufSize; - /// DOCME volatile int64_t playPos; @@ -130,7 +118,6 @@ private: /// DOCME DWORD startTime; - /// DOCME IDirectSound8 *directSound; @@ -139,7 +126,6 @@ private: bool FillBuffer(bool fill); - /// DOCME DirectSoundPlayerThread *thread; @@ -158,7 +144,6 @@ public: /// bool IsPlaying() { return playing; } - /// @brief DOCME /// @return /// @@ -172,7 +157,6 @@ public: void SetEndPosition(int64_t pos); void SetCurrentPosition(int64_t pos); - /// @brief DOCME /// @param vol /// @return diff --git a/aegisub/src/audio_player_openal.cpp b/aegisub/src/audio_player_openal.cpp index 456c4c38d..f87c11cd7 100644 --- a/aegisub/src/audio_player_openal.cpp +++ b/aegisub/src/audio_player_openal.cpp @@ -44,17 +44,6 @@ #include "frame_main.h" #include "utils.h" -#ifdef __WINDOWS__ -#include -#include -#elif defined(__APPLE__) -#include -#include -#else -#include -#include -#endif - // Auto-link to OpenAL lib for MSVC #ifdef _MSC_VER #pragma comment(lib, "openal32.lib") @@ -78,8 +67,6 @@ OpenALPlayer::~OpenALPlayer() CloseStream(); } - - /// @brief Open stream /// void OpenALPlayer::OpenStream() @@ -135,8 +122,6 @@ void OpenALPlayer::OpenStream() open = true; } - - /// @brief Close stream /// @return /// @@ -155,8 +140,6 @@ void OpenALPlayer::CloseStream() open = false; } - - /// @brief Play /// @param start /// @param count @@ -192,8 +175,6 @@ void OpenALPlayer::Play(int64_t start,int64_t count) if (displayTimer && !displayTimer->IsRunning()) displayTimer->Start(15); } - - /// @brief Stop /// @param timerToo /// @return @@ -219,8 +200,6 @@ void OpenALPlayer::Stop(bool timerToo) } } - - /// @brief DOCME /// @param count /// @@ -261,8 +240,6 @@ void OpenALPlayer::FillBuffers(ALsizei count) free(data); } - - /// @brief DOCME /// void OpenALPlayer::Notify() @@ -300,8 +277,6 @@ void OpenALPlayer::Notify() } } - - /// @brief DOCME /// @return /// @@ -310,8 +285,6 @@ bool OpenALPlayer::IsPlaying() return playing; } - - /// @brief Set end /// @param pos /// @@ -320,8 +293,6 @@ void OpenALPlayer::SetEndPosition(int64_t pos) end_frame = pos; } - - /// @brief Set current position /// @param pos /// @@ -330,8 +301,6 @@ void OpenALPlayer::SetCurrentPosition(int64_t pos) cur_frame = pos; } - - /// @brief DOCME /// @return /// @@ -340,8 +309,6 @@ int64_t OpenALPlayer::GetStartPosition() return start_frame; } - - /// @brief DOCME /// @return /// @@ -350,8 +317,6 @@ int64_t OpenALPlayer::GetEndPosition() return end_frame; } - - /// @brief Get current position /// int64_t OpenALPlayer::GetCurrentPosition() @@ -362,5 +327,4 @@ int64_t OpenALPlayer::GetCurrentPosition() return buffers_played * buffer_length + start_frame + extra * samplerate / 1000; } - #endif // WITH_OPENAL diff --git a/aegisub/src/audio_player_openal.h b/aegisub/src/audio_player_openal.h index be172689c..51c4b3e4f 100644 --- a/aegisub/src/audio_player_openal.h +++ b/aegisub/src/audio_player_openal.h @@ -34,11 +34,9 @@ /// @ingroup audio_output /// - #ifdef WITH_OPENAL #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" #ifdef __WINDOWS__ #include @@ -68,7 +66,6 @@ private: /// DOCME volatile float volume; - /// DOCME static const ALsizei num_buffers = 8; @@ -78,7 +75,6 @@ private: /// DOCME ALsizei samplerate; - /// DOCME volatile unsigned long start_frame; // first frame of playback @@ -91,7 +87,6 @@ private: /// DOCME unsigned long bpf; // bytes per frame - /// DOCME AudioProvider *provider; @@ -107,7 +102,6 @@ private: /// DOCME ALuint source; // playback source - /// DOCME ALsizei buf_first_free; // index into buffers, first free (unqueued) buffer @@ -145,7 +139,6 @@ public: void SetEndPosition(int64_t pos); void SetCurrentPosition(int64_t pos); - /// @brief DOCME /// @param vol /// @return diff --git a/aegisub/src/audio_player_oss.cpp b/aegisub/src/audio_player_oss.cpp index 5a2b62eca..c9cfec9cb 100644 --- a/aegisub/src/audio_player_oss.cpp +++ b/aegisub/src/audio_player_oss.cpp @@ -32,7 +32,6 @@ /// @ingroup audio_output /// - #include "config.h" #ifdef WITH_OSS @@ -45,7 +44,6 @@ #include "main.h" #include "utils.h" - /// @brief Constructor /// OSSPlayer::OSSPlayer() @@ -58,8 +56,6 @@ OSSPlayer::OSSPlayer() thread = 0; } - - /// @brief Destructor /// OSSPlayer::~OSSPlayer() @@ -67,8 +63,6 @@ OSSPlayer::~OSSPlayer() CloseStream(); } - - /// @brief Open stream /// void OSSPlayer::OpenStream() @@ -125,8 +119,6 @@ void OSSPlayer::OpenStream() open = true; } - - /// @brief Close stream /// @return /// @@ -141,8 +133,6 @@ void OSSPlayer::CloseStream() open = false; } - - /// @brief Play /// @param start /// @param count @@ -163,8 +153,6 @@ void OSSPlayer::Play(int64_t start, int64_t count) playing = true; } - - /// @brief Stop /// @param timerToo /// @return @@ -198,8 +186,6 @@ void OSSPlayer::Stop(bool timerToo) } } - - /// @brief DOCME /// @return /// @@ -208,8 +194,6 @@ bool OSSPlayer::IsPlaying() return playing; } - - /// @brief Set end /// @param pos /// @@ -225,8 +209,6 @@ void OSSPlayer::SetEndPosition(int64_t pos) } - - /// @brief Set current position /// @param pos /// @@ -235,8 +217,6 @@ void OSSPlayer::SetCurrentPosition(int64_t pos) cur_frame = start_frame = pos; } - - /// @brief DOCME /// @return /// @@ -245,8 +225,6 @@ int64_t OSSPlayer::GetStartPosition() return start_frame; } - - /// @brief DOCME /// @return /// @@ -255,8 +233,6 @@ int64_t OSSPlayer::GetEndPosition() return end_frame; } - - /// @brief Get current position /// @return /// @@ -305,8 +281,6 @@ int64_t OSSPlayer::GetCurrentPosition() return cur_frame; } - - /// @brief Thread constructor /// @param par /// @@ -338,6 +312,4 @@ wxThread::ExitCode OSSPlayerThread::Entry() { return 0; } - - #endif // WITH_OSS diff --git a/aegisub/src/audio_player_oss.h b/aegisub/src/audio_player_oss.h index b7d6f2b36..2b9cd3ce9 100644 --- a/aegisub/src/audio_player_oss.h +++ b/aegisub/src/audio_player_oss.h @@ -52,7 +52,6 @@ #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" class OSSPlayer; @@ -73,8 +72,6 @@ public: wxThread::ExitCode Entry(); }; - - /// DOCME /// @class OSSPlayer /// @brief DOCME diff --git a/aegisub/src/audio_player_portaudio.h b/aegisub/src/audio_player_portaudio.h index e22416d7c..d92b6e4d4 100644 --- a/aegisub/src/audio_player_portaudio.h +++ b/aegisub/src/audio_player_portaudio.h @@ -34,13 +34,13 @@ /// @ingroup audio_output /// - #ifdef WITH_PORTAUDIO #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" -extern "C" { + + + "C" { #include } diff --git a/aegisub/src/audio_player_pulse.h b/aegisub/src/audio_player_pulse.h index 01a70b832..6ec5d0b2c 100644 --- a/aegisub/src/audio_player_pulse.h +++ b/aegisub/src/audio_player_pulse.h @@ -35,15 +35,10 @@ /// #ifdef WITH_PULSEAUDIO -#ifndef AGI_PRE -#include -#endif - #include #include "include/aegisub/audio_player.h" #include "include/aegisub/audio_provider.h" -#include "utils.h" class PulseAudioPlayer; diff --git a/aegisub/src/audio_provider.cpp b/aegisub/src/audio_provider.cpp index 59e3b7974..d37307679 100644 --- a/aegisub/src/audio_provider.cpp +++ b/aegisub/src/audio_provider.cpp @@ -178,66 +178,69 @@ void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, /// AudioProvider *AudioProviderFactory::GetProvider(wxString filename, int cache) { AudioProvider *provider = NULL; + bool found = false; + std::string msg; if (!OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) { // Try a PCM provider first - provider = CreatePCMAudioProvider(filename); - if (provider) { - if (provider->GetBytesPerSample() == 2 && provider->GetSampleRate() >= 32000 && provider->GetChannels() == 1) - return provider; - else { - return CreateConvertAudioProvider(provider); + try { + provider = CreatePCMAudioProvider(filename); + } + catch (agi::FileNotFoundError const& err) { + msg = "PCM audio provider: " + err.GetMessage() + " not found.\n"; + } + catch (AudioOpenError const& err) { + found = true; + msg += err.GetMessage(); + } + } + if (!provider) { + std::vector list = GetClasses(OPT_GET("Audio/Provider")->GetString()); + if (list.empty()) throw AudioOpenError("No audio providers are available."); + + for (unsigned int i=0;i list = GetClasses(OPT_GET("Audio/Provider")->GetString()); - - if (list.empty()) throw _T("No audio providers are available."); - - // Get provider - wxString error; - for (unsigned int i=0;iNeedsCache(); - // Failed - if (!provider) throw error; - - // Give it a conversor if needed + // Give it a converter if needed if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1) provider = CreateConvertAudioProvider(provider); // Change provider to RAM/HD cache if needed if (cache == -1) cache = OPT_GET("Audio/Cache/Type")->GetInt(); - if (cache) { - AudioProvider *final = NULL; - - // Convert to RAM - if (cache == 1) final = new RAMAudioProvider(provider); - - // Convert to HD - if (cache == 2) final = new HDAudioProvider(provider); - - // Reassign - if (final) { - delete provider; - return final; - } + if (!cache || !needsCache) { + return provider; } - return provider; + // Convert to RAM + if (cache == 1) return new RAMAudioProvider(provider); + + // Convert to HD + if (cache == 2) return new HDAudioProvider(provider); + + throw AudioOpenError("Unknown caching method"); } - - /// @brief Register all providers /// void AudioProviderFactory::RegisterProviders() { diff --git a/aegisub/src/audio_provider_avs.cpp b/aegisub/src/audio_provider_avs.cpp index 995bda797..e342da69c 100644 --- a/aegisub/src/audio_provider_avs.cpp +++ b/aegisub/src/audio_provider_avs.cpp @@ -34,14 +34,10 @@ /// @ingroup audio_input /// - -/////////// -// Headers #include "config.h" #ifdef WITH_AVISYNTH - #ifndef AGI_PRE #include #include @@ -56,100 +52,59 @@ #include "standard_paths.h" #include "utils.h" - /// @brief Constructor /// @param _filename /// -AvisynthAudioProvider::AvisynthAudioProvider(wxString _filename) { - filename = _filename; - - try { - OpenAVSAudio(); - } - catch (...) { - Unload(); - throw; - } -} - - - -/// @brief Destructor -/// -AvisynthAudioProvider::~AvisynthAudioProvider() { - Unload(); -} - - - -/// @brief Unload audio -/// -void AvisynthAudioProvider::Unload() { - // Clean up avisynth - clip = NULL; -} - - - -/// @brief Load audio from avisynth -/// -void AvisynthAudioProvider::OpenAVSAudio() { - // Set variables +AvisynthAudioProvider::AvisynthAudioProvider(wxString filename) try : filename(filename) { AVSValue script; - - // Prepare avisynth wxMutexLocker lock(AviSynthMutex); - try { - // Include - if (filename.EndsWith(_T(".avs"))) { - wxFileName fn(filename); - char *fname = env->SaveString(fn.GetShortPath().mb_str(csConvLocal)); - script = env->Invoke("Import", fname); + wxFileName fn(filename); + if (!fn.FileExists()) + throw agi::FileNotFoundError(STD_STR(filename)); + + // Include + if (filename.EndsWith(_T(".avs"))) { + char *fname = env->SaveString(fn.GetShortPath().mb_str(csConvLocal)); + script = env->Invoke("Import", fname); + } + + // Use DirectShowSource + else { + const char * argnames[3] = { 0, "video", "audio" }; + AVSValue args[3] = { env->SaveString(fn.GetShortPath().mb_str(csConvLocal)), false, true }; + + // Load DirectShowSource.dll from app dir if it exists + wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); + if (dsspath.FileExists()) { + env->Invoke("LoadPlugin",env->SaveString(dsspath.GetShortPath().mb_str(csConvLocal))); } - // Use DirectShowSource + // Load audio with DSS if it exists + if (env->FunctionExists("DirectShowSource")) { + script = env->Invoke("DirectShowSource", AVSValue(args,3),argnames); + } + // Otherwise fail else { - wxFileName fn(filename); - const char * argnames[3] = { 0, "video", "audio" }; - AVSValue args[3] = { env->SaveString(fn.GetShortPath().mb_str(csConvLocal)), false, true }; - - // Load DirectShowSource.dll from app dir if it exists - wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); - if (dsspath.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dsspath.GetShortPath().mb_str(csConvLocal))); - } - - // Load audio with DSS if it exists - if (env->FunctionExists("DirectShowSource")) { - script = env->Invoke("DirectShowSource", AVSValue(args,3),argnames); - } - // Otherwise fail - else { - throw AvisynthError("No suitable audio source filter found. Try placing DirectShowSource.dll in the Aegisub application directory."); - } + throw AudioOpenError("No suitable audio source filter found. Try placing DirectShowSource.dll in the Aegisub application directory."); } + } - LoadFromClip(script); - } - - catch (AvisynthError &err) { - throw wxString::Format(_T("AviSynth error: %s"), wxString(err.msg,csConvLocal)); - } + LoadFromClip(script); +} +catch (AvisynthError &err) { + throw AudioOpenError("Avisynth error: " + std::string(err.msg)); } - - /// @brief Read from environment /// @param _clip /// void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) { - // Prepare avisynth AVSValue script; // Check if it has audio VideoInfo vi = _clip.AsClip()->GetVideoInfo(); - if (!vi.HasAudio()) throw wxString(_T("No audio found.")); + if (!vi.HasAudio()) throw AudioOpenError("No audio found."); // Convert to one channel char buffer[1024]; @@ -178,20 +133,9 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) { sample_rate = vi.SamplesPerSecond(); bytes_per_sample = vi.BytesPerAudioSample(); - // Set clip = tempclip; } - - -/// @brief Get filename -/// @return -/// -wxString AvisynthAudioProvider::GetFilename() { - return filename; -} - - /// @brief Get audio /// @param buf /// @param start @@ -223,7 +167,4 @@ void AvisynthAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) { clip->GetAudio(buf,start,count,env); } } - #endif - - diff --git a/aegisub/src/audio_provider_avs.h b/aegisub/src/audio_provider_avs.h index 3514eca12..2f573ec6b 100644 --- a/aegisub/src/audio_provider_avs.h +++ b/aegisub/src/audio_provider_avs.h @@ -35,7 +35,6 @@ /// #ifdef WITH_AVISYNTH -#include #include "include/aegisub/audio_provider.h" #include "avisynth_wrap.h" @@ -46,8 +45,6 @@ /// /// DOCME class AvisynthAudioProvider : public AudioProvider, public AviSynthWrapper { -private: - /// DOCME wxString filename; @@ -55,21 +52,18 @@ private: PClip clip; void LoadFromClip(AVSValue clip); - void OpenAVSAudio(); void SetFile(); - void Unload(); public: AvisynthAudioProvider(wxString _filename); - ~AvisynthAudioProvider(); - - wxString GetFilename(); + wxString GetFilename() { return filename; } /// @brief Only exists for x86 Windows, always delivers machine (little) endian /// @return /// bool AreSamplesNativeEndian() const { return true; } + bool NeedsCache() const { return true; } void GetAudio(void *buf, int64_t start, int64_t count); void GetWaveForm(int *min,int *peak,int64_t start,int w,int h,int samples,float scale); diff --git a/aegisub/src/audio_provider_convert.cpp b/aegisub/src/audio_provider_convert.cpp index 527a546c0..e55bf042a 100644 --- a/aegisub/src/audio_provider_convert.cpp +++ b/aegisub/src/audio_provider_convert.cpp @@ -34,9 +34,6 @@ /// @ingroup audio_input /// - -/////////// -// Headers #include "config.h" #include "aegisub_endian.h" @@ -47,8 +44,7 @@ /// @brief Constructor /// @param src /// -ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) { - source = src; +ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) : source(src) { channels = source->GetChannels(); num_samples = source->GetNumSamples(); sample_rate = source->GetSampleRate(); @@ -61,16 +57,6 @@ ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) { num_samples *= sampleMult; } - - -/// @brief Destructor -/// -ConvertAudioProvider::~ConvertAudioProvider() { - delete source; -} - - - /// @brief Convert to 16-bit /// @param src /// @param dst @@ -82,7 +68,6 @@ void ConvertAudioProvider::Make16Bit(const char *src, short *dst, int64_t count) } } - ////////////////////// // Change sample rate // This requres 16-bit input @@ -134,35 +119,21 @@ void ConvertAudioProvider::ChangeSampleRate(const short *src, short *dst, int64_ } } - - /// DOCME struct NullSampleConverter { - - /// @brief DOCME - /// @param val - /// @return - /// inline short operator()(const short val) const { return val; } }; - /// DOCME struct EndianSwapSampleConverter { - - /// @brief DOCME - /// @param val - /// @return - /// inline short operator()(const short val) const { return (short)Endian::Reverse((uint16_t)val); }; }; - /// @brief Get audio /// @param destination /// @param start @@ -234,7 +205,7 @@ AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) { { // @todo add support for more bitdepths (i.e. 24- and 32-bit audio) if (provider->GetBytesPerSample() > 2) - throw _T("Audio format converter: audio with bitdepths greater than 16 bits/sample is currently unsupported"); + AudioOpenError("Audio format converter: audio with bitdepths greater than 16 bits/sample is currently unsupported"); provider = new ConvertAudioProvider(provider); } @@ -247,5 +218,3 @@ AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) { return provider; } - - diff --git a/aegisub/src/audio_provider_convert.h b/aegisub/src/audio_provider_convert.h index e335e8ef4..397995117 100644 --- a/aegisub/src/audio_provider_convert.h +++ b/aegisub/src/audio_provider_convert.h @@ -36,6 +36,9 @@ #include "include/aegisub/audio_provider.h" +#ifndef AGI_PRE +#include +#endif /// DOCME /// @class ConvertAudioProvider @@ -43,32 +46,24 @@ /// /// DOCME class ConvertAudioProvider : public AudioProvider { -private: - /// DOCME int sampleMult; - /// DOCME - AudioProvider *source; + std::tr1::shared_ptr source; void Make16Bit(const char *src, short *dst, int64_t count); template void ChangeSampleRate(const short *src, short *dst, int64_t count, const SampleConverter &converter); public: ConvertAudioProvider(AudioProvider *source); - ~ConvertAudioProvider(); - - /// @brief // That's one of the points of it! // By its nature, the ConvertAudioProvider always delivers machine endian: - /// @return - /// + /// By its nature, the ConvertAudioProvider always delivers machine endian. + /// That's one of the points of it! bool AreSamplesNativeEndian() const { return true; } void GetAudio(void *buf, int64_t start, int64_t count); - /// @brief DOCME - /// wxString GetFilename() { return source->GetFilename(); } }; diff --git a/aegisub/src/audio_provider_downmix.cpp b/aegisub/src/audio_provider_downmix.cpp index 9f89b808c..1d1ab2492 100644 --- a/aegisub/src/audio_provider_downmix.cpp +++ b/aegisub/src/audio_provider_downmix.cpp @@ -45,7 +45,7 @@ /// @brief Constructor /// @param source /// -DownmixingAudioProvider::DownmixingAudioProvider(AudioProvider *source) { +DownmixingAudioProvider::DownmixingAudioProvider(AudioProvider *source) : provider(source) { filename = source->GetFilename(); channels = 1; // target src_channels = source->GetChannels(); @@ -53,23 +53,12 @@ DownmixingAudioProvider::DownmixingAudioProvider(AudioProvider *source) { bytes_per_sample = source->GetBytesPerSample(); sample_rate = source->GetSampleRate(); - // We now own this - provider = source; - if (!(bytes_per_sample == 1 || bytes_per_sample == 2)) - throw _T("Downmixing Audio Provider: Can only downmix 8 and 16 bit audio"); + throw AudioOpenError("Downmixing Audio Provider: Can only downmix 8 and 16 bit audio"); if (!source->AreSamplesNativeEndian()) - throw _T("Downmixing Audio Provider: Source must have machine endian samples"); + throw AudioOpenError("Downmixing Audio Provider: Source must have machine endian samples"); } - -/// @brief Destructor -/// -DownmixingAudioProvider::~DownmixingAudioProvider() { - delete provider; -} - - /// @brief Actual work happens here /// @param buf /// @param start @@ -95,7 +84,13 @@ void DownmixingAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) // a pre-allocced block of memory...? char *tmp = new char[count*bytes_per_sample*src_channels]; - provider->GetAudio(tmp, start, count); + try { + provider->GetAudio(tmp, start, count); + } + catch (...) { + delete tmp; + throw; + } // Now downmix // Just average the samples over the channels (really bad if they're out of phase!) @@ -128,5 +123,3 @@ void DownmixingAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) // Done downmixing, free the work buffer delete[] tmp; } - - diff --git a/aegisub/src/audio_provider_downmix.h b/aegisub/src/audio_provider_downmix.h index 871420aa7..91cceaa23 100644 --- a/aegisub/src/audio_provider_downmix.h +++ b/aegisub/src/audio_provider_downmix.h @@ -34,9 +34,11 @@ /// @ingroup audio_input /// - #include "include/aegisub/audio_provider.h" +#ifndef AGI_PRE +#include +#endif /// DOCME /// @class DownmixingAudioProvider @@ -44,20 +46,14 @@ /// /// DOCME class DownmixingAudioProvider : public AudioProvider { -private: - - /// DOCME - AudioProvider *provider; + std::tr1::shared_ptr provider; /// DOCME int src_channels; - public: DownmixingAudioProvider(AudioProvider *source); - ~DownmixingAudioProvider(); - - /// @brief // Downmixing requires samples to be native endian beforehand + /// @brief Downmixing requires samples to be native endian beforehand /// bool AreSamplesNativeEndian() const { return true; } diff --git a/aegisub/src/audio_provider_dummy.cpp b/aegisub/src/audio_provider_dummy.cpp index c08bf1db5..ae7f3da77 100644 --- a/aegisub/src/audio_provider_dummy.cpp +++ b/aegisub/src/audio_provider_dummy.cpp @@ -34,9 +34,6 @@ /// @ingroup audio_input /// - -/////////// -// Headers #include "config.h" #include "audio_provider_dummy.h" @@ -55,15 +52,11 @@ DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) { num_samples = (int64_t)dur_ms * sample_rate / 1000; } - - /// @brief Destructor /// DummyAudioProvider::~DummyAudioProvider() { } - - /// @brief Get audio /// @param buf /// @param start @@ -81,5 +74,3 @@ void DummyAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) { *workbuf++ = 0; } } - - diff --git a/aegisub/src/audio_provider_dummy.h b/aegisub/src/audio_provider_dummy.h index 89d7e57fd..508c15ab3 100644 --- a/aegisub/src/audio_provider_dummy.h +++ b/aegisub/src/audio_provider_dummy.h @@ -42,8 +42,6 @@ /// /// DOCME class DummyAudioProvider : public AudioProvider { -private: - /// DOCME bool noise; @@ -51,10 +49,6 @@ public: DummyAudioProvider(unsigned long dur_ms, bool _noise); ~DummyAudioProvider(); - - /// @brief DOCME - /// bool AreSamplesNativeEndian() const { return true; } - void GetAudio(void *buf, int64_t start, int64_t count); }; diff --git a/aegisub/src/audio_provider_ffmpegsource.cpp b/aegisub/src/audio_provider_ffmpegsource.cpp index fd6897062..70fd9d086 100644 --- a/aegisub/src/audio_provider_ffmpegsource.cpp +++ b/aegisub/src/audio_provider_ffmpegsource.cpp @@ -38,8 +38,6 @@ #ifdef WITH_FFMPEGSOURCE -/////////// -// Headers #ifndef AGI_PRE #ifdef WIN32 #include @@ -49,22 +47,24 @@ #endif #include "audio_provider_ffmpegsource.h" -#include "include/aegisub/aegisub.h" +#include "compat.h" #include "main.h" /// @brief Constructor /// @param filename /// -FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) { - COMInited = false; +FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) +: AudioSource(NULL) +, COMInited(false) +{ #ifdef WIN32 HRESULT res; res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (SUCCEEDED(res)) COMInited = true; else if (res != RPC_E_CHANGED_MODE) - throw _T("FFmpegSource video provider: COM initialization failure"); + throw AudioOpenError("COM initialization failure"); #endif FFMS_Init(0); @@ -72,10 +72,6 @@ FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) { ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; ErrInfo.SubType = FFMS_ERROR_SUCCESS; - ErrorMsg = _T("FFmpegSource audio provider: "); - - AudioSource = NULL; - SetLogLevel(); try { @@ -86,28 +82,20 @@ FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) { } } - - /// @brief Load audio file /// @param filename /// void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { - // clean up - Close(); - wxString FileNameShort = wxFileName(filename).GetShortPath(); FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo); if (Indexer == NULL) { - // error messages that can possibly contain a filename use this method instead of - // wxString::Format because they may contain utf8 characters - ErrorMsg.Append(_T("Failed to create indexer: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8)); - throw ErrorMsg; + throw agi::FileNotFoundError(ErrInfo.Buffer); } std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_AUDIO); if (TrackList.size() <= 0) - throw _T("FFmpegSource audio provider: no audio tracks found"); + throw AudioOpenError("no audio tracks found"); // initialize the track number to an invalid value so we can detect later on // whether the user actually had to choose a track or not @@ -116,7 +104,7 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { TrackNumber = AskForTrackSelection(TrackList, FFMS_TYPE_AUDIO); // if it's still -1 here, user pressed cancel if (TrackNumber == -1) - throw _T("FFmpegSource audio provider: audio loading cancelled by user"); + throw agi::UserCancelException("audio loading cancelled by user"); } // generate a name for the cache file @@ -143,8 +131,7 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { if (TrackNumber < 0) { FFMS_DestroyIndex(Index); Index = NULL; - ErrorMsg.Append(wxString::Format(_T("Couldn't find any audio tracks: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw AudioOpenError(std::string("Couldn't find any audio tracks: ") + ErrInfo.Buffer); } // index is valid and track number is now set, @@ -171,11 +158,9 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { try { Index = DoIndexing(Indexer, CacheName, TrackMask, GetErrorHandlingMode()); - } catch (wxString temp) { - ErrorMsg.Append(temp); - throw ErrorMsg; - } catch (...) { - throw; + } + catch (wxString const& err) { + throw AudioOpenError(STD_STR(err)); } // if tracknumber still isn't set we need to set it now @@ -192,8 +177,7 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { FFMS_DestroyIndex(Index); Index = NULL; if (!AudioSource) { - ErrorMsg.Append(wxString::Format(_T("Failed to open audio track: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw AudioOpenError(std::string("Failed to open audio track: %s") + ErrInfo.Buffer); } const FFMS_AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); @@ -202,7 +186,7 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { sample_rate = AudioInfo.SampleRate; num_samples = AudioInfo.NumSamples; if (channels <= 0 || sample_rate <= 0 || num_samples <= 0) - throw _T("FFmpegSource audio provider: sanity check failed, consult your local psychiatrist"); + throw AudioOpenError("sanity check failed, consult your local psychiatrist"); // FIXME: use the actual sample format too? // why not just bits_per_sample/8? maybe there's some oddball format with half bytes out there somewhere... @@ -212,33 +196,26 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { case 24: bytes_per_sample = 3; break; case 32: bytes_per_sample = 4; break; default: - throw _T("FFmpegSource audio provider: unknown or unsupported sample format"); + throw AudioOpenError("unknown or unsupported sample format"); } } - - /// @brief Destructor /// FFmpegSourceAudioProvider::~FFmpegSourceAudioProvider() { Close(); +} + +/// @brief Clean up +/// +void FFmpegSourceAudioProvider::Close() { + if (AudioSource) FFMS_DestroyAudioSource(AudioSource); #ifdef WIN32 if (COMInited) CoUninitialize(); #endif } - - -/// @brief Clean up -/// -void FFmpegSourceAudioProvider::Close() { - FFMS_DestroyAudioSource(AudioSource); - AudioSource = NULL; -} - - - /// @brief Get audio /// @param Buf /// @param Start @@ -246,12 +223,7 @@ void FFmpegSourceAudioProvider::Close() { /// void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) { if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) { - ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer); } } - - #endif /* WITH_FFMPEGSOURCE */ - - diff --git a/aegisub/src/audio_provider_ffmpegsource.h b/aegisub/src/audio_provider_ffmpegsource.h index d47c0d65f..3cb24e600 100644 --- a/aegisub/src/audio_provider_ffmpegsource.h +++ b/aegisub/src/audio_provider_ffmpegsource.h @@ -40,7 +40,7 @@ /// @class FFmpegSourceAudioProvider -/// @brief Implents audio loading with the FFMS library. +/// @brief Implements audio loading with the FFMS library. class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider { private: FFMS_AudioSource *AudioSource; /// audio source object @@ -48,7 +48,6 @@ private: char FFMSErrMsg[1024]; /// FFMS error message FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages - wxString ErrorMsg; /// wx-ified error message void Close(); void LoadAudio(wxString filename); @@ -61,6 +60,7 @@ public: /// @return Returns true. /// FFMS always delivers native endian samples. bool AreSamplesNativeEndian() const { return true; } + bool NeedsCache() const { return true; } virtual void GetAudio(void *buf, int64_t start, int64_t count); }; diff --git a/aegisub/src/audio_provider_hd.cpp b/aegisub/src/audio_provider_hd.cpp index 8ada334b8..a40578e9c 100644 --- a/aegisub/src/audio_provider_hd.cpp +++ b/aegisub/src/audio_provider_hd.cpp @@ -34,14 +34,9 @@ /// @ingroup audio_input /// - -/////////// -// Headers #include "config.h" - #ifndef AGI_PRE -#include #include #include #endif @@ -54,11 +49,11 @@ #include "standard_paths.h" #include "utils.h" - /// @brief Constructor /// @param source /// -HDAudioProvider::HDAudioProvider(AudioProvider *source) { +HDAudioProvider::HDAudioProvider(AudioProvider *src) { + std::auto_ptr source(src); // Copy parameters bytes_per_sample = source->GetBytesPerSample(); num_samples = source->GetNumSamples(); @@ -71,7 +66,7 @@ HDAudioProvider::HDAudioProvider(AudioProvider *source) { wxLongLong freespace; if (wxGetDiskSpace(DiskCachePath(), NULL, &freespace)) { if (num_samples * channels * bytes_per_sample > freespace) { - throw wxString(_T("Not enough free disk space in "))+DiskCachePath()+wxString(_T(" to cache the audio")); + throw AudioOpenError("Not enough free disk space in " + STD_STR(DiskCachePath()) + " to cache the audio"); } } @@ -79,7 +74,7 @@ HDAudioProvider::HDAudioProvider(AudioProvider *source) { diskCacheFilename = DiskCacheName(); file_cache.Create(diskCacheFilename,true,wxS_DEFAULT); file_cache.Open(diskCacheFilename,wxFile::read_write); - if (!file_cache.IsOpened()) throw _T("Unable to write to audio disk cache."); + if (!file_cache.IsOpened()) throw AudioOpenError("Unable to write to audio disk cache."); // Start progress volatile bool canceled = false; @@ -102,12 +97,10 @@ HDAudioProvider::HDAudioProvider(AudioProvider *source) { if (canceled) { file_cache.Close(); delete[] data; - throw wxString(_T("Audio loading cancelled by user")); + throw agi::UserCancelException("Audio loading cancelled by user"); } } - - /// @brief Destructor /// HDAudioProvider::~HDAudioProvider() { @@ -116,8 +109,6 @@ HDAudioProvider::~HDAudioProvider() { delete[] data; } - - /// @brief Get audio /// @param buf /// @param start @@ -152,8 +143,6 @@ void HDAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) { } } - - /// @brief Get disk cache path /// @return /// @@ -166,8 +155,6 @@ wxString HDAudioProvider::DiskCachePath() { return DecodeRelativePath(path,StandardPaths::DecodePath(_T("?user/"))); } - - /// @brief Get disk cache filename /// wxString HDAudioProvider::DiskCacheName() { @@ -180,17 +167,6 @@ wxString HDAudioProvider::DiskCacheName() { // File exists? wxString curStringTry = DiskCachePath() + wxString::Format(pattern.c_str(),i); if (!wxFile::Exists(curStringTry)) return curStringTry; - - // Exists, see if it can be opened (disabled because wx doesn't seem to lock the files...) - if (false) { - wxFile test(curStringTry,wxFile::write); - if (test.IsOpened()) { - test.Close(); - return curStringTry; - } - } } - return _T(""); + return L""; } - - diff --git a/aegisub/src/audio_provider_hd.h b/aegisub/src/audio_provider_hd.h index db39d6792..fd78d4587 100644 --- a/aegisub/src/audio_provider_hd.h +++ b/aegisub/src/audio_provider_hd.h @@ -47,8 +47,6 @@ /// /// DOCME class HDAudioProvider : public AudioProvider { -private: - /// DOCME wxMutex diskmutex; @@ -71,9 +69,6 @@ public: HDAudioProvider(AudioProvider *source); ~HDAudioProvider(); - - /// @brief DOCME - /// bool AreSamplesNativeEndian() const { return samples_native_endian; } void GetAudio(void *buf, int64_t start, int64_t count); diff --git a/aegisub/src/audio_provider_pcm.cpp b/aegisub/src/audio_provider_pcm.cpp index 3491e69be..33c83651d 100644 --- a/aegisub/src/audio_provider_pcm.cpp +++ b/aegisub/src/audio_provider_pcm.cpp @@ -64,7 +64,6 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) { #ifdef _WINDOWS - file_handle = CreateFile( filename.c_str(), FILE_READ_DATA, @@ -75,14 +74,13 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) 0); if (file_handle == INVALID_HANDLE_VALUE) { - wxLogWarning(_T("PCM audio provider: Could not open audio file for reading (%d)"), GetLastError()); - throw "PCM audio provider: Could not open audio file for reading"; + throw agi::FileNotFoundError(filename); } LARGE_INTEGER li_file_size = {0}; if (!GetFileSizeEx(file_handle, &li_file_size)) { CloseHandle(file_handle); - throw "PCM audio provider: Failed getting file size"; + throw AudioOpenError("Failed getting file size"); } file_size = li_file_size.QuadPart; @@ -95,7 +93,7 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) if (file_mapping == 0) { CloseHandle(file_handle); - throw "PCM audio provider: Failed creating file mapping"; + throw AudioOpenError("Failed creating file mapping"); } current_mapping = 0; @@ -105,50 +103,41 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) file_handle = open(filename.mb_str(*wxConvFileName), O_RDONLY); if (file_handle == -1) { - throw "PCM audio provider: Could not open audio file for reading"; + throw agi::FileNotFoundError(filename); } struct stat filestats; memset(&filestats, 0, sizeof(filestats)); if (fstat(file_handle, &filestats)) { close(file_handle); - throw "PCM audio provider: Could not stat file to get size"; + throw AudioOpenError("Could not stat file to get size"); } file_size = filestats.st_size; current_mapping = 0; - #endif } - - /// @brief DOCME /// PCMAudioProvider::~PCMAudioProvider() { #ifdef _WINDOWS - if (current_mapping) { UnmapViewOfFile(current_mapping); } CloseHandle(file_mapping); CloseHandle(file_handle); - #else - if (current_mapping) { munmap(current_mapping, mapping_length); } close(file_handle); - #endif } - - /// @brief DOCME /// @param range_start /// @param range_length @@ -157,14 +146,12 @@ PCMAudioProvider::~PCMAudioProvider() char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t range_length) { if (range_start + range_length > file_size) { - throw "PCM audio provider: Attempted to map beyond end of file"; + throw AudioDecodeError("Attempted to map beyond end of file"); } // Check whether the requested range is already visible if (!current_mapping || range_start < mapping_start || range_start+range_length > mapping_start+(int64_t)mapping_length) { - // It's not visible, change the current mapping - if (current_mapping) { #ifdef _WINDOWS UnmapViewOfFile(current_mapping); @@ -187,9 +174,8 @@ char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t rang // Make sure to always make a mapping at least as large as the requested range if ((int64_t)mapping_length < range_length) { if (range_length > (int64_t)(~(size_t)0)) - throw "PCM audio provider: Requested range larger than max size_t, cannot create view of file"; - else - mapping_length = range_length; + throw AudioDecodeError("Requested range larger than max size_t, cannot create view of file"); + mapping_length = range_length; } // But also make sure we don't try to make a mapping larger than the file if (mapping_start + (int64_t)mapping_length > file_size) @@ -211,9 +197,8 @@ char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t rang #endif if (!current_mapping) { - throw "PCM audio provider: Failed mapping a view of the file"; + throw AudioDecodeError("Failed mapping a view of the file"); } - } assert(current_mapping); @@ -226,8 +211,6 @@ char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t rang return ((char*)current_mapping) + rel_ofs; } - - /// @brief DOCME /// @param buf /// @param start @@ -256,9 +239,7 @@ void PCMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) buf = (char*)buf + samples_can_do * bytes_per_sample * channels; start += samples_can_do; count -= samples_can_do; - } - index++; } @@ -273,26 +254,17 @@ void PCMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) } } - -// RIFF WAV PCM provider -// Overview of RIFF WAV: - - /// DOCME /// @class RiffWavPCMAudioProvider -/// @brief DOCME +/// @brief RIFF WAV PCM provider /// -/// DOCME +/// Overview of RIFF WAV: class RiffWavPCMAudioProvider : public PCMAudioProvider { -private: - /// DOCME struct ChunkHeader { - - /// DOCME + /// Always "RIFF" char type[4]; - - /// DOCME + /// File size minus sizeof(ChunkHeader) (i.e. 8) uint32_t size; }; @@ -302,29 +274,31 @@ private: /// DOCME ChunkHeader ch; - /// DOCME + /// Always "WAVE" char format[4]; }; /// DOCME struct fmtChunk { - /// DOCME - uint16_t compression; // compression format used -- 0x0001 = PCM + /// compression format used + /// We support only PCM (0x1) + uint16_t compression; - /// DOCME + /// Number of channels uint16_t channels; - /// DOCME + /// Samples per second uint32_t samplerate; - /// DOCME - uint32_t avg_bytes_sec; // can't always be trusted + /// Bytes per second + /// can't always be trusted + uint32_t avg_bytes_sec; - /// DOCME + /// Bytes per sample uint16_t block_align; - /// DOCME + /// Bits per sample that are actually used; rest should be ignored uint16_t significant_bits_sample; // Here was supposed to be some more fields but we don't need them // and just skipping by the size of the struct wouldn't be safe @@ -359,16 +333,14 @@ public: filename = _filename; // Read header - // This should throw an exception if the mapping fails void *filestart = EnsureRangeAccessible(0, sizeof(RIFFChunk)); - assert(filestart); RIFFChunk &header = *(RIFFChunk*)filestart; // Check magic values if (!CheckFourcc(header.ch.type, "RIFF")) - throw "RIFF PCM WAV audio provider: File is not a RIFF file"; + throw AudioOpenError("File is not a RIFF file"); if (!CheckFourcc(header.format, "WAVE")) - throw "RIFF PCM WAV audio provider: File is not a RIFF WAV file"; + throw AudioOpenError("File is not a RIFF WAV file"); // Count how much more data we can have in the entire file // The first 4 bytes are already eaten by the header.format field @@ -391,12 +363,13 @@ public: filepos += sizeof(ch); if (CheckFourcc(ch.type, "fmt ")) { - if (got_fmt_header) throw "RIFF PCM WAV audio provider: Invalid file, multiple 'fmt ' chunks"; + if (got_fmt_header) throw AudioOpenError("Invalid file, multiple 'fmt ' chunks"); got_fmt_header = true; fmtChunk &fmt = *(fmtChunk*)EnsureRangeAccessible(filepos, sizeof(fmtChunk)); - if (Endian::LittleToMachine(fmt.compression) != 1) throw "RIFF PCM WAV audio provider: Can't use file, not PCM encoding"; + if (Endian::LittleToMachine(fmt.compression) != 1) + throw AudioOpenError("Can't use file, not PCM encoding"); // Set stuff inherited from the AudioProvider class sample_rate = Endian::LittleToMachine(fmt.samplerate); @@ -408,7 +381,7 @@ public: // This won't pick up 'data' chunks inside 'wavl' chunks // since the 'wavl' chunks wrap those. - if (!got_fmt_header) throw "RIFF PCM WAV audio provider: Found 'data' chunk before 'fmt ' chunk, file is invalid."; + if (!got_fmt_header) throw AudioOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid."); int64_t samples = Endian::LittleToMachine(ch.size) / bytes_per_sample; int64_t frames = samples / channels; @@ -431,8 +404,6 @@ public: } } - - /// @brief DOCME /// @return /// @@ -446,12 +417,6 @@ public: } }; - - -// Sony Wave64 audio provider -// Specs obtained at: - - /// DOCME static const uint8_t w64GuidRIFF[16] = { // {66666972-912E-11CF-A5D6-28DB04C10000} @@ -482,43 +447,25 @@ static const uint8_t w64Guiddata[16] = { /// DOCME /// @class Wave64AudioProvider -/// @brief DOCME +/// @brief Sony Wave64 audio provider /// -/// DOCME +/// http://www.vcs.de/fileadmin/user_upload/MBS/PDF/Whitepaper/Informations_about_Sony_Wave64.pdf class Wave64AudioProvider : public PCMAudioProvider { -private: // Here's some copy-paste from the FFmpegSource2 code - - /// DOCME - struct WaveFormatEx { - - /// DOCME - uint16_t wFormatTag; - - /// DOCME - uint16_t nChannels; - - /// DOCME - uint32_t nSamplesPerSec; - - /// DOCME - uint32_t nAvgBytesPerSec; - - /// DOCME - uint16_t nBlockAlign; - - /// DOCME - uint16_t wBitsPerSample; - - /// DOCME - uint16_t cbSize; + /// http://msdn.microsoft.com/en-us/library/dd757720(VS.85).aspx + struct WaveFormatEx { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t wBitsPerSample; + uint16_t cbSize; }; - /// DOCME struct RiffChunk { - /// DOCME uint8_t riff_guid[16]; @@ -532,7 +479,6 @@ private: /// DOCME struct FormatChunk { - /// DOCME uint8_t chunk_guid[16]; @@ -549,7 +495,6 @@ private: /// DOCME struct DataChunk { - /// DOCME uint8_t chunk_guid[16]; @@ -557,7 +502,6 @@ private: uint64_t chunk_size; }; - /// @brief DOCME /// @param guid1 /// @param guid2 @@ -581,7 +525,7 @@ public: int64_t smallest_possible_file = sizeof(RiffChunk) + sizeof(FormatChunk) + sizeof(DataChunk); if (file_size < smallest_possible_file) - throw "Wave64 audio provider: File is too small to be a Wave64 file"; + throw AudioOpenError("File is too small to be a Wave64 file"); // Read header // This should throw an exception if the mapping fails @@ -591,9 +535,9 @@ public: // Check magic values if (!CheckGuid(header.riff_guid, w64GuidRIFF)) - throw "Wave64 audio provider: File is not a Wave64 RIFF file"; + throw AudioOpenError("File is not a Wave64 RIFF file"); if (!CheckGuid(header.format_guid, w64GuidWAVE)) - throw "Wave64 audio provider: File is not a Wave64 WAVE file"; + throw AudioOpenError("File is not a Wave64 WAVE file"); // Count how much more data we can have in the entire file uint64_t data_left = Endian::LittleToMachine(header.file_size) - sizeof(RiffChunk); @@ -613,25 +557,24 @@ public: if (CheckGuid(chunk_guid, w64Guidfmt)) { if (got_fmt_header) - throw "Wave64 audio provider: Bad file, found more than one 'fmt' chunk"; + throw AudioOpenError("Bad file, found more than one 'fmt' chunk"); FormatChunk &fmt = *(FormatChunk*)EnsureRangeAccessible(filepos, sizeof(FormatChunk)); got_fmt_header = true; if (Endian::LittleToMachine(fmt.format.wFormatTag) == 3) - throw "Wave64 audio provider: File is IEEE 32 bit float format which isn't supported. Bug the developers if this matters."; + throw AudioOpenError("File is IEEE 32 bit float format which isn't supported. Bug the developers if this matters."); if (Endian::LittleToMachine(fmt.format.wFormatTag) != 1) - throw "Wave64 audio provider: Can't use file, not PCM encoding"; + throw AudioOpenError("Can't use file, not PCM encoding"); // Set stuff inherited from the AudioProvider class sample_rate = Endian::LittleToMachine(fmt.format.nSamplesPerSec); channels = Endian::LittleToMachine(fmt.format.nChannels); bytes_per_sample = (Endian::LittleToMachine(fmt.format.wBitsPerSample) + 7) / 8; // round up to nearest whole byte } - else if (CheckGuid(chunk_guid, w64Guiddata)) { if (!got_fmt_header) - throw "Wave64 audio provider: Found 'data' chunk before 'fmt ' chunk, file is invalid."; + throw AudioOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid."); int64_t samples = chunk_size / bytes_per_sample; int64_t frames = samples / channels; @@ -652,8 +595,6 @@ public: } } - - /// @brief DOCME /// @return /// @@ -667,38 +608,23 @@ public: } }; - - /// @brief DOCME /// @param filename /// AudioProvider *CreatePCMAudioProvider(const wxString &filename) { - AudioProvider *provider = 0; - - // Try Microsoft/IBM RIFF WAV + std::string msg; try { - provider = new RiffWavPCMAudioProvider(filename); - // don't bother trying with anything else if this works - return provider; + return new RiffWavPCMAudioProvider(filename); } - catch (const char *msg) { - LOG_E("audio/provider/pcm") << "Creating PCM WAV reader failed with message: '" << msg << "' Trying other providers"; - provider = 0; + catch (AudioOpenError const& err) { + msg = "RIFF PCM WAV audio provider: " + err.GetMessage(); } - - // Try Sony Wave64 try { - provider = new Wave64AudioProvider(filename); - return provider; + return new Wave64AudioProvider(filename); } - catch (const char *msg) { - LOG_E("audio/provider/pcm") << "Creating Wave64 reader failed with message: '" << msg << "' Trying other providers"; - provider = 0; + catch (AudioOpenError const& err) { + msg += "\nWave64 audio provider: " + err.GetMessage(); + throw AudioOpenError(msg); } - - // no providers could be created - return NULL; } - - diff --git a/aegisub/src/audio_provider_ram.cpp b/aegisub/src/audio_provider_ram.cpp index 7cba228c7..4f156ab30 100644 --- a/aegisub/src/audio_provider_ram.cpp +++ b/aegisub/src/audio_provider_ram.cpp @@ -34,9 +34,6 @@ /// @ingroup audio_input /// - -/////////// -// Headers #include "config.h" #include "audio_provider_ram.h" @@ -52,12 +49,11 @@ /// DOCME #define CacheBlockSize ((1 << CacheBits)) - - /// @brief Constructor /// @param source /// -RAMAudioProvider::RAMAudioProvider(AudioProvider *source) { +RAMAudioProvider::RAMAudioProvider(AudioProvider *src) { + std::auto_ptr source(src); // Init blockcache = NULL; blockcount = 0; @@ -79,7 +75,7 @@ RAMAudioProvider::RAMAudioProvider(AudioProvider *source) { } catch (...) { Clear(); - throw wxString(_T("Couldn't open audio, not enough ram available.")); + throw AudioOpenError("Couldn't open audio, not enough ram available."); } // Copy parameters @@ -98,7 +94,6 @@ RAMAudioProvider::RAMAudioProvider(AudioProvider *source) { // Read cache int readsize = CacheBlockSize / source->GetBytesPerSample(); for (int i=0;iGetAudio((char*)blockcache[i],i*readsize, i == blockcount-1 ? (num_samples - i*readsize) : readsize,env); source->GetAudio((char*)blockcache[i],i*readsize, i == blockcount-1 ? (source->GetNumSamples() - i*readsize) : readsize); progress->SetProgress(i,blockcount-1); } @@ -107,20 +102,16 @@ RAMAudioProvider::RAMAudioProvider(AudioProvider *source) { progress->Destroy(); if (canceled) { Clear(); - throw wxString(_T("Audio loading cancelled by user")); + throw agi::UserCancelException("Audio loading cancelled by user"); } } - - /// @brief Destructor /// RAMAudioProvider::~RAMAudioProvider() { Clear(); } - - /// @brief Clear /// void RAMAudioProvider::Clear() { @@ -135,8 +126,6 @@ void RAMAudioProvider::Clear() { blockcount = 0; } - - /// @brief Get audio /// @param buf /// @param start @@ -185,5 +174,3 @@ void RAMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) { } } } - - diff --git a/aegisub/src/audio_renderer_spectrum.cpp b/aegisub/src/audio_renderer_spectrum.cpp index de95cedd5..ab96542d8 100644 --- a/aegisub/src/audio_renderer_spectrum.cpp +++ b/aegisub/src/audio_renderer_spectrum.cpp @@ -260,7 +260,7 @@ public: // Start sample number of the next line calculated // line_length is half of the number of samples used to calculate a line, since half of the output from // a Fourier transform of real data is redundant, and not interesting for the purpose of creating - // a frequenmcy/power spectrum. + // a frequency/power spectrum. int64_t sample = start * line_length*2 + overlap*overlap_offset; long len = length; diff --git a/aegisub/src/auto4_base.cpp b/aegisub/src/auto4_base.cpp index dd7dc91e1..0f7eeeede 100644 --- a/aegisub/src/auto4_base.cpp +++ b/aegisub/src/auto4_base.cpp @@ -34,7 +34,6 @@ /// @ingroup scripting /// - #include "config.h" #ifdef WITH_AUTOMATION @@ -47,15 +46,11 @@ #include #include -#include #include #include #include -#include #include #include -#include -#include #include #include #endif @@ -73,12 +68,8 @@ #include "standard_paths.h" #include "string_codec.h" - - /// DOCME namespace Automation4 { - - /// @brief DOCME /// @param style /// @param text diff --git a/aegisub/src/auto4_lua.h b/aegisub/src/auto4_lua.h index e1c2e9c37..ad7b6ea2f 100644 --- a/aegisub/src/auto4_lua.h +++ b/aegisub/src/auto4_lua.h @@ -34,9 +34,6 @@ /// @ingroup scripting /// - - - #ifndef AGI_PRE #include #include @@ -47,7 +44,6 @@ #ifdef __WINDOWS__ #include "../../contrib/lua51/src/lua.h" -#include "../../contrib/lua51/src/lauxlib.h" #else #include #endif @@ -55,11 +51,8 @@ class wxWindow; namespace agi { namespace vfr { class Framerate; } } - /// DOCME namespace Automation4 { - - /// @class LuaAssFile /// @brief Object wrapping an AssFile object for modification through Lua class LuaAssFile { diff --git a/aegisub/src/avisynth_wrap.cpp b/aegisub/src/avisynth_wrap.cpp index cf11a3ca0..01f98e0fc 100644 --- a/aegisub/src/avisynth_wrap.cpp +++ b/aegisub/src/avisynth_wrap.cpp @@ -46,6 +46,7 @@ HINSTANCE AviSynthWrapper::hLib = NULL; IScriptEnvironment *AviSynthWrapper::env = NULL; wxMutex AviSynthWrapper::AviSynthMutex; + /// @brief AviSynth constructor /// AviSynthWrapper::AviSynthWrapper() { @@ -96,3 +97,4 @@ IScriptEnvironment *AviSynthWrapper::GetEnv() { return env; } #endif + diff --git a/aegisub/src/compat.h b/aegisub/src/compat.h index af1609e01..cbabbbee6 100644 --- a/aegisub/src/compat.h +++ b/aegisub/src/compat.h @@ -8,7 +8,7 @@ #include -#define STD_STR(x) std::string(x.utf8_str()) +#define STD_STR(x) std::string((x).utf8_str()) inline wxColour lagi_wxColour(const agi::Colour &colour) { return wxColour(colour); } inline wxString lagi_wxString(const std::string &str) { return wxString(str.c_str(), wxConvUTF8); } diff --git a/aegisub/src/ffmpegsource_common.cpp b/aegisub/src/ffmpegsource_common.cpp index 3f24fd848..2034e9e35 100644 --- a/aegisub/src/ffmpegsource_common.cpp +++ b/aegisub/src/ffmpegsource_common.cpp @@ -38,8 +38,6 @@ #ifdef WITH_FFMPEGSOURCE -/////////// -// Headers #ifndef AGI_PRE #include #include @@ -98,7 +96,8 @@ FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxStri // set up progress dialog callback IndexingProgressDialog Progress; Progress.IndexingCanceled = false; - Progress.ProgressDialog = new DialogProgress(AegisubApp::Get()->frame, _("Indexing"), &Progress.IndexingCanceled, + Progress.ProgressDialog = new DialogProgress(AegisubApp::Get()->frame, + _("Indexing"), &Progress.IndexingCanceled, _("Reading timecodes and frame/sample data"), 0, 1); Progress.ProgressDialog->Show(); Progress.ProgressDialog->SetProgress(0,1); @@ -106,12 +105,14 @@ FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxStri // index all audio tracks FFMS_Index *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, IndexEH, FFmpegSourceProvider::UpdateIndexingProgress, &Progress, &ErrInfo); + Progress.ProgressDialog->Destroy(); + if (Progress.IndexingCanceled) { + throw agi::UserCancelException("indexing cancelled by user"); + } if (Index == NULL) { - Progress.ProgressDialog->Destroy(); MsgString.Append(_T("Failed to index: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8)); throw MsgString; } - Progress.ProgressDialog->Destroy(); // write index to disk for later use // ignore write errors for now @@ -125,8 +126,6 @@ FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxStri return Index; } - - /// @brief Finds all tracks of the given type and return their track numbers and respective codec names /// @param Indexer The indexer object representing the source file /// @param Type The track type to look for @@ -141,12 +140,9 @@ std::map FFmpegSourceProvider::GetTracksOfType(FFMS_Indexer *Index TrackList.insert(std::pair(i, CodecName)); } } - return TrackList; } - - /// @brief Ask user for which track he wants to load /// @param TrackList A std::map with the track numbers as keys and codec names as values /// @param Type The track type to ask about diff --git a/aegisub/src/ffmpegsource_common.h b/aegisub/src/ffmpegsource_common.h index f9199e3c2..6f63712d8 100644 --- a/aegisub/src/ffmpegsource_common.h +++ b/aegisub/src/ffmpegsource_common.h @@ -36,8 +36,6 @@ #ifdef WITH_FFMPEGSOURCE -/////////// -// Headers #ifndef AGI_PRE #include @@ -48,15 +46,12 @@ #include #include "dialog_progress.h" -#include "include/aegisub/aegisub.h" - /// Index all tracks #define FFMS_TRACKMASK_ALL -1 /// Index no tracks #define FFMS_TRACKMASK_NONE 0 - /// @class FFmpegSourceProvider /// @brief Base class for FFMS2 source providers; contains common functions etc class FFmpegSourceProvider { @@ -97,8 +92,6 @@ public: virtual ~FFmpegSourceProvider() {} }; - - /// @class FFmpegSourceCacheCleaner /// @brief Implements index cache cleaning functionality for the FFMS2 providers class FFmpegSourceCacheCleaner : public wxThread { @@ -112,8 +105,5 @@ public: wxThread::ExitCode Entry(); }; - #endif /* WITH_FFMPEGSOURCE */ - - diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 2c18d7f3d..ff9d5a1de 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -673,7 +673,7 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { } // Setup - bool isFile = (filename != _T("")); + bool isFile = !filename.empty(); bool isBinary = false; // Load @@ -681,7 +681,9 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { // File exists? if (isFile) { wxFileName fileCheck(filename); - if (!fileCheck.FileExists()) throw _T("Selected file does not exist."); + if (!fileCheck.FileExists()) { + throw agi::FileNotFoundError(STD_STR(filename)); + } // Make sure that file isn't actually a timecode file try { @@ -697,8 +699,8 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { } } catch (...) { - // if trying to load the file as timecodes fails it's fairly safe to assume that - // it is in fact not a timecode file + // if trying to load the file as timecodes fails it's fairly + // safe to assume that it is in fact not a timecode file } } @@ -720,6 +722,11 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { StandardPaths::SetPathValue(_T("?script"),_T("")); } } + catch (agi::FileNotFoundError const&) { + wxMessageBox(filename + L" not found.", L"Error", wxOK | wxICON_ERROR, NULL); + config::mru->Remove("Subtitle", STD_STR(filename)); + return; + } catch (const wchar_t *err) { wxMessageBox(wxString(err), _T("Error"), wxOK | wxICON_ERROR, NULL); return; @@ -773,7 +780,7 @@ bool FrameMain::SaveSubtitles(bool saveas,bool withCharset) { VideoContext::Get()->Stop(); wxString path = lagi_wxString(OPT_GET("Path/Last/Subtitles")->GetString()); wxFileName origPath(ass->filename); - filename = wxFileSelector(_("Save subtitles file"),path,origPath.GetName() + _T(".ass"),_T("ass"),AssFile::GetWildcardList(1),wxFD_SAVE | wxFD_OVERWRITE_PROMPT,this); + filename = wxFileSelector(_("Save subtitles file"),path,origPath.GetName() + _T(".ass"),_T("ass"),AssFile::GetWildcardList(1),wxFD_SAVE | wxFD_OVERWRITE_PROMPT,this); } // Actually save diff --git a/aegisub/src/hotkeys.cpp b/aegisub/src/hotkeys.cpp index 9833fce95..d19986ea6 100644 --- a/aegisub/src/hotkeys.cpp +++ b/aegisub/src/hotkeys.cpp @@ -34,15 +34,11 @@ /// @ingroup main_ui /// - -/////////// -// Headers #include "config.h" #ifndef AGI_PRE #include -#include #include #include #endif @@ -51,7 +47,6 @@ #include "text_file_reader.h" #include "text_file_writer.h" - /// @brief Constructors HotkeyType ////////////////////////////////// /// HotkeyType::HotkeyType() { @@ -59,7 +54,6 @@ HotkeyType::HotkeyType() { keycode = 0; } - /// @brief DOCME /// @param text /// @param name @@ -69,8 +63,6 @@ HotkeyType::HotkeyType(wxString text,wxString name) { origName = name; } - - /// @brief Get string of hotkey /// @return /// @@ -88,8 +80,6 @@ wxString HotkeyType::GetText() const { return text; } - - /// @brief Parse text into hotkey /// @param text /// @@ -150,8 +140,6 @@ void HotkeyType::Parse(wxString text) { } } - - /// DOCME std::map HotkeyType::keyName; @@ -172,8 +160,6 @@ wxString HotkeyType::GetKeyName(int keycode) { else return wxString::Format(_T("[%i]"),keycode); } - - /// @brief Fill map /// @return /// @@ -234,29 +220,21 @@ void HotkeyType::FillMap() { } } - - /// DOCME HotkeyManager Hotkeys; - - /// @brief Constructor /// HotkeyManager::HotkeyManager() { modified = false; } - - /// @brief Destructor /// HotkeyManager::~HotkeyManager() { key.clear(); } - - /// @brief Save /// @return /// @@ -278,8 +256,6 @@ void HotkeyManager::Save() { modified = false; } - - /// @brief Load /// @return /// @@ -353,14 +329,11 @@ void HotkeyManager::Load() { Save(); } - - /// @brief Set all hotkeys to the default values /// void HotkeyManager::LoadDefaults() { modified = true; - /// @note () is used here instead of _T(). This is done so the strings can be extracted. /// However, since this function is called before locale is set, it won't ever be translated. /// Keep this in mind: THESE CANNOT BE TRANSLATED HERE! @@ -503,8 +476,6 @@ void HotkeyManager::LoadDefaults() { SetHotkey(_("Visual Tool Vector Clip"), _T("J")); } - - /// @brief Set hotkey /// @param function /// @param hotkey @@ -514,7 +485,6 @@ void HotkeyManager::SetHotkey(wxString function,HotkeyType hotkey) { modified = true; } - /// @brief DOCME /// @param function /// @param hotkey @@ -524,8 +494,6 @@ void HotkeyManager::SetHotkey(wxString function,wxString hotkey) { modified = true; } - - /// @brief Set file /// @param file /// @@ -533,8 +501,6 @@ void HotkeyManager::SetFile(wxString file) { filename = file; } - - /// @brief Get hotkey as text /// @param function /// @return @@ -547,8 +513,6 @@ const wxString HotkeyManager::GetText(wxString function) const { else throw _T("Hotkey not defined"); } - - /// @brief Get hotkey as accelerator entry /// @param function /// @param id @@ -565,8 +529,6 @@ wxAcceleratorEntry HotkeyManager::GetAccelerator(wxString function,int id) const else throw _T("Hotkey not defined"); } - - /// @brief Set last key pressed /// @param keypress /// @param ctrl @@ -581,8 +543,6 @@ void HotkeyManager::SetPressed(int keypress,bool ctrl,bool alt,bool shift) { if (shift) lastMod |= wxACCEL_SHIFT; } - - /// @brief Is pressed? /// @param function /// @return @@ -596,8 +556,6 @@ bool HotkeyManager::IsPressed(wxString function) const { else throw _T("Hotkey not defined"); } - - /// @brief Search for a hotkey /// @param keycode /// @param mod diff --git a/aegisub/src/include/aegisub/audio_provider.h b/aegisub/src/include/aegisub/audio_provider.h index 9e646f4ae..b52d369e9 100644 --- a/aegisub/src/include/aegisub/audio_provider.h +++ b/aegisub/src/include/aegisub/audio_provider.h @@ -40,6 +40,7 @@ #include #endif +#include #include "factory_manager.h" /// @class AudioProvider @@ -88,6 +89,9 @@ public: virtual bool AreSamplesNativeEndian() const = 0; void GetWaveForm(int *min,int *peak,int64_t start,int w,int h,int samples,float scale); + + /// @brief Does this provider benefit from external caching? + virtual bool NeedsCache() const { return false; } }; /// DOCME @@ -100,3 +104,9 @@ public: static void RegisterProviders(); static AudioProvider *GetProvider(wxString filename, int cache=-1); }; + +DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception); +DEFINE_SIMPLE_EXCEPTION_NOINNER(AudioOpenError, AudioProviderError, "audio/open/failed"); + +/// Error of some sort occurred while decoding a frame +DEFINE_SIMPLE_EXCEPTION_NOINNER(AudioDecodeError, AudioProviderError, "audio/error"); diff --git a/aegisub/src/include/aegisub/video_provider.h b/aegisub/src/include/aegisub/video_provider.h index c56152be5..a658f5e32 100644 --- a/aegisub/src/include/aegisub/video_provider.h +++ b/aegisub/src/include/aegisub/video_provider.h @@ -37,6 +37,7 @@ #pragma once #include "video_frame.h" +#include #include /// @class VideoProvider @@ -69,3 +70,12 @@ public: /// @return Returns true if caching is desired, false otherwise. virtual bool WantsCaching() const { return false; } }; + +DEFINE_BASE_EXCEPTION_NOINNER(VideoProviderError, agi::Exception); +/// File could be opened, but is not a supported format +DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoNotSupported, VideoProviderError, "video/open/notsupported"); +/// File appears to be a supported format, but could not be opened +DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoOpenError, VideoProviderError, "video/open/failed"); + +/// Error of some sort occurred while decoding a frame +DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoDecodeError, VideoProviderError, "video/error"); diff --git a/aegisub/src/mkv_wrap.cpp b/aegisub/src/mkv_wrap.cpp index 80bb6e1bc..980b3cb0c 100644 --- a/aegisub/src/mkv_wrap.cpp +++ b/aegisub/src/mkv_wrap.cpp @@ -38,7 +38,6 @@ #ifndef AGI_PRE #include -#include #include #include @@ -54,33 +53,24 @@ #include #include "mkv_wrap.h" - /// DOCME MatroskaWrapper MatroskaWrapper::wrapper; - - /// DOCME #define CACHESIZE 65536 - - /// @brief Constructor /// MatroskaWrapper::MatroskaWrapper() { file = NULL; } - - /// @brief Destructor /// MatroskaWrapper::~MatroskaWrapper() { Close(); } - - /// @brief Open file /// @param filename /// @param parse @@ -112,8 +102,6 @@ void MatroskaWrapper::Open(wxString filename,bool parse) { } } - - /// @brief Close file /// @return /// @@ -127,8 +115,6 @@ void MatroskaWrapper::Close() { timecodes.clear(); } - - /// @brief Return keyframes /// @return /// @@ -136,8 +122,6 @@ std::vector MatroskaWrapper::GetKeyFrames() { return keyFrames; } - - /// @brief Comparison operator /// @param t1 /// @param t2 @@ -147,8 +131,6 @@ bool operator < (MkvFrame &t1, MkvFrame &t2) { return t1.time < t2.time; } - - /// @brief Actually parse /// void MatroskaWrapper::Parse() { @@ -200,7 +182,7 @@ void MatroskaWrapper::Parse() { // Cancelled? if (canceled) { Close(); - throw _T("Canceled"); + throw agi::UserCancelException("Canceled"); } // Identical to (frameN % 2048) == 0, @@ -257,7 +239,6 @@ void MatroskaWrapper::Parse() { } } - static int mkv_round(double num) { return (int)(num + .5); } @@ -275,8 +256,6 @@ void MatroskaWrapper::SetToTimecodes(agi::vfr::Framerate &target) { target = agi::vfr::Framerate(times); } - - /// @brief Get subtitles /// @param target /// @@ -330,7 +309,7 @@ void MatroskaWrapper::GetSubtitles(AssFile *target) { if (choice == -1) { target->LoadDefault(true); Close(); - throw _T("Canceled."); + throw agi::UserCancelException("cancelled"); } trackToRead = tracksFound[choice]; } @@ -398,7 +377,7 @@ void MatroskaWrapper::GetSubtitles(AssFile *target) { if (canceled) { target->LoadDefault(true); Close(); - throw _T("Canceled"); + throw agi::UserCancelException("cancelled"); } // Read to temp @@ -525,7 +504,6 @@ bool MatroskaWrapper::HasSubtitles(wxString const& filename) { #define std_ftell ftello #endif - /// @brief STDIO class /// @param _st /// @param pos @@ -577,7 +555,6 @@ longlong StdIoScan(InputStream *_st, ulonglong start, unsigned signature) { return -1; } - /// @brief This is used to limit readahead. /// @param _st /// @return Cache size @@ -586,7 +563,6 @@ unsigned StdIoGetCacheSize(InputStream *_st) { return CACHESIZE; } - /// @brief Get last error message /// @param _st /// @return Last error message @@ -596,7 +572,6 @@ const char *StdIoGetLastError(InputStream *_st) { return strerror(st->error); } - /// @brief Memory allocation, this is done via stdlib /// @param _st /// @param size @@ -606,7 +581,6 @@ void *StdIoMalloc(InputStream *_st, size_t size) { return malloc(size); } - /// @brief DOCME /// @param _st /// @param mem @@ -617,7 +591,6 @@ void *StdIoRealloc(InputStream *_st, void *mem, size_t size) { return realloc(mem,size); } - /// @brief DOCME /// @param _st /// @param mem @@ -626,7 +599,6 @@ void StdIoFree(InputStream *_st, void *mem) { free(mem); } - /// @brief DOCME /// @param _st /// @param cur @@ -637,7 +609,6 @@ int StdIoProgress(InputStream *_st, ulonglong cur, ulonglong max) { return 1; } - /// @brief DOCME /// @param _st /// @return @@ -652,7 +623,6 @@ longlong StdIoGetFileSize(InputStream *_st) { return epos; } - /// @brief DOCME /// @param filename /// @@ -673,4 +643,3 @@ MkvStdIO::MkvStdIO(wxString filename) { } } - diff --git a/aegisub/src/mkv_wrap.h b/aegisub/src/mkv_wrap.h index 47e10dc76..11931c31a 100644 --- a/aegisub/src/mkv_wrap.h +++ b/aegisub/src/mkv_wrap.h @@ -64,8 +64,6 @@ public: int error; }; - - /// DOCME /// @class MkvFrame /// @brief DOCME @@ -83,7 +81,6 @@ public: /// DOCME int64_t filePos; - /// @brief DOCME /// MkvFrame() { @@ -107,7 +104,6 @@ public: bool operator < (MkvFrame &t1, MkvFrame &t2); - /// DOCME /// @class MatroskaWrapper /// @brief DOCME @@ -142,7 +138,6 @@ public: MatroskaWrapper(); ~MatroskaWrapper(); - /// @brief DOCME /// @return /// @@ -166,9 +161,6 @@ public: void GetSubtitles(AssFile *target); static bool HasSubtitles(wxString const& filename); - /// DOCME static MatroskaWrapper wrapper; }; - - diff --git a/aegisub/src/spellchecker_hunspell.cpp b/aegisub/src/spellchecker_hunspell.cpp index 5bbf40c40..246d8c18f 100644 --- a/aegisub/src/spellchecker_hunspell.cpp +++ b/aegisub/src/spellchecker_hunspell.cpp @@ -34,12 +34,8 @@ /// @ingroup spelling /// - -/////////// -// Headers #include "config.h" - #ifdef WITH_HUNSPELL #ifndef AGI_PRE @@ -51,7 +47,6 @@ #endif #include -#include #include "charset_conv.h" #include "compat.h" @@ -62,7 +57,6 @@ #include "text_file_writer.h" #include "utils.h" - /// @brief Constructor HunspellSpellChecker::HunspellSpellChecker() { hunspell = NULL; @@ -71,15 +65,11 @@ HunspellSpellChecker::HunspellSpellChecker() { SetLanguage(lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString())); } - - /// @brief Destructor HunspellSpellChecker::~HunspellSpellChecker() { Reset(); } - - /// @brief Reset spelling library void HunspellSpellChecker::Reset() { delete hunspell; @@ -92,8 +82,6 @@ void HunspellSpellChecker::Reset() { dicpath.Clear(); } - - /// @brief Can add to dictionary? /// @param word Word to check. /// @return Whether word can be added or not. @@ -109,8 +97,6 @@ bool HunspellSpellChecker::CanAddWord(wxString word) { } } - - /// @brief Add word to dictionary /// @param word Word to add. /// @@ -171,8 +157,6 @@ void HunspellSpellChecker::AddWord(wxString word) { } } - - /// @brief Check if the word is valid. /// @param word Word to check /// @return Whether word is valid or not. @@ -187,8 +171,6 @@ bool HunspellSpellChecker::CheckWord(wxString word) { } } - - /// @brief Get suggestions for word. /// @param word Word to get suggestions for /// @return List of suggestions @@ -217,8 +199,6 @@ wxArrayString HunspellSpellChecker::GetSuggestions(wxString word) { return suggestions; } - - /// @brief Get list of available dictionaries. /// @return List of available dictionaries /// @@ -252,8 +232,6 @@ wxArrayString HunspellSpellChecker::GetLanguageList() { return list; } - - /// @brief Set language. /// @param language Language to set /// diff --git a/aegisub/src/subtitles_provider_csri.cpp b/aegisub/src/subtitles_provider_csri.cpp index cb779bd9f..e55e687b5 100644 --- a/aegisub/src/subtitles_provider_csri.cpp +++ b/aegisub/src/subtitles_provider_csri.cpp @@ -42,6 +42,7 @@ #include "subtitles_provider_csri.h" #include "text_file_writer.h" #include "video_context.h" +#include "video_frame.h" /// @brief Constructor /// @param type diff --git a/aegisub/src/text_file_reader.cpp b/aegisub/src/text_file_reader.cpp index 25725858c..13b1dee34 100644 --- a/aegisub/src/text_file_reader.cpp +++ b/aegisub/src/text_file_reader.cpp @@ -41,10 +41,7 @@ #include #include -#include #include - -#include #endif #include diff --git a/aegisub/src/threaded_frame_source.cpp b/aegisub/src/threaded_frame_source.cpp index dd9d7f85f..50dc1f5b5 100644 --- a/aegisub/src/threaded_frame_source.cpp +++ b/aegisub/src/threaded_frame_source.cpp @@ -67,8 +67,7 @@ AegiVideoFrame const& ThreadedFrameSource::ProcFrame(int frameNum, double time, try { frame->CopyFrom(videoProvider->GetFrame(frameNum)); } - catch (const wchar_t *err) { throw VideoProviderErrorEvent(err); } - catch (wxString const& err) { throw VideoProviderErrorEvent(err); } + catch (VideoProviderError const& err) { throw VideoProviderErrorEvent(err); } } // This deliberately results in a call to LoadSubtitles while a render @@ -107,7 +106,6 @@ AegiVideoFrame const& ThreadedFrameSource::ProcFrame(int frameNum, double time, } } } - catch (const wchar_t *err) { throw SubtitlesProviderErrorEvent(err); } catch (wxString const& err) { throw SubtitlesProviderErrorEvent(err); } provider->DrawSubtitles(*frame, time); @@ -200,13 +198,13 @@ wxDEFINE_EVENT(EVT_FRAME_READY, FrameReadyEvent); wxDEFINE_EVENT(EVT_VIDEO_ERROR, VideoProviderErrorEvent); wxDEFINE_EVENT(EVT_SUBTITLES_ERROR, SubtitlesProviderErrorEvent); -VideoProviderErrorEvent::VideoProviderErrorEvent(wxString msg) -: agi::Exception(STD_STR(msg), NULL) +VideoProviderErrorEvent::VideoProviderErrorEvent(VideoProviderError const& err) +: agi::Exception(err.GetMessage(), &err) { SetEventType(EVT_VIDEO_ERROR); } -SubtitlesProviderErrorEvent::SubtitlesProviderErrorEvent(wxString msg) -: agi::Exception(STD_STR(msg), NULL) +SubtitlesProviderErrorEvent::SubtitlesProviderErrorEvent(wxString err) +: agi::Exception(err, NULL) { SetEventType(EVT_SUBTITLES_ERROR); } diff --git a/aegisub/src/threaded_frame_source.h b/aegisub/src/threaded_frame_source.h index a7b84ffdd..85870e1ef 100644 --- a/aegisub/src/threaded_frame_source.h +++ b/aegisub/src/threaded_frame_source.h @@ -47,6 +47,7 @@ class AssFile; class SubtitlesProvider; class VideoProvider; +class VideoProviderError; /// @class ThreadedFrameSource /// @brief An asynchronous video decoding and subtitle rendering wrapper @@ -155,7 +156,7 @@ public: const char * GetName() const { return "video/error"; } wxEvent *Clone() const { return new VideoProviderErrorEvent(*this); }; agi::Exception *Copy() const { return new VideoProviderErrorEvent(*this); }; - VideoProviderErrorEvent(wxString msg); + VideoProviderErrorEvent(VideoProviderError const& err); }; class SubtitlesProviderErrorEvent : public wxEvent, public agi::Exception { diff --git a/aegisub/src/video_box.cpp b/aegisub/src/video_box.cpp index 70d43f2b4..7d5155d08 100644 --- a/aegisub/src/video_box.cpp +++ b/aegisub/src/video_box.cpp @@ -34,9 +34,6 @@ /// @ingroup main_ui video /// - -//////////// -// Includes #include "config.h" #ifndef AGI_PRE @@ -44,7 +41,6 @@ #include #include #include -#include #endif #include "ass_dialogue.h" diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 1fdc41e86..5c340c606 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -74,6 +74,7 @@ #include "video_box.h" #include "video_context.h" #include "video_display.h" +#include "video_frame.h" /// IDs enum { @@ -196,11 +197,13 @@ void VideoContext::SetVideo(const wxString &filename) { UpdateDisplays(true); } - catch (const wchar_t *e) { - wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK); + catch (agi::UserCancelException const&) { } + catch (agi::FileNotAccessibleError const& err) { + config::mru->Remove("Video", STD_STR(filename)); + wxMessageBox(lagi_wxString(err.GetMessage()), L"Error setting video", wxICON_ERROR | wxOK); } - catch (const wxString &e) { - wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK); + catch (VideoProviderError const& err) { + wxMessageBox(lagi_wxString(err.GetMessage()), L"Error setting video", wxICON_ERROR | wxOK); } } diff --git a/aegisub/src/video_context.h b/aegisub/src/video_context.h index 96940f01c..9093f1949 100644 --- a/aegisub/src/video_context.h +++ b/aegisub/src/video_context.h @@ -49,17 +49,9 @@ #error "Aegisub requires wxWidgets to be compiled with OpenGL support." #endif -#ifdef __APPLE__ -#include -#include -#else -#include -#include -#endif - #include -#include "video_frame.h" +class AegiVideoFrame; class SubtitlesGrid; class AudioProvider; class AudioDisplay; diff --git a/aegisub/src/video_provider_avs.cpp b/aegisub/src/video_provider_avs.cpp index fe5bb1c06..3185b649d 100644 --- a/aegisub/src/video_provider_avs.cpp +++ b/aegisub/src/video_provider_avs.cpp @@ -43,6 +43,7 @@ #endif #include "charset_conv.h" +#include "compat.h" #include "gl_wrap.h" #include #include "mkv_wrap.h" @@ -51,174 +52,159 @@ #include "video_context.h" #include "video_provider_avs.h" - /// @brief Constructor /// @param _filename /// -AvisynthVideoProvider::AvisynthVideoProvider(wxString _filename) { - bool mpeg2dec3_priority = true; - RGB32Video = NULL; - num_frames = 0; - last_fnum = -1; - KeyFrames.clear(); - - RGB32Video = OpenVideo(_filename,mpeg2dec3_priority); +AvisynthVideoProvider::AvisynthVideoProvider(wxString filename) try +: usedDirectShow(false) +, decoderName(_("Unknown")) +, num_frames(0) +, last_fnum(-1) +, RGB32Video(NULL) +{ + RGB32Video = OpenVideo(filename); vi = RGB32Video->GetVideoInfo(); } +catch (AvisynthError const& err) { + throw VideoOpenError("Avisynth error: " + std::string(err.msg)); +} /// @brief Destructor -/// AvisynthVideoProvider::~AvisynthVideoProvider() { iframe.Clear(); } -/// @brief Actually open the video into Avisynth -/// @param _filename -/// @param mpeg2dec3_priority -/// @return -/// -PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priority) { - wxMutexLocker lock(AviSynthMutex); - AVSValue script; +AVSValue AvisynthVideoProvider::Open(wxFileName const& fname, wxString const& extension) { + char *videoFilename = env->SaveString(fname.GetShortPath().mb_str(csConvLocal)); - usedDirectShow = false; - decoderName = _("Unknown"); + // Avisynth file, just import it + if (extension == L".avs") { + LOG_I("avisynth/video") << "Opening .avs file with Import"; + decoderName = L"Import"; + return env->Invoke("Import", videoFilename); + } - wxString extension = _filename.Right(4); - extension.LowerCase(); - - try { - // Prepare filename - //char *videoFilename = env->SaveString(_filename.mb_str(wxConvLocal)); - wxFileName fname(_filename); - char *videoFilename = env->SaveString(fname.GetShortPath().mb_str(csConvLocal)); - - // Avisynth file, just import it - if (extension == _T(".avs")) { - LOG_I("avisynth/video") << "Opening .avs file with Import"; - script = env->Invoke("Import", videoFilename); - decoderName = _T("Import"); + // Open avi file with AviSource + if (extension == L".avi") { + LOG_I("avisynth/video") << "Opening .avi file with AviSource"; + try { + const char *argnames[2] = { 0, "audio" }; + AVSValue args[2] = { videoFilename, false }; + decoderName = L"AviSource"; + return env->Invoke("AviSource", AVSValue(args,2), argnames); } - // Open avi file with AviSource - else if (extension == _T(".avi")) { - LOG_I("avisynth/video") << "Opening .avi file with AviSource"; - try { - const char *argnames[2] = { 0, "audio" }; - AVSValue args[2] = { videoFilename, false }; - script = env->Invoke("AviSource", AVSValue(args,2), argnames); - decoderName = _T("AviSource"); - } - - // On Failure, fallback to DSS - catch (AvisynthError &) { - LOG_I("avisynth/video") << "Failed to open .avi file with AviSource, switching to DirectShowSource"; - goto directshowOpen; - } - } - - // Open d2v with mpeg2dec3 - else if (extension == _T(".d2v") && env->FunctionExists("Mpeg2Dec3_Mpeg2Source") && mpeg2dec3_priority) { - LOG_I("avisynth/video") << "Opening .d2v file with Mpeg2Dec3_Mpeg2Source"; - script = env->Invoke("Mpeg2Dec3_Mpeg2Source", videoFilename); - decoderName = _T("Mpeg2Dec3_Mpeg2Source"); - - //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this - if (env->FunctionExists("SetPlanarLegacyAlignment")) { - AVSValue args[2] = { script, true }; - script = env->Invoke("SetPlanarLegacyAlignment", AVSValue(args,2)); - } - } - - // If that fails, try opening it with DGDecode - else if (extension == _T(".d2v") && env->FunctionExists("DGDecode_Mpeg2Source")) { - LOG_I("avisynth/video") << "Opening .d2v file with DGDecode_Mpeg2Source"; - script = env->Invoke("Mpeg2Source", videoFilename); - decoderName = _T("DGDecode_Mpeg2Source"); - - //note that DGDecode will also have issues like if the version is too ancient but no sane person - //would use that anyway - } - - else if (extension == _T(".d2v") && env->FunctionExists("Mpeg2Source")) { - LOG_I("avisynth/video") << "Opening .d2v file with other Mpeg2Source"; - script = env->Invoke("Mpeg2Source", videoFilename); - decoderName = _T("Mpeg2Source"); - - //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this - if (env->FunctionExists("SetPlanarLegacyAlignment")) - script = env->Invoke("SetPlanarLegacyAlignment", script); - } - - // Some other format, such as mkv, mp4, ogm... try both flavors of DirectShowSource - else { - directshowOpen: - - // Try loading DirectShowSource2 - bool dss2 = false; - if (env->FunctionExists("dss2")) dss2 = true; - if (!dss2) { - wxFileName dss2path(StandardPaths::DecodePath(_T("?data/avss.dll"))); - if (dss2path.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dss2path.GetFullPath().mb_str(csConvLocal))); - } - } - - // If DSS2 loaded properly, try using it - dss2 = false; - if (env->FunctionExists("dss2")) { - LOG_I("avisynth/video") << "Opening video with DSS2"; - script = env->Invoke("DSS2", videoFilename); - dss2 = true; - decoderName = _T("DSS2"); - } - - // Try DirectShowSource - if (!dss2) { - // Load DirectShowSource.dll from app dir if it exists - wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); - if (dsspath.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dsspath.GetFullPath().mb_str(csConvLocal))); - } - - // Then try using DSS - if (env->FunctionExists("DirectShowSource")) { - const char *argnames[3] = { 0, "video", "audio" }; - AVSValue args[3] = { videoFilename, true, false }; - LOG_I("avisynth/video") << "Opening video with DirectShowSource"; - script = env->Invoke("DirectShowSource", AVSValue(args,3), argnames); - usedDirectShow = true; - decoderName = _T("DirectShowSource"); - } - - // Failed to find a suitable function - else { - LOG_E("avisynth/video") << "DSS function not found"; - throw AvisynthError("No function suitable for opening the video found"); - } - } + // On Failure, fallback to DSS + catch (AvisynthError &) { + LOG_I("avisynth/video") << "Failed to open .avi file with AviSource, switching to DirectShowSource"; } } - - // Catch errors - catch (AvisynthError &err) { - LOG_E("avisynth/video") << "Avisynth error: " << err.msg; - throw _T("AviSynth error: ") + wxString(err.msg,csConvLocal); + + // Open d2v with mpeg2dec3 + if (extension == L".d2v" && env->FunctionExists("Mpeg2Dec3_Mpeg2Source")) { + LOG_I("avisynth/video") << "Opening .d2v file with Mpeg2Dec3_Mpeg2Source"; + AVSValue script = env->Invoke("Mpeg2Dec3_Mpeg2Source", videoFilename); + decoderName = L"Mpeg2Dec3_Mpeg2Source"; + + //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this + if (env->FunctionExists("SetPlanarLegacyAlignment")) { + AVSValue args[2] = { script, true }; + script = env->Invoke("SetPlanarLegacyAlignment", AVSValue(args,2)); + } + return script; + } + + // If that fails, try opening it with DGDecode + if (extension == L".d2v" && env->FunctionExists("DGDecode_Mpeg2Source")) { + LOG_I("avisynth/video") << "Opening .d2v file with DGDecode_Mpeg2Source"; + decoderName = L"DGDecode_Mpeg2Source"; + return env->Invoke("Mpeg2Source", videoFilename); + + //note that DGDecode will also have issues like if the version is too ancient but no sane person + //would use that anyway + } + + if (extension == L".d2v" && env->FunctionExists("Mpeg2Source")) { + LOG_I("avisynth/video") << "Opening .d2v file with other Mpeg2Source"; + AVSValue script = env->Invoke("Mpeg2Source", videoFilename); + decoderName = L"Mpeg2Source"; + + //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this + if (env->FunctionExists("SetPlanarLegacyAlignment")) + script = env->Invoke("SetPlanarLegacyAlignment", script); + + return script; + } + + // Try loading DirectShowSource2 + if (!env->FunctionExists("dss2")) { + wxFileName dss2path(StandardPaths::DecodePath(_T("?data/avss.dll"))); + if (dss2path.FileExists()) { + env->Invoke("LoadPlugin",env->SaveString(dss2path.GetFullPath().mb_str(csConvLocal))); + } + } + + // If DSS2 loaded properly, try using it + if (env->FunctionExists("dss2")) { + LOG_I("avisynth/video") << "Opening file with DSS2"; + decoderName = L"DSS2"; + return env->Invoke("DSS2", videoFilename); + } + + // Try DirectShowSource + // Load DirectShowSource.dll from app dir if it exists + wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); + if (dsspath.FileExists()) { + env->Invoke("LoadPlugin",env->SaveString(dsspath.GetFullPath().mb_str(csConvLocal))); + } + + // Then try using DSS + if (env->FunctionExists("DirectShowSource")) { + const char *argnames[3] = { 0, "video", "audio" }; + AVSValue args[3] = { videoFilename, true, false }; + usedDirectShow = true; + decoderName = L"DirectShowSource"; + LOG_I("avisynth/video") << "Opening file with DirectShowSource"; + return env->Invoke("DirectShowSource", AVSValue(args,3), argnames); + } + + // Failed to find a suitable function + LOG_E("avisynth/video") << "DSS function not found"; + throw VideoNotSupported("No function suitable for opening the video found"); +} + +/// @brief Actually open the video into Avisynth +/// @param _filename +/// @return +/// +PClip AvisynthVideoProvider::OpenVideo(wxString filename) { + wxMutexLocker lock(AviSynthMutex); + + wxFileName fname(filename); + if (!fname.FileExists()) + throw agi::FileNotFoundError(STD_STR(filename)); + + AVSValue script; + wxString extension = filename.Right(4).Lower(); + try { + script = Open(fname, extension); + } + catch (AvisynthError const& err) { + throw VideoOpenError("Avisynth error: " + std::string(err.msg)); } // Check if video was loaded properly if (!script.IsClip() || !script.AsClip()->GetVideoInfo().HasVideo()) { - LOG_E("avisynth/video") << "AvisynthVideoProvider::OpenVideo: No suitable video found"; - throw _T("Avisynth: No usable video found in ") + _filename; + throw VideoNotSupported("No usable video found"); } // Read keyframes and timecodes from MKV file bool mkvOpen = MatroskaWrapper::wrapper.IsOpen(); KeyFrames.clear(); - if (extension == _T(".mkv") || mkvOpen) { + if (extension == L".mkv" || mkvOpen) { // Parse mkv - if (!mkvOpen) MatroskaWrapper::wrapper.Open(_filename); + if (!mkvOpen) MatroskaWrapper::wrapper.Open(filename); // Get keyframes KeyFrames = MatroskaWrapper::wrapper.GetKeyFrames(); @@ -230,9 +216,9 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori } // check if we have windows, if so we can load keyframes from AVI files using VFW #ifdef __WINDOWS__ - else if (extension == _T(".avi")) { + else if (extension == L".avi") { KeyFrames.clear(); - KeyFrames = VFWWrapper::GetKeyFrames(_filename); + KeyFrames = VFWWrapper::GetKeyFrames(filename); } #endif /* __WINDOWS__ */ @@ -261,8 +247,6 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori return (env->Invoke("Cache", script)).AsClip(); } - - /// @brief Actually get a frame /// @param _n /// @return diff --git a/aegisub/src/video_provider_avs.h b/aegisub/src/video_provider_avs.h index beceb5b6e..b6a024fca 100644 --- a/aegisub/src/video_provider_avs.h +++ b/aegisub/src/video_provider_avs.h @@ -78,10 +78,11 @@ class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper { /// DOCME PClip RGB32Video; - PClip OpenVideo(wxString _filename, bool mpeg2dec3_priority = true); + PClip OpenVideo(wxString filename); + AVSValue Open(wxFileName const& fname, wxString const& extension); public: - AvisynthVideoProvider(wxString _filename); + AvisynthVideoProvider(wxString filename); ~AvisynthVideoProvider(); const AegiVideoFrame GetFrame(int n); diff --git a/aegisub/src/video_provider_cache.h b/aegisub/src/video_provider_cache.h index 4bd5914c7..98962cd33 100644 --- a/aegisub/src/video_provider_cache.h +++ b/aegisub/src/video_provider_cache.h @@ -79,6 +79,4 @@ public: virtual std::vector GetKeyFrames() const { return master->GetKeyFrames(); } virtual wxString GetWarning() const { return master->GetWarning(); } virtual wxString GetDecoderName() const { return master->GetDecoderName(); } - - }; diff --git a/aegisub/src/video_provider_dummy.cpp b/aegisub/src/video_provider_dummy.cpp index 883784867..a7080e7a9 100644 --- a/aegisub/src/video_provider_dummy.cpp +++ b/aegisub/src/video_provider_dummy.cpp @@ -122,12 +122,12 @@ DummyVideoProvider::DummyVideoProvider(wxString filename) { wxString params; if (!filename.StartsWith(_T("?dummy:"), ¶ms)) { - throw _T("Attempted creating dummy video provider with non-dummy filename"); + throw agi::FileNotFoundError("Attempted creating dummy video provider with non-dummy filename"); } wxStringTokenizer t(params, _T(":")); if (t.CountTokens() < 7) { - throw _T("Too few fields in dummy video parameter list"); + throw VideoOpenError("Too few fields in dummy video parameter list"); } double fps; @@ -136,37 +136,37 @@ DummyVideoProvider::DummyVideoProvider(wxString filename) wxString field = t.GetNextToken(); if (!field.ToDouble(&fps)) { - throw _T("Unable to parse fps field in dummy video parameter list"); + throw VideoOpenError("Unable to parse fps field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&_frames)) { - throw _T("Unable to parse framecount field in dummy video parameter list"); + throw VideoOpenError("Unable to parse framecount field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&_width)) { - throw _T("Unable to parse width field in dummy video parameter list"); + throw VideoOpenError("Unable to parse width field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&_height)) { - throw _T("Unable to parse height field in dummy video parameter list"); + throw VideoOpenError("Unable to parse height field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&red)) { - throw _T("Unable to parse red colour field in dummy video parameter list"); + throw VideoOpenError("Unable to parse red colour field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&green)) { - throw _T("Unable to parse green colour field in dummy video parameter list"); + throw VideoOpenError("Unable to parse green colour field in dummy video parameter list"); } field = t.GetNextToken(); if (!field.ToLong(&blue)) { - throw _T("Unable to parse bluecolour field in dummy video parameter list"); + throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list"); } field = t.GetNextToken(); diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index fe0a9dbd0..dd6fbb625 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -51,7 +51,7 @@ #endif #include "aegisub_endian.h" -#include "include/aegisub/aegisub.h" +#include "compat.h" #include "main.h" #include "video_context.h" #include "video_provider_ffmpegsource.h" @@ -60,35 +60,41 @@ /// @brief Constructor /// @param filename The filename to open -FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) { - COMInited = false; +FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) +: VideoSource(NULL) +, VideoInfo(NULL) +, Width(-1) +, Height(-1) +, FrameNumber(-1) +, COMInited(false) +{ #ifdef WIN32 - HRESULT res; - res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (SUCCEEDED(res)) COMInited = true; else if (res != RPC_E_CHANGED_MODE) - throw _T("FFmpegSource video provider: COM initialization failure"); + throw VideoOpenError("COM initialization failure"); #endif // initialize ffmpegsource // FIXME: CPU detection? FFMS_Init(0); - // clean up variables - VideoSource = NULL; - FrameNumber = -1; ErrInfo.Buffer = FFMSErrMsg; ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; ErrInfo.SubType = FFMS_ERROR_SUCCESS; - ErrorMsg = _T("FFmpegSource video provider: "); SetLogLevel(); // and here we go try { LoadVideo(filename); - } catch (...) { + } + catch (wxString const& err) { + Close(); + throw VideoOpenError(STD_STR(err)); + } + catch (...) { Close(); throw; } @@ -98,32 +104,22 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) { /// @brief Destructor FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() { Close(); -#ifdef WIN32 - if (COMInited) - CoUninitialize(); -#endif } /// @brief Opens video /// @param filename The filename to open void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { - // make sure we don't have anything messy lying around - Close(); - wxString FileNameShort = wxFileName(filename).GetShortPath(); FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo); if (Indexer == NULL) { - // error messages that can possibly contain a filename use this method instead of - // wxString::Format because they may contain utf8 characters - ErrorMsg.Append(_T("Failed to create indexer: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8)); - throw ErrorMsg; + throw agi::FileNotFoundError(ErrInfo.Buffer); } std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_VIDEO); if (TrackList.size() <= 0) - throw _T("FFmpegSource video provider: no video tracks found"); + throw VideoNotSupported("no video tracks found"); // initialize the track number to an invalid value so we can detect later on // whether the user actually had to choose a track or not @@ -132,7 +128,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { TrackNumber = AskForTrackSelection(TrackList, FFMS_TYPE_VIDEO); // if it's still -1 here, user pressed cancel if (TrackNumber == -1) - throw _T("FFmpegSource video provider: video loading cancelled by user"); + throw agi::UserCancelException("video loading cancelled by user"); } // generate a name for the cache file @@ -169,11 +165,9 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { try { // ignore audio decoding errors here, we don't care right now Index = DoIndexing(Indexer, CacheName, TrackMask, FFMS_IEH_IGNORE); - } catch (wxString temp) { - ErrorMsg.Append(temp); - throw ErrorMsg; - } catch (...) { - throw; + } + catch (wxString err) { + throw VideoOpenError(STD_STR(err)); } } @@ -192,15 +186,14 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { if (TrackNumber < 0) { FFMS_DestroyIndex(Index); Index = NULL; - ErrorMsg.Append(wxString::Format(_T("Couldn't find any video tracks: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw VideoNotSupported(std::string("Couldn't find any video tracks: ") + ErrInfo.Buffer); } } // set thread count int Threads = OPT_GET("Provider/Video/FFmpegSource/Decoding Threads")->GetInt(); if (Threads < 1) - throw _T("FFmpegSource video provider: invalid decoding thread count"); + throw VideoOpenError("invalid decoding thread count"); // set seekmode // TODO: give this its own option? @@ -214,8 +207,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { FFMS_DestroyIndex(Index); Index = NULL; if (VideoSource == NULL) { - ErrorMsg.Append(wxString::Format(_T("Failed to open video track: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw VideoOpenError(std::string("Failed to open video track: ") + ErrInfo.Buffer); } // load video properties @@ -223,24 +215,22 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { const FFMS_Frame *TempFrame = FFMS_GetFrame(VideoSource, 0, &ErrInfo); if (TempFrame == NULL) { - ErrorMsg.Append(wxString::Format(_T("Failed to decode first frame: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw VideoOpenError(std::string("Failed to decode first frame: ") + ErrInfo.Buffer); } Width = TempFrame->EncodedWidth; Height = TempFrame->EncodedHeight; if (FFMS_SetOutputFormatV(VideoSource, 1LL << FFMS_GetPixFmt("bgra"), Width, Height, FFMS_RESIZER_BICUBIC, &ErrInfo)) { - ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw VideoOpenError(std::string("Failed to set output format: ") + ErrInfo.Buffer); } // get frame info data FFMS_Track *FrameData = FFMS_GetTrackFromVideo(VideoSource); if (FrameData == NULL) - throw _T("FFmpegSource video provider: failed to get frame data"); + throw VideoOpenError("failed to get frame data"); const FFMS_TrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData); if (TimeBase == NULL) - throw _T("FFmpegSource video provider: failed to get track time base"); + throw VideoOpenError("failed to get track time base"); const FFMS_FrameInfo *CurFrameData; @@ -249,8 +239,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) { CurFrameData = FFMS_GetFrameInfo(FrameData, CurFrameNum); if (CurFrameData == NULL) { - ErrorMsg.Append(wxString::Format(_T("Couldn't get info about frame %d"), CurFrameNum)); - throw ErrorMsg; + throw VideoOpenError(STD_STR(wxString::Format(L"Couldn't get info about frame %d", CurFrameNum))); } // keyframe? @@ -269,13 +258,11 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { /// @brief Close video /// void FFmpegSourceVideoProvider::Close() { - FFMS_DestroyVideoSource(VideoSource); - VideoSource = NULL; - - KeyFramesList.clear(); - FrameNumber = -1; - Timecodes = agi::vfr::Framerate(); - CurFrame.Clear(); + if (VideoSource) FFMS_DestroyVideoSource(VideoSource); +#ifdef WIN32 + if (COMInited) + CoUninitialize(); +#endif } /// @brief Get frame @@ -295,8 +282,7 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) { // decode frame const FFMS_Frame *SrcFrame = FFMS_GetFrame(VideoSource, n, &ErrInfo); if (SrcFrame == NULL) { - ErrorMsg.Append(wxString::Format(_T("Failed to retrieve frame: %s"), ErrInfo.Buffer)); - throw ErrorMsg; + throw VideoDecodeError(std::string("Failed to retrieve frame:") + ErrInfo.Buffer); } CurFrame.SetTo(SrcFrame->Data, Width, Height, SrcFrame->Linesize, FORMAT_RGB32); diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index c7e1626cc..aeb1c6f9c 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -61,7 +61,6 @@ private: char FFMSErrMsg[1024]; /// FFMS error message FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages - wxString ErrorMsg; /// wx-ified error message void LoadVideo(wxString filename); void Close(); diff --git a/aegisub/src/video_provider_manager.cpp b/aegisub/src/video_provider_manager.cpp index a9ff88d1a..537460286 100644 --- a/aegisub/src/video_provider_manager.cpp +++ b/aegisub/src/video_provider_manager.cpp @@ -58,53 +58,51 @@ /// @return /// VideoProvider *VideoProviderFactory::GetProvider(wxString video) { - // First check special case of dummy video - if (video.StartsWith(_T("?dummy:"))) { - return new DummyVideoProvider(video.wc_str()); - } - - try { - VideoProvider *y4m_provider = new YUV4MPEGVideoProvider(video); - if (y4m_provider) - y4m_provider = new VideoProviderCache(y4m_provider); - return y4m_provider; - } - catch (wxString temp) { - LOG_E("manager/video/provider/yuv4mpeg") << "Provider creation failed with reason: "<< temp.c_str() << " trying other providers"; - } - catch (...) { - LOG_E("manager/video/provider/yuv4mpeg") << "Provider creation failed (unknown reason) trying other providers"; - } - - // List of providers std::vector list = GetClasses(OPT_GET("Video/Provider")->GetString()); if (video.StartsWith("?dummy")) list.insert(list.begin(), "Dummy"); list.insert(list.begin(), "YUV4MPEG"); - // None available - if (list.empty()) throw _T("No video providers are available."); - - // Get provider - wxString error; - for (unsigned int i=0;iWantsCaching()) { - provider = new VideoProviderCache(provider); - } - return provider; + LOG_I("manager/video/provider") << list[i] << ": opened " << STD_STR(video); + if (provider->WantsCaching()) { + return new VideoProviderCache(provider); } + return provider; + } + catch (agi::FileNotFoundError const&) { + std::string err = list[i] + ": " + STD_STR(video) + " not found."; + errors += err + "\n"; + LOG_D("manager/video/provider") << err; + // Keep trying other providers as this one may just not be able to + // open a valid path + } + catch (VideoNotSupported const&) { + fileFound = true; + std::string err = list[i] + ": " + STD_STR(video) + " is not in a supported format.\n"; + errors += err + "\n"; + LOG_D("manager/video/provider") << err; + } + catch (VideoOpenError const& ex) { + fileSupported = true; + std::string err = list[i] + ": " + ex.GetMessage(); + errors += err + "\n"; + LOG_D("manager/video/provider") << err; } - catch (wxString err) { error += list[i] + _T(" factory: ") + err + _T("\n"); } - catch (const wxChar *err) { error += list[i] + _T(" factory: ") + wxString(err) + _T("\n"); } - catch (...) { error += list[i] + _T(" factory: Unknown error\n"); } } - // Failed - throw error; + // No provider could open the file + LOG_E("manager/video/provider") << "Could not open " << STD_STR(video); + std::string msg = "Could not open " + STD_STR(video) + ":\n" + errors; + + if (!fileFound) throw agi::FileNotFoundError(STD_STR(video)); + if (!fileSupported) throw VideoNotSupported(msg); + throw VideoOpenError(msg); } /// @brief Register all providers @@ -120,5 +118,4 @@ void VideoProviderFactory::RegisterProviders() { Register("YUV4MPEG", true); } -/// DOCME template<> VideoProviderFactory::map *FactoryBase::classes = NULL; diff --git a/aegisub/src/video_provider_yuv4mpeg.cpp b/aegisub/src/video_provider_yuv4mpeg.cpp index 02ac91b34..8754cc373 100644 --- a/aegisub/src/video_provider_yuv4mpeg.cpp +++ b/aegisub/src/video_provider_yuv4mpeg.cpp @@ -38,6 +38,7 @@ #include +#include "compat.h" #include "video_provider_yuv4mpeg.h" // All of this cstdio bogus is because of one reason and one reason only: @@ -49,36 +50,70 @@ #define ftello _ftelli64 #endif - - - /// @brief Constructor /// @param filename The filename to open -YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(wxString filename) { - sf = NULL; - w = 0; - h = 0; - cur_fn = -1; - inited = false; - pixfmt = Y4M_PIXFMT_NONE; - imode = Y4M_ILACE_NOTSET; - num_frames = -1; - fps_rat.num = -1; +YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(wxString fname) +: sf(NULL) +, w (0) +, h (0) +, cur_fn(-1) +, pixfmt(Y4M_PIXFMT_NONE) +, imode(Y4M_ILACE_NOTSET) +, num_frames(-1) +{ + fps_rat.num = -1; fps_rat.den = 1; - seek_table.clear(); - - errmsg = _T("YUV4MPEG video provider: "); try { - LoadVideo(filename); - } - catch (wxString temp) { - Close(); - errmsg.Append(temp); - throw errmsg; + wxString filename = wxFileName(fname).GetShortPath(); + +#ifdef WIN32 + sf = _wfopen(filename.wc_str(), _T("rb")); +#else + sf = fopen(filename.utf8_str(), "rb"); +#endif + + if (sf == NULL) throw agi::FileNotFoundError(STD_STR(fname)); + + CheckFileFormat(); + + ParseFileHeader(ReadHeader(0, false)); + + if (w <= 0 || h <= 0) + throw VideoOpenError("Invalid resolution"); + if (fps_rat.num <= 0 || fps_rat.den <= 0) { + fps_rat.num = 25; + fps_rat.den = 1; + LOG_D("provider/video/yuv4mpeg") << "framerate info unavailable, assuming 25fps"; + } + if (pixfmt == Y4M_PIXFMT_NONE) + pixfmt = Y4M_PIXFMT_420JPEG; + if (imode == Y4M_ILACE_NOTSET) + imode = Y4M_ILACE_UNKNOWN; + + luma_sz = w * h; + switch (pixfmt) { + case Y4M_PIXFMT_420JPEG: + case Y4M_PIXFMT_420MPEG2: + case Y4M_PIXFMT_420PALDV: + chroma_sz = (w * h) >> 2; break; + case Y4M_PIXFMT_422: + chroma_sz = (w * h) >> 1; break; + /// @todo add support for more pixel formats + default: + throw VideoOpenError("Unsupported pixel format"); + } + frame_sz = luma_sz + chroma_sz*2; + + num_frames = IndexFile(); + if (num_frames <= 0 || seek_table.empty()) + throw VideoOpenError("Unable to determine file length"); + cur_fn = 0; + + fseeko(sf, 0, SEEK_SET); } catch (...) { - Close(); + if (sf) fclose(sf); throw; } } @@ -86,88 +121,22 @@ YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(wxString filename) { /// @brief Destructor YUV4MPEGVideoProvider::~YUV4MPEGVideoProvider() { - Close(); + if (sf) fclose(sf); } - -/// @brief Open a video file -/// @param _filename The video file to open -void YUV4MPEGVideoProvider::LoadVideo(const wxString _filename) { - Close(); - - wxString filename = wxFileName(_filename).GetShortPath(); - -#ifdef WIN32 - sf = _wfopen(filename.wc_str(), _T("rb")); -#else - sf = fopen(filename.utf8_str(), "rb"); -#endif - - if (sf == NULL) - throw wxString::Format(_T("Failed to open file")); - - CheckFileFormat(); - - ParseFileHeader(ReadHeader(0, false)); - - if (w <= 0 || h <= 0) - throw wxString(_T("Invalid resolution")); - if (fps_rat.num <= 0 || fps_rat.den <= 0) { - fps_rat.num = 25; - fps_rat.den = 1; - LOG_D("provider/video/yuv4mpeg") << "framerate info unavailable, assuming 25fps"; - } - if (pixfmt == Y4M_PIXFMT_NONE) - pixfmt = Y4M_PIXFMT_420JPEG; - if (imode == Y4M_ILACE_NOTSET) - imode = Y4M_ILACE_UNKNOWN; - - luma_sz = w * h; - switch (pixfmt) { - case Y4M_PIXFMT_420JPEG: - case Y4M_PIXFMT_420MPEG2: - case Y4M_PIXFMT_420PALDV: - chroma_sz = (w * h) >> 2; break; - case Y4M_PIXFMT_422: - chroma_sz = (w * h) >> 1; break; - /// @todo add support for more pixel formats - default: - throw wxString(_T("Unsupported pixel format")); - } - frame_sz = luma_sz + chroma_sz*2; - - num_frames = IndexFile(); - if (num_frames <= 0 || seek_table.empty()) - throw wxString(_T("Unable to determine file length")); - cur_fn = 0; - - fseeko(sf, 0, SEEK_SET); -} - - -/// @brief Closes the currently open file (if any) and resets reader state -void YUV4MPEGVideoProvider::Close() { - seek_table.clear(); - if (sf) - fclose(sf); - sf = NULL; -} - - /// @brief Checks if the file is an YUV4MPEG file or not /// Note that it reports the error by throwing an exception, /// not by returning a false value. void YUV4MPEGVideoProvider::CheckFileFormat() { char buf[10]; if (fread(buf, 10, 1, sf) != 1) - throw wxString(_T("CheckFileFormat: Failed reading header")); + throw VideoNotSupported("CheckFileFormat: Failed reading header"); if (strncmp("YUV4MPEG2 ", buf, 10)) - throw wxString(_T("CheckFileFormat: File is not a YUV4MPEG file (bad magic)")); + throw VideoNotSupported("CheckFileFormat: File is not a YUV4MPEG file (bad magic)"); fseeko(sf, 0, SEEK_SET); } - /// @brief Read a frame or file header at a given file position /// @param startpos The byte offset at where to start reading /// @param reset_pos If true, the function will reset the file position to what it was before the function call before returning @@ -175,17 +144,17 @@ void YUV4MPEGVideoProvider::CheckFileFormat() { std::vector YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool reset_pos) { int64_t oldpos = ftello(sf); std::vector tags; - wxString curtag = _T(""); - int bytesread = 0; + wxString curtag; + int bytesread = 0; int buf; if (fseeko(sf, startpos, SEEK_SET)) - throw wxString::Format(_T("YUV4MPEG video provider: ReadHeader: failed seeking to position %d"), startpos); + throw VideoOpenError(STD_STR(wxString::Format(L"YUV4MPEG video provider: ReadHeader: failed seeking to position %d", startpos))); // read header until terminating newline (0x0A) is found while ((buf = fgetc(sf)) != 0x0A) { if (ferror(sf)) - throw wxString(_T("ReadHeader: Failed to read from file")); + throw VideoOpenError("ReadHeader: Failed to read from file"); if (feof(sf)) { // you know, this is one of the places where it would be really nice // to be able to throw an exception object that tells the caller that EOF was reached @@ -195,9 +164,9 @@ std::vector YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool r // some basic low-effort sanity checking if (buf == 0x00) - throw wxString(_T("ReadHeader: Malformed header (unexpected NUL)")); + throw VideoOpenError("ReadHeader: Malformed header (unexpected NUL)"); if (++bytesread >= YUV4MPEG_HEADER_MAXLEN) - throw wxString(_T("ReadHeader: Malformed header (no terminating newline found)")); + throw VideoOpenError("ReadHeader: Malformed header (no terminating newline found)"); // found a new tag if (buf == 0x20) { @@ -220,14 +189,13 @@ std::vector YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool r return tags; } - /// @brief Parses a list of parameters and sets reader state accordingly /// @param tags The list of parameters to parse void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { if (tags.size() <= 1) - throw wxString(_T("ParseFileHeader: contentless header")); + throw VideoOpenError("ParseFileHeader: contentless header"); if (tags.front().Cmp(_T("YUV4MPEG2"))) - throw wxString(_T("ParseFileHeader: malformed header (bad magic)")); + throw VideoOpenError("ParseFileHeader: malformed header (bad magic)"); // temporary stuff int t_w = -1; @@ -244,17 +212,17 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { if (tags.at(i).StartsWith(_T("W"), &tag)) { if (!tag.ToLong(&tmp_long1)) - throw wxString(_T("ParseFileHeader: invalid width")); + throw VideoOpenError("ParseFileHeader: invalid width"); t_w = (int)tmp_long1; } else if (tags.at(i).StartsWith(_T("H"), &tag)) { if (!tag.ToLong(&tmp_long1)) - throw wxString(_T("ParseFileHeader: invalid height")); + throw VideoOpenError("ParseFileHeader: invalid height"); t_h = (int)tmp_long1; } else if (tags.at(i).StartsWith(_T("F"), &tag)) { if (!(tag.BeforeFirst(':')).ToLong(&tmp_long1) && tag.AfterFirst(':').ToLong(&tmp_long2)) - throw wxString(_T("ParseFileHeader: invalid framerate")); + throw VideoOpenError("ParseFileHeader: invalid framerate"); t_fps_num = (int)tmp_long1; t_fps_den = (int)tmp_long2; } @@ -271,7 +239,7 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { else if (!tag.CmpNoCase(_T("444alpha"))) t_pixfmt = Y4M_PIXFMT_444ALPHA; else if (!tag.CmpNoCase(_T("mono"))) t_pixfmt = Y4M_PIXFMT_MONO; else - throw wxString(_T("ParseFileHeader: invalid or unknown colorspace")); + throw VideoOpenError("ParseFileHeader: invalid or unknown colorspace"); } else if (tags.at(i).StartsWith(_T("I"), &tag)) { if (!tag.CmpNoCase(_T("p"))) t_imode = Y4M_ILACE_PROGRESSIVE; @@ -280,7 +248,7 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { else if (!tag.CmpNoCase(_T("m"))) t_imode = Y4M_ILACE_MIXED; else if (!tag.CmpNoCase(_T("?"))) t_imode = Y4M_ILACE_UNKNOWN; else - throw wxString(_T("ParseFileHeader: invalid or unknown interlacing mode")); + throw VideoOpenError("ParseFileHeader: invalid or unknown interlacing mode"); } else LOG_D("provider/video/yuv4mpeg") << "Unparsed tag: " << tags.at(i).c_str(); @@ -292,15 +260,15 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { // but the "reference implementation" (mjpegtools) does, so I'm doing it too. if (inited) { if (t_w > 0 && t_w != w) - throw wxString(_T("ParseFileHeader: illegal width change")); + throw VideoOpenError("ParseFileHeader: illegal width change"); if (t_h > 0 && t_h != h) - throw wxString(_T("ParseFileHeader: illegal height change")); + throw VideoOpenError("ParseFileHeader: illegal height change"); if ((t_fps_num > 0 && t_fps_den > 0) && (t_fps_num != fps_rat.num || t_fps_den != fps_rat.den)) - throw wxString(_T("ParseFileHeader: illegal framerate change")); + throw VideoOpenError("ParseFileHeader: illegal framerate change"); if (t_pixfmt != Y4M_PIXFMT_NONE && t_pixfmt != pixfmt) - throw wxString(_T("ParseFileHeader: illegal colorspace change")); + throw VideoOpenError("ParseFileHeader: illegal colorspace change"); if (t_imode != Y4M_ILACE_NOTSET && t_imode != imode) - throw wxString(_T("ParseFileHeader: illegal interlacing mode change")); + throw VideoOpenError("ParseFileHeader: illegal interlacing mode change"); } else { w = t_w; @@ -314,21 +282,19 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { } } - /// @brief Parses a frame header /// @param tags The list of parameters to parse /// @return The flags set, as a binary mask /// This function is currently unimplemented (it will always return Y4M_FFLAG_NONE). YUV4MPEGVideoProvider::Y4M_FrameFlags YUV4MPEGVideoProvider::ParseFrameHeader(const std::vector& tags) { if (tags.front().Cmp(_("FRAME"))) - throw wxString(_T("ParseFrameHeader: malformed frame header (bad magic)")); + throw VideoOpenError("ParseFrameHeader: malformed frame header (bad magic)"); /// @todo implement parsing of frame flags return Y4M_FFLAG_NONE; } - /// @brief Indexes the file /// @return The number of frames found in the file /// This function goes through the file, finds and parses all file and frame headers, @@ -362,7 +328,7 @@ int YUV4MPEGVideoProvider::IndexFile() { seek_table.push_back(curpos); // seek to next frame header start position if (fseeko(sf, frame_sz, SEEK_CUR)) - throw wxString::Format(_T("IndexFile: failed seeking to position %d"), curpos + frame_sz); + throw VideoOpenError(STD_STR(wxString::Format(_T("IndexFile: failed seeking to position %d"), curpos + frame_sz))); } else { /// @todo implement rff flags etc @@ -372,8 +338,6 @@ int YUV4MPEGVideoProvider::IndexFile() { return framecount; } - - /// @brief Gets a given frame /// @param n The frame number to return /// @return The video frame @@ -398,7 +362,7 @@ const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) { src_fmt = FORMAT_YUY2; uv_width = w / 2; break; /// @todo add support for more pixel formats default: - throw wxString(_T("YUV4MPEG video provider: GetFrame: Unsupported source colorspace")); + throw _T("YUV4MPEG video provider: GetFrame: Unsupported source colorspace"); } AegiVideoFrame tmp_frame; @@ -416,11 +380,11 @@ const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) { size_t ret; ret = fread(tmp_frame.data[0], luma_sz, 1, sf); if (ret != 1 || feof(sf) || ferror(sf)) - throw wxString(_T("YUV4MPEG video provider: GetFrame: failed to read luma plane")); + throw _T("YUV4MPEG video provider: GetFrame: failed to read luma plane"); for (int i = 1; i <= 2; i++) { ret = fread(tmp_frame.data[i], chroma_sz, 1, sf); if (ret != 1 || feof(sf) || ferror(sf)) - throw wxString(_T("YUV4MPEG video provider: GetFrame: failed to read chroma planes")); + throw _T("YUV4MPEG video provider: GetFrame: failed to read chroma planes"); } AegiVideoFrame dst_frame; diff --git a/aegisub/src/video_provider_yuv4mpeg.h b/aegisub/src/video_provider_yuv4mpeg.h index 9a59e613c..87031f4bb 100644 --- a/aegisub/src/video_provider_yuv4mpeg.h +++ b/aegisub/src/video_provider_yuv4mpeg.h @@ -131,11 +131,6 @@ class YUV4MPEGVideoProvider : public VideoProvider { /// each frame header can be found std::vector seek_table; - wxString errmsg; /// error message - - void LoadVideo(const wxString filename); - void Close(); - void CheckFileFormat(); void ParseFileHeader(const std::vector& tags); Y4M_FrameFlags ParseFrameHeader(const std::vector& tags); diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index e3ea2bbef..018b6f153 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -40,12 +40,6 @@ #include #endif -#ifdef __APPLE__ -#include -#else -#include -#endif - #include "ass_dialogue.h" #include "ass_file.h" #include "ass_override.h" diff --git a/aegisub/src/visual_tool_vector_clip.cpp b/aegisub/src/visual_tool_vector_clip.cpp index 848b68de5..56ea80d73 100644 --- a/aegisub/src/visual_tool_vector_clip.cpp +++ b/aegisub/src/visual_tool_vector_clip.cpp @@ -37,12 +37,8 @@ #include #ifdef HAVE_APPLE_OPENGL_FRAMEWORK -#include -#include #include #else -#include -#include #include "gl/glext.h" #endif