diff --git a/aegisub/src/audio_provider_ffmpegsource.cpp b/aegisub/src/audio_provider_ffmpegsource.cpp index 50433db62..fdedc3a46 100644 --- a/aegisub/src/audio_provider_ffmpegsource.cpp +++ b/aegisub/src/audio_provider_ffmpegsource.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -41,6 +41,8 @@ // Headers #include "include/aegisub/aegisub.h" #include "audio_provider_ffmpegsource.h" +#include "options.h" +#include #ifdef WIN32 #include #endif @@ -61,7 +63,7 @@ FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(Aegisub::String filename) { FFMS_Init(0); MsgSize = sizeof(FFMSErrMsg); - MsgString = _T("FFmpegSource audio provider: "); + ErrorMsg = _T("FFmpegSource audio provider: "); AudioSource = NULL; @@ -82,60 +84,78 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { wxString FileNameWX = wxFileName(wxString(filename.c_str(), wxConvFile)).GetShortPath(); - // generate a default name for the cache file + FFIndexer *Indexer = FFMS_CreateIndexer(FileNameWX.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize); + 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(FFMSErrMsg, wxConvUTF8)); + throw ErrorMsg; + } + + std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_AUDIO); + if (TrackList.size() <= 0) + throw _T("FFmpegSource audio provider: 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 + int TrackNumber = -1; + if (TrackList.size() > 1) { + 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"); + } + + // generate a name for the cache file wxString CacheName = GetCacheFilename(filename.c_str()); + // try to read index FFIndex *Index = NULL; - bool ReIndex = false; Index = FFMS_ReadIndex(CacheName.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize); - if (Index == NULL) { - ReIndex = true; - } - // index exists, but is it the index we think it is? - else if (FFMS_IndexBelongsToFile(Index, FileNameWX.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize)) { - FFMS_DestroyIndex(Index); - Index = NULL; - ReIndex = true; - } - // it is, but does it have indexing info for the audio track(s)? - else { - int NumTracks = FFMS_GetNumTracks(Index); - // sanity check - if (NumTracks <= 0) { + bool IndexIsValid = false; + if (Index != NULL) { + if (FFMS_IndexBelongsToFile(Index, FileNameWX.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize)) { FFMS_DestroyIndex(Index); Index = NULL; - throw _T("FFmpegSource audio provider: no tracks found in index file"); - } - - for (int i = 0; i < NumTracks; i++) { - FFTrack *TrackData = FFMS_GetTrackFromIndex(Index, i); - // more sanity checking - if (TrackData == NULL) { - FFMS_DestroyIndex(Index); - Index = NULL; - wxString temp(FFMSErrMsg, wxConvUTF8); - MsgString << _T("Couldn't get track data: ") << temp; - throw MsgString; - } - - // does the track have any indexed frames? - if (FFMS_GetNumFrames(TrackData) <= 0 && (FFMS_GetTrackType(TrackData) == FFMS_TYPE_AUDIO)) { - // found an unindexed audio track, we'll need to reindex - FFMS_DestroyIndex(Index); - Index = NULL; - ReIndex = true; - break; - } } + else + IndexIsValid = true; } - // index didn't exist or was invalid, we'll have to (re)create it - if (ReIndex) { + // index valid but track number still not set? + if (IndexIsValid) { + // track number not set? just grab the first track + if (TrackNumber < 0) + TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, FFMSErrMsg, MsgSize); + if (TrackNumber < 0) { + FFMS_DestroyIndex(Index); + Index = NULL; + ErrorMsg.Append(wxString::Format(_T("Couldn't find any audio tracks: %s"), FFMSErrMsg)); + throw ErrorMsg; + } + + // index is valid and track number is now set, + // but do we have indexing info for the desired audio track? + FFTrack *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); + if (FFMS_GetNumFrames(TempTrackData) <= 0) { + IndexIsValid = false; + FFMS_DestroyIndex(Index); + Index = NULL; + } + } + // no valid index exists and the file only has one audio track, index all tracks + else if (TrackNumber < 0) + TrackNumber = FFMSTrackMaskAll; + // else: do nothing (keep track mask as it is) + + // moment of truth + if (!IndexIsValid) { + int TrackMask = Options.AsBool(_T("FFmpegSource always index all tracks")) ? FFMSTrackMaskAll : 1 << TrackNumber; try { - Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll, false); + Index = DoIndexing(Indexer, CacheName, TrackMask, false); } catch (wxString temp) { - MsgString << temp; - throw MsgString; + ErrorMsg.Append(temp); + throw ErrorMsg; } catch (...) { throw; } @@ -144,23 +164,12 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { // update access time of index file so it won't get cleaned away wxFileName(CacheName).Touch(); - // FIXME: provide a way to choose which audio track to load? - int TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, FFMSErrMsg, MsgSize); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; - wxString temp(FFMSErrMsg, wxConvUTF8); - MsgString << _T("Couldn't find any audio tracks: ") << temp; - throw MsgString; - } - AudioSource = FFMS_CreateAudioSource(FileNameWX.mb_str(wxConvUTF8), TrackNumber, Index, FFMSErrMsg, MsgSize); FFMS_DestroyIndex(Index); Index = NULL; if (!AudioSource) { - wxString temp(FFMSErrMsg, wxConvUTF8); - MsgString << _T("Failed to open audio track: ") << temp; - throw MsgString; + ErrorMsg.Append(wxString::Format(_T("Failed to open audio track: %s"), FFMSErrMsg)); + throw ErrorMsg; } const FFAudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); @@ -171,7 +180,7 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { if (channels <= 0 || sample_rate <= 0 || num_samples <= 0) throw _T("FFmpegSource audio provider: sanity check failed, consult your local psychiatrist"); - // FIXME: use + // 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... switch (AudioInfo.BitsPerSample) { case 8: bytes_per_sample = 1; break; @@ -207,9 +216,8 @@ void FFmpegSourceAudioProvider::Close() { // Get audio void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) { if (FFMS_GetAudio(AudioSource, Buf, Start, Count, FFMSErrMsg, MsgSize)) { - wxString temp(FFMSErrMsg, wxConvUTF8); - MsgString << _T("Failed to get audio samples: ") << temp; - throw MsgString; + ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), FFMSErrMsg)); + throw ErrorMsg; } } diff --git a/aegisub/src/audio_provider_ffmpegsource.h b/aegisub/src/audio_provider_ffmpegsource.h index 4d8fe59c0..5b9bf9d8d 100644 --- a/aegisub/src/audio_provider_ffmpegsource.h +++ b/aegisub/src/audio_provider_ffmpegsource.h @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ private: char FFMSErrMsg[1024]; unsigned MsgSize; - wxString MsgString; + wxString ErrorMsg; bool COMInited; diff --git a/aegisub/src/ffmpegsource_common.cpp b/aegisub/src/ffmpegsource_common.cpp index f2be3f12b..0468c55f5 100644 --- a/aegisub/src/ffmpegsource_common.cpp +++ b/aegisub/src/ffmpegsource_common.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ #include -// lookit dis here static shit +// lookit dis here static storage wxMutex FFmpegSourceProvider::CleaningInProgress; @@ -62,8 +62,8 @@ int FFMS_CC FFmpegSourceProvider::UpdateIndexingProgress(int64_t Current, int64_ if (Progress->IndexingCanceled) return 1; - // noone cares about a little bit of a rounding error here anyway - Progress->ProgressDialog->SetProgress((1000*Current)/Total, 1000); + // no one cares about a little bit of a rounding error here anyway + Progress->ProgressDialog->SetProgress(((int64_t)1000*Current)/Total, 1000); return 0; } @@ -71,7 +71,7 @@ int FFMS_CC FFmpegSourceProvider::UpdateIndexingProgress(int64_t Current, int64_ /////////// // Do indexing -FFIndex *FFmpegSourceProvider::DoIndexing(FFIndex *Index, wxString FileNameWX, wxString CacheName, int Trackmask, bool IgnoreDecodeErrors) { +FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) { char FFMSErrMsg[1024]; unsigned MsgSize = sizeof(FFMSErrMsg); wxString MsgString; @@ -79,16 +79,17 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndex *Index, wxString FileNameWX, w // set up progress dialog callback IndexingProgressDialog Progress; Progress.IndexingCanceled = false; - Progress.ProgressDialog = new DialogProgress(AegisubApp::Get()->frame, _("Indexing"), &Progress.IndexingCanceled, _("Reading timecodes and frame/sample data"), 0, 1); + 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); // index all audio tracks - Index = FFMS_MakeIndex(FileNameWX.mb_str(wxConvUTF8), Trackmask, FFMSTrackMaskNone, NULL, NULL, IgnoreDecodeErrors, FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); - if (!Index) { + FFIndex *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMSTrackMaskNone, NULL, NULL, IgnoreDecodeErrors, + FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); + if (Index == NULL) { Progress.ProgressDialog->Destroy(); - wxString temp(FFMSErrMsg, wxConvUTF8); - MsgString << _T("Failed to index: ") << temp; + MsgString.Append(_T("Failed to index: ")).Append(wxString(FFMSErrMsg, wxConvUTF8)); throw MsgString; } Progress.ProgressDialog->Destroy(); @@ -105,6 +106,47 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndex *Index, wxString FileNameWX, w return Index; } +/////////// +// Find all tracks of the given typo and return their track numbers and respective codec names +std::map FFmpegSourceProvider::GetTracksOfType(FFIndexer *Indexer, FFMS_TrackType Type) { + std::map TrackList; + int NumTracks = FFMS_GetNumTracksI(Indexer); + + for (int i=0; i(i, CodecName)); + } + } + + return TrackList; +} + +/////////// +// Ask user for which track he wants to load +int FFmpegSourceProvider::AskForTrackSelection(const std::map &TrackList, FFMS_TrackType Type) { + std::vector TrackNumbers; + wxArrayString Choices; + wxString TypeName = _T(""); + if (Type == FFMS_TYPE_VIDEO) + TypeName = _("video"); + else if (Type == FFMS_TYPE_AUDIO) + TypeName = _("audio"); + + for (std::map::const_iterator i = TrackList.begin(); i != TrackList.end(); i++) { + Choices.Add(wxString::Format(_("Track %02d: %s"), i->first, i->second.c_str())); + TrackNumbers.push_back(i->first); + } + + int Choice = wxGetSingleChoiceIndex(wxString::Format(_("Multiple %s tracks detected, please choose the one you wish to load:"), TypeName.c_str()), + wxString::Format(_("Choose %s track"), TypeName.c_str()), Choices); + + if (Choice < 0) + return Choice; + else + return TrackNumbers[Choice]; +} + ///////////////////// // Creates a name for the ffmpegsource2 index and prepares the folder if it doesn't exist // method by amz diff --git a/aegisub/src/ffmpegsource_common.h b/aegisub/src/ffmpegsource_common.h index 80d4f9fcf..ded8dee37 100644 --- a/aegisub/src/ffmpegsource_common.h +++ b/aegisub/src/ffmpegsource_common.h @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -60,7 +60,10 @@ public: bool CleanCache(); static int FFMS_CC UpdateIndexingProgress(int64_t Current, int64_t Total, void *Private); - FFIndex *DoIndexing(FFIndex *Index, wxString Filename, wxString Cachename, int Trackmask, bool IgnoreDecodeErrors); + + FFIndex *DoIndexing(FFIndexer *Indexer, const wxString& Cachename, int Trackmask, bool IgnoreDecodeErrors); + std::map GetTracksOfType(FFIndexer *Indexer, FFMS_TrackType Type); + int AskForTrackSelection(const std::map& TrackList, FFMS_TrackType Type); wxString GetCacheFilename(const wxString& filename); virtual FFmpegSourceProvider::~FFmpegSourceProvider() {} diff --git a/aegisub/src/options.cpp b/aegisub/src/options.cpp index 2c4ae5185..34ba0c923 100644 --- a/aegisub/src/options.cpp +++ b/aegisub/src/options.cpp @@ -176,6 +176,7 @@ void OptionsManager::LoadDefaults(bool onlyDefaults,bool doOverride) { SetBool(_T("Video Use Pixel Shaders"),false,1700); SetInt(_T("FFmpegSource max cache size"),42); SetInt(_T("FFmpegSource max cache files"),20); + SetInt(_T("FFmpegSource always index all tracks"), true); // Audio Options SetModificationType(MOD_AUTOMATIC); diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index 247eb4681..77bffaba1 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -40,6 +40,8 @@ /////////// // Headers #include +#include +#include #include "include/aegisub/aegisub.h" #include "video_provider_ffmpegsource.h" #include "video_context.h" @@ -72,7 +74,7 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(Aegisub::String filename, d LastDstFormat = FFMS_GetPixFmt("none"); KeyFramesLoaded = false; FrameNumber = -1; - MessageSize = sizeof(FFMSErrorMessage); + MsgSize = sizeof(FFMSErrMsg); ErrorMsg = _T("FFmpegSource video provider: "); // and here we go @@ -102,40 +104,75 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) wxString FileNameWX = wxFileName(wxString(filename.c_str(), wxConvFile)).GetShortPath(); + FFIndexer *Indexer = FFMS_CreateIndexer(FileNameWX.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize); + 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(FFMSErrMsg, wxConvUTF8)); + throw ErrorMsg; + } + + std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_VIDEO); + if (TrackList.size() <= 0) + throw _T("FFmpegSource video provider: 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 + int TrackNumber = -1; + if (TrackList.size() > 1) { + 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"); + } + // generate a name for the cache file wxString CacheName = GetCacheFilename(filename.c_str()); // try to read index FFIndex *Index = NULL; - Index = FFMS_ReadIndex(CacheName.mb_str(wxConvUTF8), FFMSErrorMessage, MessageSize); - bool ReIndex = false; - if (Index == NULL) { - ReIndex = true; - } - else if (FFMS_IndexBelongsToFile(Index, FileNameWX.mb_str(wxConvUTF8), FFMSErrorMessage, MessageSize)) { - FFMS_DestroyIndex(Index); - Index = NULL; - ReIndex = true; + Index = FFMS_ReadIndex(CacheName.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize); + bool IndexIsValid = false; + if (Index != NULL) { + if (FFMS_IndexBelongsToFile(Index, FileNameWX.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize)) { + FFMS_DestroyIndex(Index); + Index = NULL; + } + else + IndexIsValid = true; } - // index didn't exist or was invalid, we'll have to (re)create it - if (ReIndex) { + // 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) { + FFTrack *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); + if (FFMS_GetNumFrames(TempTrackData) <= 0) { + IndexIsValid = false; + FFMS_DestroyIndex(Index); + Index = NULL; + } + } + + // moment of truth + if (!IndexIsValid) { + int TrackMask = Options.AsBool(_T("FFmpegSource always index all tracks")) ? FFMSTrackMaskAll : FFMSTrackMaskNone; try { try { // ignore audio decoding errors here, we don't care right now - Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll, true); + Index = DoIndexing(Indexer, CacheName, TrackMask, true); } catch (...) { - // Try without audio - Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskNone, true); + // something borked, try if it works without audio + Index = DoIndexing(Indexer, CacheName, FFMSTrackMaskNone, true); } } catch (wxString temp) { - ErrorMsg << temp; + ErrorMsg.Append(temp); throw ErrorMsg; } catch (...) { throw; } } - + // update access time of index file so it won't get cleaned away wxFileName(CacheName).Touch(); @@ -144,6 +181,18 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) //do something? } + // track number still not set? + if (TrackNumber < 0) { + // just grab the first track + TrackNumber = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, FFMSErrMsg, MsgSize); + if (TrackNumber < 0) { + FFMS_DestroyIndex(Index); + Index = NULL; + ErrorMsg.Append(wxString::Format(_T("Couldn't find any video tracks: %s"), FFMSErrMsg)); + throw ErrorMsg; + } + } + // set thread count int Threads = Options.AsInt(_T("FFmpegSource decoding threads")); if (Threads < 1) @@ -157,22 +206,11 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) else SeekMode = FFMS_SEEK_NORMAL; - // FIXME: provide a way to choose which audio track to load? - int TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_VIDEO, FFMSErrorMessage, MessageSize); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; - wxString temp(FFMSErrorMessage, wxConvUTF8); - ErrorMsg << _T("Couldn't find any video tracks: ") << temp; - throw ErrorMsg; - } - - VideoSource = FFMS_CreateVideoSource(FileNameWX.mb_str(wxConvUTF8), TrackNumber, Index, "", Threads, SeekMode, FFMSErrorMessage, MessageSize); + VideoSource = FFMS_CreateVideoSource(FileNameWX.mb_str(wxConvUTF8), TrackNumber, Index, "", Threads, SeekMode, FFMSErrMsg, MsgSize); FFMS_DestroyIndex(Index); Index = NULL; if (VideoSource == NULL) { - wxString temp(FFMSErrorMessage, wxConvUTF8); - ErrorMsg << _T("Failed to open video track: ") << temp; + ErrorMsg.Append(wxString::Format(_T("Failed to open video track: %s"), FFMSErrMsg)); throw ErrorMsg; } @@ -193,8 +231,7 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) { CurFrameData = FFMS_GetFrameInfo(FrameData, CurFrameNum); if (CurFrameData == NULL) { - wxString temp(FFMSErrorMessage, wxConvUTF8); - ErrorMsg << _T("Couldn't get framedata for frame ") << CurFrameNum << _T(": ") << temp; + ErrorMsg.Append(wxString::Format(_T("Couldn't get info about frame %d"), CurFrameNum)); throw ErrorMsg; } @@ -278,19 +315,17 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) // requested format was changed since last time we were called, (re)set output format if (LastDstFormat != DstFormat) { - if (FFMS_SetOutputFormatV(VideoSource, 1 << DstFormat, w, h, FFMS_RESIZER_BICUBIC, FFMSErrorMessage, MessageSize)) { - wxString temp(FFMSErrorMessage, wxConvUTF8); - ErrorMsg << _T("Failed to set output format: ") << temp; + if (FFMS_SetOutputFormatV(VideoSource, 1 << DstFormat, w, h, FFMS_RESIZER_BICUBIC, FFMSErrMsg, MsgSize)) { + ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), FFMSErrMsg)); throw ErrorMsg; } LastDstFormat = DstFormat; } // decode frame - const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrorMessage, MessageSize); + const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrMsg, MsgSize); if (SrcFrame == NULL) { - wxString temp(FFMSErrorMessage, wxConvUTF8); - ErrorMsg << _T("Failed to retrieve frame: ") << temp; + ErrorMsg.Append(wxString::Format(_T("Failed to retrieve frame: %s"), FFMSErrMsg)); throw ErrorMsg; } diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index a568e2877..d0a77ce8a 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -1,4 +1,4 @@ -// Copyright (c) 2008, Karl Blomster +// Copyright (c) 2008-2009, Karl Blomster // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -60,8 +60,8 @@ private: int LastDstFormat; AegiVideoFrame CurFrame; - char FFMSErrorMessage[1024]; - unsigned MessageSize; + char FFMSErrMsg[1024]; + unsigned MsgSize; wxString ErrorMsg; bool COMInited;