Skip to content
Extraits de code Groupes Projets
Valider 8ecedcbc rédigé par Karl Blomster's avatar Karl Blomster
Parcourir les fichiers

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.
parent 666e2502
Branches
Étiquettes
Aucune requête de fusion associée trouvée
...@@ -76,27 +76,43 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { ...@@ -76,27 +76,43 @@ 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); throw MsgString;
} catch (...) {
// index all audio tracks throw;
Index = FFMS_MakeIndex(FileNameWX.char_str(), FFMSTrackMaskAll, CacheName.char_str(), FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); }
if (Index == NULL) { } else {
Progress.ProgressDialog->Destroy(); // 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");
for (int i = 0; i < NumTracks; i++) {
FrameInfoVector *FrameData = FFMS_GetTITrackIndex(Index, i, FFMSErrMsg, MsgSize);
if (FrameData == NULL) {
wxString temp(FFMSErrMsg, wxConvUTF8); wxString temp(FFMSErrMsg, wxConvUTF8);
MsgString << _T("failed to index: ") << temp; MsgString << _T("couldn't get track data: ") << temp;
throw MsgString; throw MsgString;
} }
Progress.ProgressDialog->Destroy();
// write index to disk for later use // does the track have any indexed frames?
if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) { if (FFMS_GetNumFrames(FrameData, FFMSErrMsg, MsgSize) <= 0 && (FFMS_GetTrackType(FrameData, FFMSErrMsg, MsgSize) == FFMS_TYPE_AUDIO)) {
wxString temp(FFMSErrMsg, wxConvUTF8); // found an unindexed audio track, we'll need to reindex
MsgString << _T("failed to write index: ") << temp; try {
Index = DoIndexing(Index, FileNameWX, CacheName, FFMSTrackMaskAll);
} catch (wxString temp) {
MsgString << temp;
throw MsgString; throw MsgString;
} catch (...) {
throw;
}
// don't reindex more than once
break;
}
} }
} }
...@@ -111,11 +127,13 @@ void FFmpegSourceAudioProvider::LoadAudio(Aegisub::String filename) { ...@@ -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 ...@@ -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
\ No newline at end of file
...@@ -54,7 +54,8 @@ public: ...@@ -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 */
\ No newline at end of file
...@@ -88,29 +88,14 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) ...@@ -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;
} }
} }
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter