diff --git a/aegisub/src/audio_provider_ffmpegsource.cpp b/aegisub/src/audio_provider_ffmpegsource.cpp index 6a121477e..50433db62 100644 --- a/aegisub/src/audio_provider_ffmpegsource.cpp +++ b/aegisub/src/audio_provider_ffmpegsource.cpp @@ -58,7 +58,7 @@ FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(Aegisub::String filename) { else if (res != RPC_E_CHANGED_MODE) throw _T("FFmpegSource video provider: COM initialization failure"); #endif - FFMS_Init(); + FFMS_Init(0); MsgSize = sizeof(FFMSErrMsg); MsgString = _T("FFmpegSource audio provider: "); @@ -85,21 +85,22 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { // generate a default name for the cache file wxString CacheName = GetCacheFilename(filename.c_str()); - FFIndex *Index; - Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrMsg, MsgSize); + FFIndex *Index = NULL; + bool ReIndex = false; + Index = FFMS_ReadIndex(CacheName.mb_str(wxConvUTF8), FFMSErrMsg, MsgSize); if (Index == NULL) { - // index didn't exist or was invalid, we'll have to (re)create it - try { - Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll, false); - } catch (wxString temp) { - MsgString << temp; - throw MsgString; - } catch (...) { - throw; - } - } else { - // index exists, but does it have indexing info for the audio track(s)? + 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) { FFMS_DestroyIndex(Index); Index = NULL; @@ -107,8 +108,9 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { } for (int i = 0; i < NumTracks; i++) { - FFTrack *FrameData = FFMS_GetTrackFromIndex(Index, i); - if (FrameData == NULL) { + FFTrack *TrackData = FFMS_GetTrackFromIndex(Index, i); + // more sanity checking + if (TrackData == NULL) { FFMS_DestroyIndex(Index); Index = NULL; wxString temp(FFMSErrMsg, wxConvUTF8); @@ -117,24 +119,27 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { } // does the track have any indexed frames? - if (FFMS_GetNumFrames(FrameData) <= 0 && (FFMS_GetTrackType(FrameData) == FFMS_TYPE_AUDIO)) { + if (FFMS_GetNumFrames(TrackData) <= 0 && (FFMS_GetTrackType(TrackData) == FFMS_TYPE_AUDIO)) { // found an unindexed audio track, we'll need to reindex - try { - FFMS_DestroyIndex(Index); - Index = NULL; - Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll, false); - } catch (wxString temp) { - MsgString << temp; - throw MsgString; - } catch (...) { - throw; - } - - // don't reindex more than once + FFMS_DestroyIndex(Index); + Index = NULL; + ReIndex = true; break; } } } + + // index didn't exist or was invalid, we'll have to (re)create it + if (ReIndex) { + try { + Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll, false); + } catch (wxString temp) { + MsgString << temp; + throw MsgString; + } catch (...) { + throw; + } + } // update access time of index file so it won't get cleaned away wxFileName(CacheName).Touch(); @@ -149,7 +154,7 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { throw MsgString; } - AudioSource = FFMS_CreateAudioSource(FileNameWX.mb_str(wxConvLocal), TrackNumber, Index, FFMSErrMsg, MsgSize); + AudioSource = FFMS_CreateAudioSource(FileNameWX.mb_str(wxConvUTF8), TrackNumber, Index, FFMSErrMsg, MsgSize); FFMS_DestroyIndex(Index); Index = NULL; if (!AudioSource) { @@ -158,10 +163,7 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { throw MsgString; } - const TAudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); - - if (AudioInfo.Float) - throw _T("FFmpegSource audio provider: I don't know what to do with floating point audio"); + const FFAudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); channels = AudioInfo.Channels; sample_rate = AudioInfo.SampleRate; @@ -169,6 +171,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 // 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; diff --git a/aegisub/src/ffmpegsource_common.cpp b/aegisub/src/ffmpegsource_common.cpp index 3f52e4555..f2be3f12b 100644 --- a/aegisub/src/ffmpegsource_common.cpp +++ b/aegisub/src/ffmpegsource_common.cpp @@ -84,7 +84,7 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndex *Index, wxString FileNameWX, w Progress.ProgressDialog->SetProgress(0,1); // index all audio tracks - Index = FFMS_MakeIndex(FileNameWX.mb_str(wxConvLocal), Trackmask, FFMSTrackMaskNone, NULL, NULL, IgnoreDecodeErrors, FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); + Index = FFMS_MakeIndex(FileNameWX.mb_str(wxConvUTF8), Trackmask, FFMSTrackMaskNone, NULL, NULL, IgnoreDecodeErrors, FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); if (!Index) { Progress.ProgressDialog->Destroy(); wxString temp(FFMSErrMsg, wxConvUTF8); @@ -239,7 +239,7 @@ wxThread::ExitCode FFmpegSourceCacheCleaner::Entry() { if (numfiles <= maxfiles && cursize <= maxsize) { wxLogDebug(_T("FFmpegSourceCacheCleaner: cache does not need cleaning (maxsize=%d, cursize=%d; maxfiles=%d, numfiles=%d), exiting"), - maxsize, cursize, maxfiles, numfiles); + (int)maxsize, (int)cursize, maxfiles, numfiles); return (wxThread::ExitCode)0; } diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index 02e10eab9..247eb4681 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -63,7 +63,8 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(Aegisub::String filename, d throw _T("FFmpegSource video provider: COM initialization failure"); #endif // initialize ffmpegsource - FFMS_Init(); + // FIXME: CPU detection? + FFMS_Init(0); // clean up variables VideoSource = NULL; @@ -99,15 +100,26 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) // make sure we don't have anything messy lying around Close(); - wxString FileNameWX = wxFileName(wxString(filename.c_str(), wxConvFile)).GetShortPath(); + wxString FileNameWX = wxFileName(wxString(filename.c_str(), wxConvFile)).GetShortPath(); // generate a name for the cache file wxString CacheName = GetCacheFilename(filename.c_str()); // try to read index - FFIndex *Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrorMessage, MessageSize); + FFIndex *Index = NULL; + Index = FFMS_ReadIndex(CacheName.mb_str(wxConvUTF8), FFMSErrorMessage, MessageSize); + bool ReIndex = false; if (Index == NULL) { - // index didn't exist or was invalid, we'll have to (re)create it + ReIndex = true; + } + else if (FFMS_IndexBelongsToFile(Index, FileNameWX.mb_str(wxConvUTF8), FFMSErrorMessage, MessageSize)) { + FFMS_DestroyIndex(Index); + Index = NULL; + ReIndex = true; + } + + // index didn't exist or was invalid, we'll have to (re)create it + if (ReIndex) { try { try { // ignore audio decoding errors here, we don't care right now @@ -155,7 +167,7 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) throw ErrorMsg; } - VideoSource = FFMS_CreateVideoSource(FileNameWX.mb_str(wxConvLocal), TrackNumber, Index, "", Threads, SeekMode, FFMSErrorMessage, MessageSize); + VideoSource = FFMS_CreateVideoSource(FileNameWX.mb_str(wxConvUTF8), TrackNumber, Index, "", Threads, SeekMode, FFMSErrorMessage, MessageSize); FFMS_DestroyIndex(Index); Index = NULL; if (VideoSource == NULL) { @@ -171,7 +183,7 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) FFTrack *FrameData = FFMS_GetTrackFromVideo(VideoSource); if (FrameData == NULL) throw _T("FFmpegSource video provider: failed to get frame data"); - const TTrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData); + const FFTrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData); if (TimeBase == NULL) throw _T("FFmpegSource video provider: failed to get track time base"); @@ -191,7 +203,7 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) KeyFramesList.Add(CurFrameNum); // calculate timestamp and add to timecodes vector - int64_t Timestamp = (int64_t)((CurFrameData->DTS * TimeBase->Num) / (double)TimeBase->Den); + int Timestamp = (int)((CurFrameData->DTS * TimeBase->Num) / TimeBase->Den); TimecodesVector.push_back(Timestamp); } KeyFramesLoaded = true; @@ -266,7 +278,7 @@ 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_SetOutputFormat(VideoSource, 1 << DstFormat, w, h, FFMSErrorMessage, MessageSize)) { + 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; throw ErrorMsg; @@ -275,7 +287,7 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) } // decode frame - const TAVFrameLite *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrorMessage, MessageSize); + const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrorMessage, MessageSize); if (SrcFrame == NULL) { wxString temp(FFMSErrorMessage, wxConvUTF8); ErrorMsg << _T("Failed to retrieve frame: ") << temp; diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index a51d42754..a568e2877 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -48,7 +48,7 @@ class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { private: FFVideo *VideoSource; - const TVideoProperties *VideoInfo; + const FFVideoProperties *VideoInfo; int FrameNumber; wxArrayInt KeyFramesList;