Update ffms providers to use new and improved FFMS API functionality.
Also moved the indexing function to ffmpegsource_common.cpp. Originally committed to SVN as r2387.
This commit is contained in:
parent
666e250265
commit
8ecedcbc2d
4 changed files with 82 additions and 43 deletions
|
@ -76,29 +76,45 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) {
|
||||||
Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrMsg, MsgSize);
|
Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrMsg, MsgSize);
|
||||||
if (Index == NULL) {
|
if (Index == NULL) {
|
||||||
// index didn't exist or was invalid, we'll have to (re)create it
|
// index didn't exist or was invalid, we'll have to (re)create it
|
||||||
IndexingProgressDialog Progress;
|
try {
|
||||||
Progress.IndexingCanceled = false;
|
Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll);
|
||||||
Progress.ProgressDialog = new DialogProgress(NULL, _("Indexing"), &Progress.IndexingCanceled, _("Indexing audio file"), 0, 1);
|
} catch (wxString temp) {
|
||||||
Progress.ProgressDialog->Show();
|
MsgString << temp;
|
||||||
Progress.ProgressDialog->SetProgress(0,1);
|
|
||||||
|
|
||||||
// index all audio tracks
|
|
||||||
Index = FFMS_MakeIndex(FileNameWX.char_str(), FFMSTrackMaskAll, CacheName.char_str(), FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize);
|
|
||||||
if (Index == NULL) {
|
|
||||||
Progress.ProgressDialog->Destroy();
|
|
||||||
wxString temp(FFMSErrMsg, wxConvUTF8);
|
|
||||||
MsgString << _T("failed to index: ") << temp;
|
|
||||||
throw MsgString;
|
throw MsgString;
|
||||||
|
} catch (...) {
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
Progress.ProgressDialog->Destroy();
|
} else {
|
||||||
|
// index exists, but does it have indexing info for the audio track(s)?
|
||||||
|
int NumTracks = FFMS_GetNumTracks(Index, FFMSErrMsg, MsgSize);
|
||||||
|
if (NumTracks <= 0)
|
||||||
|
throw _T("FFmpegSource audio provider: no tracks found in index file");
|
||||||
|
|
||||||
// write index to disk for later use
|
for (int i = 0; i < NumTracks; i++) {
|
||||||
if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) {
|
FrameInfoVector *FrameData = FFMS_GetTITrackIndex(Index, i, FFMSErrMsg, MsgSize);
|
||||||
wxString temp(FFMSErrMsg, wxConvUTF8);
|
if (FrameData == NULL) {
|
||||||
MsgString << _T("failed to write index: ") << temp;
|
wxString temp(FFMSErrMsg, wxConvUTF8);
|
||||||
throw MsgString;
|
MsgString << _T("couldn't get track data: ") << temp;
|
||||||
|
throw MsgString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// does the track have any indexed frames?
|
||||||
|
if (FFMS_GetNumFrames(FrameData, FFMSErrMsg, MsgSize) <= 0 && (FFMS_GetTrackType(FrameData, FFMSErrMsg, MsgSize) == FFMS_TYPE_AUDIO)) {
|
||||||
|
// found an unindexed audio track, we'll need to reindex
|
||||||
|
try {
|
||||||
|
Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll);
|
||||||
|
} catch (wxString temp) {
|
||||||
|
MsgString << temp;
|
||||||
|
throw MsgString;
|
||||||
|
} catch (...) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't reindex more than once
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: provide a way to choose which audio track to load?
|
// FIXME: provide a way to choose which audio track to load?
|
||||||
AudioSource = FFMS_CreateAudioSource(FileNameWX.char_str(), FFMSFirstSuitableTrack, Index, FFMSErrMsg, MsgSize);
|
AudioSource = FFMS_CreateAudioSource(FileNameWX.char_str(), FFMSFirstSuitableTrack, Index, FFMSErrMsg, MsgSize);
|
||||||
|
@ -111,11 +127,13 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) {
|
||||||
const AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource);
|
const AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource);
|
||||||
|
|
||||||
if (AudioInfo.Float)
|
if (AudioInfo.Float)
|
||||||
throw _T("FFmpegSource audio provider: don't know what to do with floating point audio");
|
throw _T("FFmpegSource audio provider: I don't know what to do with floating point audio");
|
||||||
|
|
||||||
channels = AudioInfo.Channels;
|
channels = AudioInfo.Channels;
|
||||||
sample_rate = AudioInfo.SampleRate;
|
sample_rate = AudioInfo.SampleRate;
|
||||||
num_samples = AudioInfo.NumSamples;
|
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");
|
||||||
|
|
||||||
// why not just bits_per_sample/8? maybe there's some oddball format with half bytes out there somewhere...
|
// why not just bits_per_sample/8? maybe there's some oddball format with half bytes out there somewhere...
|
||||||
switch (AudioInfo.BitsPerSample) {
|
switch (AudioInfo.BitsPerSample) {
|
||||||
|
|
|
@ -53,4 +53,39 @@ int __stdcall FFmpegSourceProvider::UpdateIndexingProgress(int State, int64_t Cu
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Do indexing
|
||||||
|
FrameIndex *FFmpegSourceProvider::DoIndexing(FrameIndex *Index, wxString FileNameWX, wxString CacheName, int Trackmask) {
|
||||||
|
char FFMSErrMsg[1024];
|
||||||
|
unsigned MsgSize = sizeof(FFMSErrMsg);
|
||||||
|
wxString MsgString;
|
||||||
|
|
||||||
|
// set up progress dialog callback
|
||||||
|
IndexingProgressDialog Progress;
|
||||||
|
Progress.IndexingCanceled = false;
|
||||||
|
Progress.ProgressDialog = new DialogProgress(NULL, _("Indexing"), &Progress.IndexingCanceled, _("Indexing timecodes and frame/sample data"), 0, 1);
|
||||||
|
Progress.ProgressDialog->Show();
|
||||||
|
Progress.ProgressDialog->SetProgress(0,1);
|
||||||
|
|
||||||
|
// index all audio tracks
|
||||||
|
Index = FFMS_MakeIndex(FileNameWX.char_str(), Trackmask, FFMSTrackMaskNone, NULL, FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize);
|
||||||
|
if (!Index) {
|
||||||
|
Progress.ProgressDialog->Destroy();
|
||||||
|
wxString temp(FFMSErrMsg, wxConvUTF8);
|
||||||
|
MsgString << _T("failed to index: ") << temp;
|
||||||
|
throw MsgString;
|
||||||
|
}
|
||||||
|
Progress.ProgressDialog->Destroy();
|
||||||
|
|
||||||
|
// write index to disk for later use
|
||||||
|
if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) {
|
||||||
|
wxString temp(FFMSErrMsg, wxConvUTF8);
|
||||||
|
MsgString << _T("failed to write index: ") << temp;
|
||||||
|
throw MsgString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Index;
|
||||||
|
}
|
||||||
|
|
||||||
#endif WITH_FFMPEGSOURCE
|
#endif WITH_FFMPEGSOURCE
|
|
@ -54,7 +54,8 @@ public:
|
||||||
DialogProgress *ProgressDialog;
|
DialogProgress *ProgressDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __stdcall FFmpegSourceProvider::UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private);
|
static int __stdcall UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private);
|
||||||
|
FrameIndex *DoIndexing(FrameIndex *Index, wxString Filename, wxString Cachename, int Trackmask);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WITH_FFMPEGSOURCE */
|
#endif /* WITH_FFMPEGSOURCE */
|
|
@ -88,29 +88,14 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps)
|
||||||
// try to read index
|
// try to read index
|
||||||
Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrorMessage, MessageSize);
|
Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrorMessage, MessageSize);
|
||||||
if (Index == NULL) {
|
if (Index == NULL) {
|
||||||
// reading failed, create index
|
// index didn't exist or was invalid, we'll have to (re)create it
|
||||||
// prepare stuff for callback
|
try {
|
||||||
IndexingProgressDialog Progress;
|
Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll);
|
||||||
Progress.IndexingCanceled = false;
|
} catch (wxString temp) {
|
||||||
Progress.ProgressDialog = new DialogProgress(NULL, _("Indexing"), &Progress.IndexingCanceled, _("Reading keyframes and timecodes from video"), 0, 1);
|
ErrorMsg << temp;
|
||||||
Progress.ProgressDialog->Show();
|
|
||||||
Progress.ProgressDialog->SetProgress(0,1);
|
|
||||||
|
|
||||||
// set trackmask to -1 (all) here but don't output any audio file, this allows the audio provider to reuse the index later
|
|
||||||
Index = FFMS_MakeIndex(FileNameWX.char_str(), FFMSTrackMaskAll, CacheName.char_str(), FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrorMessage, MessageSize);
|
|
||||||
if (Index == NULL) {
|
|
||||||
Progress.ProgressDialog->Destroy();
|
|
||||||
wxString temp(FFMSErrorMessage, wxConvUTF8);
|
|
||||||
ErrorMsg << _T("failed to index: ") << temp;
|
|
||||||
throw ErrorMsg;
|
|
||||||
}
|
|
||||||
Progress.ProgressDialog->Destroy();
|
|
||||||
|
|
||||||
// write it to disk
|
|
||||||
if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrorMessage, MessageSize)) {
|
|
||||||
wxString temp(FFMSErrorMessage, wxConvUTF8);
|
|
||||||
ErrorMsg << _T("failed to write index: ") << temp;
|
|
||||||
throw ErrorMsg;
|
throw ErrorMsg;
|
||||||
|
} catch (...) {
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue