Updating ffms2 to r221 (2.12), step 3/3: Aegisub interface

Originally committed to SVN as r3576.
This commit is contained in:
Karl Blomster 2009-09-26 21:58:00 +00:00
parent 6e39199cb4
commit 9d80eb066f
6 changed files with 116 additions and 169 deletions

View File

@ -68,7 +68,10 @@ FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(wxString filename) {
#endif
FFMS_Init(0);
MsgSize = sizeof(FFMSErrMsg);
ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg);
ErrInfo.ErrorType = FFMS_ERROR_SUCCESS;
ErrInfo.SubType = FFMS_ERROR_SUCCESS;
ErrorMsg = _T("FFmpegSource audio provider: ");
AudioSource = NULL;
@ -94,11 +97,11 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
wxString FileNameShort = wxFileName(filename).GetShortPath();
FFIndexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), FFMSErrMsg, MsgSize);
FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo);
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));
ErrorMsg.Append(_T("Failed to create indexer: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8));
throw ErrorMsg;
}
@ -120,11 +123,11 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
wxString CacheName = GetCacheFilename(filename);
// try to read index
FFIndex *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), FFMSErrMsg, MsgSize);
FFMS_Index *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo);
bool IndexIsValid = false;
if (Index != NULL) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), FFMSErrMsg, MsgSize)) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) {
FFMS_DestroyIndex(Index);
Index = NULL;
}
@ -136,17 +139,17 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
if (IndexIsValid) {
// track number not set? just grab the first track
if (TrackNumber < 0)
TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, FFMSErrMsg, MsgSize);
TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &ErrInfo);
if (TrackNumber < 0) {
FFMS_DestroyIndex(Index);
Index = NULL;
ErrorMsg.Append(wxString::Format(_T("Couldn't find any audio tracks: %s"), FFMSErrMsg));
ErrorMsg.Append(wxString::Format(_T("Couldn't find any audio tracks: %s"), ErrInfo.Buffer));
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);
FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber);
if (FFMS_GetNumFrames(TempTrackData) <= 0) {
IndexIsValid = false;
FFMS_DestroyIndex(Index);
@ -176,15 +179,15 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
// warn user?
}
AudioSource = FFMS_CreateAudioSource(FileNameShort.utf8_str(), TrackNumber, Index, FFMSErrMsg, MsgSize);
AudioSource = FFMS_CreateAudioSource(FileNameShort.utf8_str(), TrackNumber, Index, &ErrInfo);
FFMS_DestroyIndex(Index);
Index = NULL;
if (!AudioSource) {
ErrorMsg.Append(wxString::Format(_T("Failed to open audio track: %s"), FFMSErrMsg));
ErrorMsg.Append(wxString::Format(_T("Failed to open audio track: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
const FFAudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource);
const FFMS_AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource);
channels = AudioInfo.Channels;
sample_rate = AudioInfo.SampleRate;
@ -233,8 +236,8 @@ void FFmpegSourceAudioProvider::Close() {
/// @param Count
///
void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) {
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, FFMSErrMsg, MsgSize)) {
ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), FFMSErrMsg));
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) {
ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
}

View File

@ -41,30 +41,16 @@
#include "ffmpegsource_common.h"
/// DOCME
/// @class FFmpegSourceAudioProvider
/// @brief DOCME
///
/// DOCME
/// @brief Implents audio loading with the FFMS library.
class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider {
private:
FFMS_AudioSource *AudioSource; /// audio source object
bool COMInited; /// COM initialization state
/// DOCME
FFAudio *AudioSource;
/// DOCME
char FFMSErrMsg[1024];
/// DOCME
unsigned MsgSize;
/// DOCME
wxString ErrorMsg;
/// DOCME
bool COMInited;
char FFMSErrMsg[1024]; /// FFMS error message
FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages
wxString ErrorMsg; /// wx-ified error message
void Close();
void LoadAudio(wxString filename);
@ -73,29 +59,23 @@ public:
FFmpegSourceAudioProvider(wxString filename);
virtual ~FFmpegSourceAudioProvider();
/// @brief // FFMS always delivers samples in machine endian
/// @return
///
/// @brief Checks sample endianness
/// @return Returns true.
/// FFMS always delivers native endian samples.
bool AreSamplesNativeEndian() { return true; }
virtual void GetAudio(void *buf, int64_t start, int64_t count);
};
/// DOCME
/// @class FFmpegSourceAudioProviderFactory
/// @brief DOCME
///
/// DOCME
/// @brief Creates a FFmpegSource audio provider.
class FFmpegSourceAudioProviderFactory : public AudioProviderFactory {
public:
/// @brief DOCME
/// @param file
///
/// @brief Creates a FFmpegSource audio provider.
/// @param video The audio filename to open.
/// @return Returns the audio provider.
AudioProvider *CreateProvider(wxString file) { return new FFmpegSourceAudioProvider(file); }
};

View File

@ -84,9 +84,13 @@ int FFMS_CC FFmpegSourceProvider::UpdateIndexingProgress(int64_t Current, int64_
/// @param IgnoreDecodeErrors True if audio decoding errors will be tolerated, false otherwise
/// @return Returns the index object on success, NULL otherwise
///
FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) {
char FFMSErrMsg[1024];
unsigned MsgSize = sizeof(FFMSErrMsg);
FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) {
char FFMSErrMsg[1024];
FFMS_ErrorInfo ErrInfo;
ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg);
ErrInfo.ErrorType = FFMS_ERROR_SUCCESS;
ErrInfo.SubType = FFMS_ERROR_SUCCESS;
wxString MsgString;
// set up progress dialog callback
@ -97,19 +101,21 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &Ca
Progress.ProgressDialog->Show();
Progress.ProgressDialog->SetProgress(0,1);
int ErrHandling = IgnoreDecodeErrors ? FFMS_IEH_IGNORE : FFMS_IEH_STOP_TRACK;
// index all audio tracks
FFIndex *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, IgnoreDecodeErrors,
FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize);
FFMS_Index *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, ErrHandling,
FFmpegSourceProvider::UpdateIndexingProgress, &Progress, &ErrInfo);
if (Index == NULL) {
Progress.ProgressDialog->Destroy();
MsgString.Append(_T("Failed to index: ")).Append(wxString(FFMSErrMsg, wxConvUTF8));
MsgString.Append(_T("Failed to index: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8));
throw MsgString;
}
Progress.ProgressDialog->Destroy();
// write index to disk for later use
// ignore write errors for now
FFMS_WriteIndex(CacheName.utf8_str(), Index, FFMSErrMsg, MsgSize);
FFMS_WriteIndex(CacheName.utf8_str(), Index, &ErrInfo);
/*if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) {
wxString temp(FFMSErrMsg, wxConvUTF8);
MsgString << _T("Failed to write index: ") << temp;
@ -125,7 +131,7 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &Ca
/// @param Indexer The indexer object representing the source file
/// @param Type The track type to look for
/// @return Returns a std::map with the track numbers as keys and the codec names as values.
std::map<int,wxString> FFmpegSourceProvider::GetTracksOfType(FFIndexer *Indexer, FFMS_TrackType Type) {
std::map<int,wxString> FFmpegSourceProvider::GetTracksOfType(FFMS_Indexer *Indexer, FFMS_TrackType Type) {
std::map<int,wxString> TrackList;
int NumTracks = FFMS_GetNumTracksI(Indexer);

View File

@ -87,8 +87,8 @@ public:
static int FFMS_CC UpdateIndexingProgress(int64_t Current, int64_t Total, void *Private);
FFIndex *DoIndexing(FFIndexer *Indexer, const wxString& Cachename, int Trackmask, bool IgnoreDecodeErrors);
std::map<int,wxString> GetTracksOfType(FFIndexer *Indexer, FFMS_TrackType Type);
FFMS_Index *DoIndexing(FFMS_Indexer *Indexer, const wxString& Cachename, int Trackmask, bool IgnoreDecodeErrors);
std::map<int,wxString> GetTracksOfType(FFMS_Indexer *Indexer, FFMS_TrackType Type);
int AskForTrackSelection(const std::map<int,wxString>& TrackList, FFMS_TrackType Type);
wxString GetCacheFilename(const wxString& filename);
void SetLogLevel();

View File

@ -61,8 +61,7 @@
/// @brief Constructor
/// @param filename
///
/// @param filename The filename to open
FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
COMInited = false;
#ifdef WIN32
@ -81,7 +80,10 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
VideoSource = NULL;
KeyFramesLoaded = false;
FrameNumber = -1;
MsgSize = sizeof(FFMSErrMsg);
ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg);
ErrInfo.ErrorType = FFMS_ERROR_SUCCESS;
ErrInfo.SubType = FFMS_ERROR_SUCCESS;
ErrorMsg = _T("FFmpegSource video provider: ");
SetLogLevel();
@ -97,7 +99,6 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
/// @brief Destructor
///
FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() {
Close();
#ifdef WIN32
@ -107,20 +108,19 @@ FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() {
}
/// @brief Open video
/// @param filename
///
/// @brief Opens video
/// @param filename The filename to open
void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// make sure we don't have anything messy lying around
Close();
wxString FileNameShort = wxFileName(filename).GetShortPath();
FFIndexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), FFMSErrMsg, MsgSize);
FFMS_Indexer *Indexer = FFMS_CreateIndexer(FileNameShort.utf8_str(), &ErrInfo);
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));
ErrorMsg.Append(_T("Failed to create indexer: ")).Append(wxString(ErrInfo.Buffer, wxConvUTF8));
throw ErrorMsg;
}
@ -142,11 +142,11 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
wxString CacheName = GetCacheFilename(filename);
// try to read index
FFIndex *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), FFMSErrMsg, MsgSize);
FFMS_Index *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo);
bool IndexIsValid = false;
if (Index != NULL) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), FFMSErrMsg, MsgSize)) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) {
FFMS_DestroyIndex(Index);
Index = NULL;
}
@ -158,7 +158,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// 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);
FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber);
if (FFMS_GetNumFrames(TempTrackData) <= 0) {
IndexIsValid = false;
FFMS_DestroyIndex(Index);
@ -181,10 +181,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
}
// update access time of index file so it won't get cleaned away
if (!wxFileName(CacheName).Touch()) {
// warn user?
// FIND OUT WHY IT'S POPPING UP ERROR MESSAGES HERE
}
wxFileName(CacheName).Touch();
// we have now read the index and may proceed with cleaning the index cache
if (!CleanCache()) {
@ -194,11 +191,11 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// track number still not set?
if (TrackNumber < 0) {
// just grab the first track
TrackNumber = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, FFMSErrMsg, MsgSize);
TrackNumber = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, &ErrInfo);
if (TrackNumber < 0) {
FFMS_DestroyIndex(Index);
Index = NULL;
ErrorMsg.Append(wxString::Format(_T("Couldn't find any video tracks: %s"), FFMSErrMsg));
ErrorMsg.Append(wxString::Format(_T("Couldn't find any video tracks: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
}
@ -216,31 +213,39 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
else
SeekMode = FFMS_SEEK_NORMAL;
VideoSource = FFMS_CreateVideoSource(FileNameShort.utf8_str(), TrackNumber, Index, "", Threads, SeekMode, FFMSErrMsg, MsgSize);
VideoSource = FFMS_CreateVideoSource(FileNameShort.utf8_str(), TrackNumber, Index, Threads, SeekMode, &ErrInfo);
FFMS_DestroyIndex(Index);
Index = NULL;
if (VideoSource == NULL) {
ErrorMsg.Append(wxString::Format(_T("Failed to open video track: %s"), FFMSErrMsg));
ErrorMsg.Append(wxString::Format(_T("Failed to open video track: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
// load video properties
VideoInfo = FFMS_GetVideoProperties(VideoSource);
if (FFMS_SetOutputFormatV(VideoSource, 1 << FFMS_GetPixFmt("bgra"), VideoInfo->Width, VideoInfo->Height, FFMS_RESIZER_BICUBIC, FFMSErrMsg, MsgSize)) {
ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), FFMSErrMsg));
const FFMS_Frame *TempFrame = FFMS_GetFrame(VideoSource, 0, &ErrInfo);
if (TempFrame == NULL) {
ErrorMsg.Append(wxString::Format(_T("Failed to decode first frame: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
Width = TempFrame->EncodedWidth;
Height = TempFrame->EncodedHeight;
if (FFMS_SetOutputFormatV(VideoSource, 1 << FFMS_GetPixFmt("bgra"), Width, Height, FFMS_RESIZER_BICUBIC, &ErrInfo)) {
ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
// get frame info data
FFTrack *FrameData = FFMS_GetTrackFromVideo(VideoSource);
FFMS_Track *FrameData = FFMS_GetTrackFromVideo(VideoSource);
if (FrameData == NULL)
throw _T("FFmpegSource video provider: failed to get frame data");
const FFTrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData);
const FFMS_TrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData);
if (TimeBase == NULL)
throw _T("FFmpegSource video provider: failed to get track time base");
const FFFrameInfo *CurFrameData;
const FFMS_FrameInfo *CurFrameData;
// build list of keyframes and timecodes
for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) {
@ -306,25 +311,21 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
n = GetFrameCount()-1;
// set position
FrameNumber = n;
// these are for convenience
// int w = VideoInfo->Width;
// int h = VideoInfo->Height;
// this is what we'll return eventually
AegiVideoFrame &DstFrame = CurFrame;
// decode frame
const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrMsg, MsgSize);
const FFMS_Frame *SrcFrame = FFMS_GetFrame(VideoSource, n, &ErrInfo);
if (SrcFrame == NULL) {
ErrorMsg.Append(wxString::Format(_T("Failed to retrieve frame: %s"), FFMSErrMsg));
ErrorMsg.Append(wxString::Format(_T("Failed to retrieve frame: %s"), ErrInfo.Buffer));
throw ErrorMsg;
}
// set some properties
DstFrame.format = FORMAT_RGB32;
DstFrame.w = VideoInfo->Width;
DstFrame.h = VideoInfo->Height;
DstFrame.w = Width;
DstFrame.h = Height;
DstFrame.flipped = false;
DstFrame.invertChannels = true;
@ -345,7 +346,7 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
/// @return
///
int FFmpegSourceVideoProvider::GetWidth() {
return VideoInfo->Width;
return Width;
}
@ -353,7 +354,7 @@ int FFmpegSourceVideoProvider::GetWidth() {
/// @return
///
int FFmpegSourceVideoProvider::GetHeight() {
return VideoInfo->Height;
return Height;
}

View File

@ -46,59 +46,31 @@
#include "vfr.h"
/// DOCME
/// @class FFmpegSourceVideoProvider
/// @brief DOCME
///
/// DOCME
/// @brief Implements video loading through the FFMS library.
class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider {
private:
FFMS_VideoSource *VideoSource; /// video source object
const FFMS_VideoProperties *VideoInfo; /// video properties
/// DOCME
FFVideo *VideoSource;
/// DOCME
const FFVideoProperties *VideoInfo;
/// DOCME
int FrameNumber;
/// DOCME
wxArrayInt KeyFramesList;
/// DOCME
bool KeyFramesLoaded;
/// DOCME
std::vector<int> TimecodesVector;
/// DOCME
FrameRate Timecodes;
/// DOCME
AegiVideoFrame CurFrame;
/// DOCME
char FFMSErrMsg[1024];
/// DOCME
unsigned MsgSize;
/// DOCME
wxString ErrorMsg;
/// DOCME
bool COMInited;
int Width; /// width in pixels
int Height; /// height in pixels
int FrameNumber; /// current framenumber
wxArrayInt KeyFramesList; /// list of keyframes
bool KeyFramesLoaded; /// keyframe loading state
std::vector<int> TimecodesVector; /// list of timestamps
FrameRate Timecodes; /// vfr object
bool COMInited; /// COM initialization state
AegiVideoFrame CurFrame; /// current video frame
char FFMSErrMsg[1024]; /// FFMS error message
FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages
wxString ErrorMsg; /// wx-ified error message
void LoadVideo(wxString filename);
void Close();
protected:
public:
FFmpegSourceVideoProvider(wxString filename);
~FFmpegSourceVideoProvider();
@ -111,50 +83,35 @@ public:
int GetHeight();
double GetFPS();
/// @brief DOCME
/// @return
///
/// @brief Reports keyframe status
/// @return Returns true if keyframes are loaded, false otherwise.
bool AreKeyFramesLoaded() { return KeyFramesLoaded; };
/// @brief DOCME
/// @return
///
/// @brief Gets a list of keyframes
/// @return Returns a wxArrayInt of keyframes.
wxArrayInt GetKeyFrames() { return KeyFramesList; };
/// @brief DOCME
/// @return
///
/// @brief Checks if source is VFR
/// @return Returns true.
bool IsVFR() { return true; };
/// @brief DOCME
/// @return
///
/// @brief Gets a VFR framerate object
/// @return Returns the framerate object.
FrameRate GetTrueFrameRate() { return Timecodes; };
/// @brief DOCME
/// @return
///
/// @brief Gets the name of the provider
/// @return Returns "FFmpegSource".
wxString GetDecoderName() { return L"FFmpegSource"; }
/// @brief DOCME
/// @return
///
/// @brief Gets the number of frames to cache.
/// @return Returns 8.
int GetDesiredCacheSize() { return 8; }
};
/// DOCME
/// @class FFmpegSourceVideoProviderFactory
/// @brief DOCME
///
/// DOCME
/// @brief Creates a FFmpegSource video provider.
class FFmpegSourceVideoProviderFactory : public VideoProviderFactory {
public:
/// @brief DOCME
/// @param video
///
/// @brief Creates a FFmpegSource video provider.
/// @param video The video filename to open.
/// @return Returns the video provider.
VideoProvider *CreateProvider(wxString video) { return new FFmpegSourceVideoProvider(video); }
};