diff --git a/aegisub/src/audio_player_dsound2.cpp b/aegisub/src/audio_player_dsound2.cpp index 970a68d36..1e09f53c1 100644 --- a/aegisub/src/audio_player_dsound2.cpp +++ b/aegisub/src/audio_player_dsound2.cpp @@ -119,25 +119,19 @@ struct COMObjectRetainer { }; /// @brief RAII wrapper around Win32 HANDLE type -struct Win32KernelHandle { - /// HANDLE value being managed - HANDLE handle; - +struct Win32KernelHandle : public agi::scoped_holder { /// @brief Create with a managed handle /// @param handle Win32 handle to manage Win32KernelHandle(HANDLE handle = 0) - : handle(handle) + : scoped_holder(handle, CloseHandle) { } - /// @brief Destructor, closes the managed handle - ~Win32KernelHandle() + Win32KernelHandle& operator=(HANDLE new_handle) { - if (handle) CloseHandle(handle); + scoped_holder::operator=(new_handle); + return *this; } - - /// @brief Returns the managed handle - operator HANDLE () const { return handle; } }; /// @class DirectSoundPlayer2Thread @@ -667,7 +661,7 @@ DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int start_frame = 0; end_frame = 0; - thread_handle.handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0); + thread_handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0); if (!thread_handle) throw agi::AudioPlayerOpenError("Failed creating playback thread in DirectSoundPlayer2. This is bad.", 0); diff --git a/aegisub/src/audio_provider_ffmpegsource.cpp b/aegisub/src/audio_provider_ffmpegsource.cpp index 90d3caa93..28842d29a 100644 --- a/aegisub/src/audio_provider_ffmpegsource.cpp +++ b/aegisub/src/audio_provider_ffmpegsource.cpp @@ -53,52 +53,31 @@ #include "main.h" /// @brief Constructor -/// @param filename -/// -FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) -: AudioSource(NULL) -, COMInited(false) +/// @param filename The filename to open +FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) try +: AudioSource(NULL, FFMS_DestroyAudioSource) { -#ifdef WIN32 - HRESULT res; - res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (SUCCEEDED(res)) - COMInited = true; - else if (res != RPC_E_CHANGED_MODE) - throw agi::AudioProviderOpenError("COM initialization failure", 0); -#endif - // initialize ffmpegsource - // FIXME: CPU detection? -#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (0 << 8) | 0) - FFMS_Init(0, 1); -#else - FFMS_Init(0); -#endif - ErrInfo.Buffer = FFMSErrMsg; ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; ErrInfo.SubType = FFMS_ERROR_SUCCESS; SetLogLevel(); - try { - LoadAudio(filename); - } catch (...) { - Close(); - throw; - } + LoadAudio(filename); +} +catch (wxString const& err) { + throw agi::AudioProviderOpenError(STD_STR(err), 0); +} +catch (const char *err) { + throw agi::AudioProviderOpenError(err, 0); } -/// @brief Load audio file -/// @param filename -/// void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { wxString FileNameShort = wxFileName(filename).GetShortPath(); FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo); - if (Indexer == NULL) { + if (!Indexer) throw agi::FileNotFoundError(ErrInfo.Buffer); - } std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_AUDIO); if (TrackList.size() <= 0) @@ -118,37 +97,25 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { wxString CacheName = GetCacheFilename(filename); // try to read index - FFMS_Index *Index = NULL; - Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo); - bool IndexIsValid = false; - if (Index != NULL) { - if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) { - FFMS_DestroyIndex(Index); - Index = NULL; - } - else - IndexIsValid = true; - } + agi::scoped_holder + Index(FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo), FFMS_DestroyIndex); + + if (Index && !FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) + Index = NULL; // index valid but track number still not set? - if (IndexIsValid) { + if (Index) { // track number not set? just grab the first track if (TrackNumber < 0) TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &ErrInfo); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; + if (TrackNumber < 0) throw agi::AudioDataNotFoundError(std::string("Couldn't find any audio tracks: ") + ErrInfo.Buffer, 0); - } // index is valid and track number is now set, // but do we have indexing info for the desired audio track? FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); - if (FFMS_GetNumFrames(TempTrackData) <= 0) { - IndexIsValid = false; - FFMS_DestroyIndex(Index); + if (FFMS_GetNumFrames(TempTrackData) <= 0) Index = NULL; - } } // no valid index exists and the file only has one audio track, index it else if (TrackNumber < 0) @@ -156,19 +123,14 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { // else: do nothing (keep track mask as it is) // moment of truth - if (!IndexIsValid) { + if (!Index) { int TrackMask; if (OPT_GET("Provider/FFmpegSource/Index All Tracks")->GetBool() || TrackNumber == FFMS_TRACKMASK_ALL) TrackMask = FFMS_TRACKMASK_ALL; else TrackMask = (1 << TrackNumber); - try { - Index = DoIndexing(Indexer, CacheName, TrackMask, GetErrorHandlingMode()); - } - catch (wxString const& err) { - throw agi::AudioProviderOpenError(STD_STR(err), 0); - } + Index = DoIndexing(Indexer, CacheName, TrackMask, GetErrorHandlingMode()); // if tracknumber still isn't set we need to set it now if (TrackNumber == FFMS_TRACKMASK_ALL) @@ -185,12 +147,9 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { #else AudioSource = FFMS_CreateAudioSource(FileNameShort.utf8_str(), TrackNumber, Index, &ErrInfo); #endif - FFMS_DestroyIndex(Index); - Index = NULL; - if (!AudioSource) { - throw agi::AudioProviderOpenError(std::string("Failed to open audio track: %s") + ErrInfo.Buffer, 0); - } - + if (!AudioSource) + throw agi::AudioProviderOpenError(std::string("Failed to open audio track: ") + ErrInfo.Buffer, 0); + const FFMS_AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); channels = AudioInfo.Channels; @@ -211,27 +170,6 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) { } } -/// @brief Destructor -/// -FFmpegSourceAudioProvider::~FFmpegSourceAudioProvider() { - Close(); -} - -/// @brief Clean up -/// -void FFmpegSourceAudioProvider::Close() { - if (AudioSource) FFMS_DestroyAudioSource(AudioSource); -#ifdef WIN32 - if (COMInited) - CoUninitialize(); -#endif -} - -/// @brief Get audio -/// @param Buf -/// @param Start -/// @param Count -/// void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) const { if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) { throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer); diff --git a/aegisub/src/audio_provider_ffmpegsource.h b/aegisub/src/audio_provider_ffmpegsource.h index d01b41fd8..46107a930 100644 --- a/aegisub/src/audio_provider_ffmpegsource.h +++ b/aegisub/src/audio_provider_ffmpegsource.h @@ -42,19 +42,16 @@ /// @class FFmpegSourceAudioProvider /// @brief Implements audio loading with the FFMS library. class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider { -private: - FFMS_AudioSource *AudioSource; ///< audio source object - bool COMInited; ///< COM initialization state + /// audio source object + agi::scoped_holder AudioSource; mutable char FFMSErrMsg[1024]; ///< FFMS error message mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages - void Close(); void LoadAudio(wxString filename); public: FFmpegSourceAudioProvider(wxString filename); - virtual ~FFmpegSourceAudioProvider(); /// @brief Checks sample endianness /// @return Returns true. diff --git a/aegisub/src/audio_provider_pcm.cpp b/aegisub/src/audio_provider_pcm.cpp index fbea3475d..711ceb073 100644 --- a/aegisub/src/audio_provider_pcm.cpp +++ b/aegisub/src/audio_provider_pcm.cpp @@ -64,8 +64,10 @@ /// @param filename /// PCMAudioProvider::PCMAudioProvider(const wxString &filename) -{ #ifdef _WIN32 +: file_handle(0, CloseHandle) +, file_mapping(0, CloseHandle) +{ file_handle = CreateFile( filename.c_str(), FILE_READ_DATA, @@ -75,15 +77,13 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, 0); - if (file_handle == INVALID_HANDLE_VALUE) { + if (file_handle == INVALID_HANDLE_VALUE) throw agi::FileNotFoundError(STD_STR(filename)); - } LARGE_INTEGER li_file_size = {0}; - if (!GetFileSizeEx(file_handle, &li_file_size)) { - CloseHandle(file_handle); + if (!GetFileSizeEx(file_handle, &li_file_size)) throw agi::AudioProviderOpenError("Failed getting file size", 0); - } + file_size = li_file_size.QuadPart; file_mapping = CreateFileMapping( @@ -93,20 +93,16 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) 0, 0, 0); - if (file_mapping == 0) { - CloseHandle(file_handle); + if (file_mapping == 0) throw agi::AudioProviderOpenError("Failed creating file mapping", 0); - } current_mapping = 0; #else - - file_handle = open(filename.mb_str(*wxConvFileName), O_RDONLY); - - if (file_handle == -1) { +: file_handle(open(filename.mb_str(*wxConvFileName), O_RDONLY), close) +{ + if (file_handle == -1) throw agi::FileNotFoundError(STD_STR(filename)); - } struct stat filestats; memset(&filestats, 0, sizeof(filestats)); @@ -125,18 +121,11 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename) PCMAudioProvider::~PCMAudioProvider() { #ifdef _WIN32 - if (current_mapping) { + if (current_mapping) UnmapViewOfFile(current_mapping); - } - - CloseHandle(file_mapping); - CloseHandle(file_handle); #else - if (current_mapping) { + if (current_mapping) munmap(current_mapping, mapping_length); - } - - close(file_handle); #endif } diff --git a/aegisub/src/audio_provider_pcm.h b/aegisub/src/audio_provider_pcm.h index e81c80f65..d5cab0e6c 100644 --- a/aegisub/src/audio_provider_pcm.h +++ b/aegisub/src/audio_provider_pcm.h @@ -47,6 +47,8 @@ #include "include/aegisub/audio_provider.h" +#include + /// DOCME /// @class PCMAudioProvider @@ -54,14 +56,12 @@ /// /// DOCME class PCMAudioProvider : public AudioProvider { -private: #ifdef _WIN32 + /// DOCME + agi::scoped_holder file_handle; /// DOCME - HANDLE file_handle; - - /// DOCME - HANDLE file_mapping; + agi::scoped_holder file_mapping; /// DOCME mutable void *current_mapping; @@ -72,7 +72,7 @@ private: /// DOCME mutable size_t mapping_length; #else - int file_handle; + agi::scoped_holder file_handle; mutable void *current_mapping; mutable off_t mapping_start; mutable size_t mapping_length; diff --git a/aegisub/src/dialog_version_check.cpp b/aegisub/src/dialog_version_check.cpp index 286603f70..b16162164 100644 --- a/aegisub/src/dialog_version_check.cpp +++ b/aegisub/src/dialog_version_check.cpp @@ -271,28 +271,22 @@ typedef BOOL (WINAPI * PGetUserPreferredUILanguages)(DWORD dwFlags, PULONG pulNu // Try using Win 6+ functions if available static wxString GetUILanguage() { - wxString res; - - HMODULE kernel32 = LoadLibraryW(L"kernel32.dll"); - if (!kernel32) return res; + agi::scoped_holder kernel32(LoadLibraryW(L"kernel32.dll"), FreeLibrary); + if (!kernel32) return ""; PGetUserPreferredUILanguages gupuil = (PGetUserPreferredUILanguages)GetProcAddress(kernel32, "GetUserPreferredUILanguages"); - if (!gupuil) goto error; + if (!gupuil) return ""; ULONG numlang = 0, output_len = 0; - if (gupuil(MUI_LANGUAGE_NAME, &numlang, 0, &output_len) == TRUE && output_len) - { - std::vector output(output_len); - if (gupuil(MUI_LANGUAGE_NAME, &numlang, &output[0], &output_len) && numlang >= 1) - { - // We got at least one language, just treat it as the only, and a null-terminated string - res = &output[0]; - } - } + if (gupuil(MUI_LANGUAGE_NAME, &numlang, 0, &output_len) != TRUE || !output_len) + return ""; -error: - FreeModule(kernel32); - return res; + std::vector output(output_len); + if (!gupuil(MUI_LANGUAGE_NAME, &numlang, &output[0], &output_len) || numlang < 1) + return ""; + + // We got at least one language, just treat it as the only, and a null-terminated string + return &output[0]; } static wxString GetSystemLanguage() { diff --git a/aegisub/src/ffmpegsource_common.cpp b/aegisub/src/ffmpegsource_common.cpp index 4e0b94ed9..c05b70ca6 100644 --- a/aegisub/src/ffmpegsource_common.cpp +++ b/aegisub/src/ffmpegsource_common.cpp @@ -56,6 +56,33 @@ #include "md5.h" #include "standard_paths.h" +#ifdef WIN32 +static void deinit_com(bool) { + CoUninitialize(); +} +#else +static void deinit_com(bool) { } +#endif + +FFmpegSourceProvider::FFmpegSourceProvider() +: COMInited(false, deinit_com) +{ +#ifdef WIN32 + HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (SUCCEEDED(res)) + COMInited = true; + else if (res != RPC_E_CHANGED_MODE) + throw "COM initialization failure"; +#endif + + // initialize ffmpegsource + // FIXME: CPU detection? +#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (0 << 8) | 0) + FFMS_Init(0, 1); +#else + FFMS_Init(0); +#endif +} wxMutex FFmpegSourceProvider::CleaningInProgress; diff --git a/aegisub/src/ffmpegsource_common.h b/aegisub/src/ffmpegsource_common.h index e89b41ed6..9be835e70 100644 --- a/aegisub/src/ffmpegsource_common.h +++ b/aegisub/src/ffmpegsource_common.h @@ -45,6 +45,8 @@ #include +#include + /// Index all tracks #define FFMS_TRACKMASK_ALL -1 /// Index no tracks @@ -54,7 +56,11 @@ /// @brief Base class for FFMS2 source providers; contains common functions etc class FFmpegSourceProvider { friend class FFmpegSourceCacheCleaner; + agi::scoped_holder COMInited; ///< COM initialization state + public: + FFmpegSourceProvider(); + /// Logging level constants from avutil/log.h enum FFMS_LogLevel { /// nothing printed @@ -85,7 +91,6 @@ public: /// @class FFmpegSourceCacheCleaner /// @brief Implements index cache cleaning functionality for the FFMS2 providers class FFmpegSourceCacheCleaner : public wxThread { -private: FFmpegSourceProvider *parent; public: @@ -96,4 +101,3 @@ public: }; #endif /* WITH_FFMS2 */ - diff --git a/aegisub/src/font_file_lister_fontconfig.cpp b/aegisub/src/font_file_lister_fontconfig.cpp index d82d6ffb5..e20db14ea 100644 --- a/aegisub/src/font_file_lister_fontconfig.cpp +++ b/aegisub/src/font_file_lister_fontconfig.cpp @@ -124,7 +124,7 @@ FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(wxString bold; int slant = italic ? 110 : 0; - scoped pat(FcPatternCreate(), FcPatternDestroy); + agi::scoped_holder pat(FcPatternCreate(), FcPatternDestroy); if (!pat) return ret; int family_cnt = add_families(pat, family); @@ -138,11 +138,11 @@ FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(wxString if (!FcConfigSubstitute(config, pat, FcMatchPattern)) return ret; FcResult result; - scoped fsorted(FcFontSort(config, pat, true, NULL, &result), FcFontSetDestroy); - scoped ffullname(MatchFullname(family.c_str(), weight, slant), FcFontSetDestroy); + agi::scoped_holder fsorted(FcFontSort(config, pat, true, NULL, &result), FcFontSetDestroy); + agi::scoped_holder ffullname(MatchFullname(family.c_str(), weight, slant), FcFontSetDestroy); if (!fsorted || !ffullname) return ret; - scoped fset(FcFontSetCreate(), FcFontSetDestroy); + agi::scoped_holder fset(FcFontSetCreate(), FcFontSetDestroy); for (int cur_font = 0; cur_font < ffullname->nfont; ++cur_font) { FcPattern *curp = ffullname->fonts[cur_font]; FcPatternReference(curp); @@ -169,7 +169,7 @@ FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(wxString for (; family_cnt > 1; --family_cnt) FcPatternRemove(pat, FC_FAMILY, family_cnt - 1); - scoped rpat(FcFontRenderPrepare(config, pat, fset->fonts[cur_font]), FcPatternDestroy); + agi::scoped_holder rpat(FcFontRenderPrepare(config, pat, fset->fonts[cur_font]), FcPatternDestroy); if (!rpat) return ret; FcChar8 *r_family; diff --git a/aegisub/src/font_file_lister_fontconfig.h b/aegisub/src/font_file_lister_fontconfig.h index 9d6255dd3..7df85fc33 100644 --- a/aegisub/src/font_file_lister_fontconfig.h +++ b/aegisub/src/font_file_lister_fontconfig.h @@ -25,23 +25,15 @@ #include "font_file_lister.h" +#include + typedef struct _FcConfig FcConfig; typedef struct _FcFontSet FcFontSet; /// @class FontConfigFontFileLister /// @brief fontconfig powered font lister class FontConfigFontFileLister : public FontFileLister { - template class scoped { - T data; - void (*destructor)(T); - public: - scoped(T data, void (*destructor)(T)) : data(data), destructor(destructor) { } - ~scoped() { if (data) destructor(data); } - operator T() { return data; } - T operator->() { return data; } - }; - - scoped config; + agi::scoped_holder config; /// @brief Case-insensitive match ASS/SSA font family against full name. (also known as "name for humans") /// @param family font fullname diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index 7bf156bb1..1c076e299 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -57,33 +57,15 @@ #include "video_context.h" #include "video_provider_ffmpegsource.h" - - /// @brief Constructor /// @param filename The filename to open -FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) -: VideoSource(NULL) +FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) try +: VideoSource(NULL, FFMS_DestroyVideoSource) , VideoInfo(NULL) , Width(-1) , Height(-1) , FrameNumber(-1) -, COMInited(false) { -#ifdef WIN32 - HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (SUCCEEDED(res)) - COMInited = true; - else if (res != RPC_E_CHANGED_MODE) - throw VideoOpenError("COM initialization failure"); -#endif - // initialize ffmpegsource - // FIXME: CPU detection? -#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (0 << 8) | 0) - FFMS_Init(0, 1); -#else - FFMS_Init(0); -#endif - ErrInfo.Buffer = FFMSErrMsg; ErrInfo.BufferSize = sizeof(FFMSErrMsg); ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; @@ -92,25 +74,14 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) SetLogLevel(); // and here we go - try { - LoadVideo(filename); - } - catch (wxString const& err) { - Close(); - throw VideoOpenError(STD_STR(err)); - } - catch (...) { - Close(); - throw; - } + LoadVideo(filename); } - - -/// @brief Destructor -FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() { - Close(); +catch (wxString const& err) { + throw VideoOpenError(STD_STR(err)); +} +catch (const char * err) { + throw VideoOpenError(err); } - /// @brief Opens video /// @param filename The filename to open @@ -118,9 +89,8 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { wxString FileNameShort = wxFileName(filename).GetShortPath(); FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo); - if (Indexer == NULL) { + if (!Indexer) throw agi::FileNotFoundError(ErrInfo.Buffer); - } std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_VIDEO); if (TrackList.size() <= 0) @@ -140,40 +110,26 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { wxString CacheName = GetCacheFilename(filename); // try to read index - FFMS_Index *Index = NULL; - Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo); - bool IndexIsValid = false; - if (Index != NULL) { - if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) { - FFMS_DestroyIndex(Index); - Index = NULL; - } - else - IndexIsValid = true; - } + agi::scoped_holder + Index(FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo), FFMS_DestroyIndex); + + if (Index && !FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) + Index = NULL; // time to examine the index and check if the track we want is indexed // technically this isn't really needed since all video tracks should always be indexed, // but a bit of sanity checking never hurt anyone - if (IndexIsValid && TrackNumber >= 0) { + if (Index && TrackNumber >= 0) { FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); - if (FFMS_GetNumFrames(TempTrackData) <= 0) { - IndexIsValid = false; - FFMS_DestroyIndex(Index); + if (FFMS_GetNumFrames(TempTrackData) <= 0) Index = NULL; - } } // moment of truth - if (!IndexIsValid) { + if (!Index) { int TrackMask = OPT_GET("Provider/FFmpegSource/Index All Tracks")->GetBool() ? FFMS_TRACKMASK_ALL : FFMS_TRACKMASK_NONE; - try { - // ignore audio decoding errors here, we don't care right now - Index = DoIndexing(Indexer, CacheName, TrackMask, FFMS_IEH_IGNORE); - } - catch (wxString err) { - throw VideoOpenError(STD_STR(err)); - } + // ignore audio decoding errors here, we don't care right now + Index = DoIndexing(Indexer, CacheName, TrackMask, FFMS_IEH_IGNORE); } // update access time of index file so it won't get cleaned away @@ -188,11 +144,8 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { if (TrackNumber < 0) { // just grab the first track TrackNumber = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, &ErrInfo); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; + if (TrackNumber < 0) throw VideoNotSupported(std::string("Couldn't find any video tracks: ") + ErrInfo.Buffer); - } } // set thread count @@ -207,11 +160,8 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { SeekMode = FFMS_SEEK_NORMAL; VideoSource = FFMS_CreateVideoSource(FileNameShort.utf8_str(), TrackNumber, Index, Threads, SeekMode, &ErrInfo); - FFMS_DestroyIndex(Index); - Index = NULL; - if (VideoSource == NULL) { + if (!VideoSource) throw VideoOpenError(std::string("Failed to open video track: ") + ErrInfo.Buffer); - } // load video properties VideoInfo = FFMS_GetVideoProperties(VideoSource); @@ -274,14 +224,6 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { FrameNumber = 0; } -void FFmpegSourceVideoProvider::Close() { - if (VideoSource) FFMS_DestroyVideoSource(VideoSource); -#ifdef WIN32 - if (COMInited) - CoUninitialize(); -#endif -} - const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int n) { FrameNumber = mid(0, n, GetFrameCount() - 1); diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index f688d2325..a19c4cfb0 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -46,7 +46,8 @@ /// @class FFmpegSourceVideoProvider /// @brief Implements video loading through the FFMS library. class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { - FFMS_VideoSource *VideoSource; ///< video source object + /// video source object + agi::scoped_holder VideoSource; const FFMS_VideoProperties *VideoInfo; ///< video properties int Width; ///< width in pixels @@ -54,7 +55,6 @@ class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { int FrameNumber; ///< current framenumber std::vector KeyFramesList; ///< list of keyframes agi::vfr::Framerate Timecodes; ///< vfr object - bool COMInited; ///< COM initialization state wxString ColorSpace; ///< Colorspace name AegiVideoFrame CurFrame; ///< current video frame @@ -63,11 +63,9 @@ class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages void LoadVideo(wxString filename); - void Close(); public: FFmpegSourceVideoProvider(wxString filename); - ~FFmpegSourceVideoProvider(); const AegiVideoFrame GetFrame(int n);