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 #endif
FFMS_Init(0); 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: "); ErrorMsg = _T("FFmpegSource audio provider: ");
AudioSource = NULL; AudioSource = NULL;
@ -94,11 +97,11 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
wxString FileNameShort = wxFileName(filename).GetShortPath(); 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) { if (Indexer == NULL) {
// error messages that can possibly contain a filename use this method instead of // error messages that can possibly contain a filename use this method instead of
// wxString::Format because they may contain utf8 characters // 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; throw ErrorMsg;
} }
@ -120,11 +123,11 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
wxString CacheName = GetCacheFilename(filename); wxString CacheName = GetCacheFilename(filename);
// try to read index // try to read index
FFIndex *Index = NULL; FFMS_Index *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), FFMSErrMsg, MsgSize); Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo);
bool IndexIsValid = false; bool IndexIsValid = false;
if (Index != NULL) { if (Index != NULL) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), FFMSErrMsg, MsgSize)) { if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) {
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
Index = NULL; Index = NULL;
} }
@ -136,17 +139,17 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
if (IndexIsValid) { if (IndexIsValid) {
// track number not set? just grab the first track // track number not set? just grab the first track
if (TrackNumber < 0) if (TrackNumber < 0)
TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, FFMSErrMsg, MsgSize); TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &ErrInfo);
if (TrackNumber < 0) { if (TrackNumber < 0) {
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
Index = NULL; 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; throw ErrorMsg;
} }
// index is valid and track number is now set, // index is valid and track number is now set,
// but do we have indexing info for the desired audio track? // 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) { if (FFMS_GetNumFrames(TempTrackData) <= 0) {
IndexIsValid = false; IndexIsValid = false;
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
@ -176,15 +179,15 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
// warn user? // warn user?
} }
AudioSource = FFMS_CreateAudioSource(FileNameShort.utf8_str(), TrackNumber, Index, FFMSErrMsg, MsgSize); AudioSource = FFMS_CreateAudioSource(FileNameShort.utf8_str(), TrackNumber, Index, &ErrInfo);
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
Index = NULL; Index = NULL;
if (!AudioSource) { 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; throw ErrorMsg;
} }
const FFAudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); const FFMS_AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource);
channels = AudioInfo.Channels; channels = AudioInfo.Channels;
sample_rate = AudioInfo.SampleRate; sample_rate = AudioInfo.SampleRate;
@ -233,8 +236,8 @@ void FFmpegSourceAudioProvider::Close() {
/// @param Count /// @param Count
/// ///
void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) { void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) {
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, FFMSErrMsg, MsgSize)) { if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) {
ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), FFMSErrMsg)); ErrorMsg.Append(wxString::Format(_T("Failed to get audio samples: %s"), ErrInfo.Buffer));
throw ErrorMsg; throw ErrorMsg;
} }
} }

View file

@ -41,30 +41,16 @@
#include "ffmpegsource_common.h" #include "ffmpegsource_common.h"
/// DOCME
/// @class FFmpegSourceAudioProvider /// @class FFmpegSourceAudioProvider
/// @brief DOCME /// @brief Implents audio loading with the FFMS library.
///
/// DOCME
class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider { class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider {
private: private:
FFMS_AudioSource *AudioSource; /// audio source object
bool COMInited; /// COM initialization state
/// DOCME char FFMSErrMsg[1024]; /// FFMS error message
FFAudio *AudioSource; FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages
wxString ErrorMsg; /// wx-ified error message
/// DOCME
char FFMSErrMsg[1024];
/// DOCME
unsigned MsgSize;
/// DOCME
wxString ErrorMsg;
/// DOCME
bool COMInited;
void Close(); void Close();
void LoadAudio(wxString filename); void LoadAudio(wxString filename);
@ -73,29 +59,23 @@ public:
FFmpegSourceAudioProvider(wxString filename); FFmpegSourceAudioProvider(wxString filename);
virtual ~FFmpegSourceAudioProvider(); virtual ~FFmpegSourceAudioProvider();
/// @brief Checks sample endianness
/// @brief // FFMS always delivers samples in machine endian /// @return Returns true.
/// @return /// FFMS always delivers native endian samples.
///
bool AreSamplesNativeEndian() { return true; } bool AreSamplesNativeEndian() { return true; }
virtual void GetAudio(void *buf, int64_t start, int64_t count); virtual void GetAudio(void *buf, int64_t start, int64_t count);
}; };
/// DOCME
/// @class FFmpegSourceAudioProviderFactory /// @class FFmpegSourceAudioProviderFactory
/// @brief DOCME /// @brief Creates a FFmpegSource audio provider.
///
/// DOCME
class FFmpegSourceAudioProviderFactory : public AudioProviderFactory { class FFmpegSourceAudioProviderFactory : public AudioProviderFactory {
public: public:
/// @brief Creates a FFmpegSource audio provider.
/// @brief DOCME /// @param video The audio filename to open.
/// @param file /// @return Returns the audio provider.
///
AudioProvider *CreateProvider(wxString file) { return new FFmpegSourceAudioProvider(file); } 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 /// @param IgnoreDecodeErrors True if audio decoding errors will be tolerated, false otherwise
/// @return Returns the index object on success, NULL otherwise /// @return Returns the index object on success, NULL otherwise
/// ///
FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) { FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) {
char FFMSErrMsg[1024]; char FFMSErrMsg[1024];
unsigned MsgSize = sizeof(FFMSErrMsg); FFMS_ErrorInfo ErrInfo;
ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg);
ErrInfo.ErrorType = FFMS_ERROR_SUCCESS;
ErrInfo.SubType = FFMS_ERROR_SUCCESS;
wxString MsgString; wxString MsgString;
// set up progress dialog callback // set up progress dialog callback
@ -97,19 +101,21 @@ FFIndex *FFmpegSourceProvider::DoIndexing(FFIndexer *Indexer, const wxString &Ca
Progress.ProgressDialog->Show(); Progress.ProgressDialog->Show();
Progress.ProgressDialog->SetProgress(0,1); Progress.ProgressDialog->SetProgress(0,1);
int ErrHandling = IgnoreDecodeErrors ? FFMS_IEH_IGNORE : FFMS_IEH_STOP_TRACK;
// index all audio tracks // index all audio tracks
FFIndex *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, IgnoreDecodeErrors, FFMS_Index *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, ErrHandling,
FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrMsg, MsgSize); FFmpegSourceProvider::UpdateIndexingProgress, &Progress, &ErrInfo);
if (Index == NULL) { if (Index == NULL) {
Progress.ProgressDialog->Destroy(); 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; throw MsgString;
} }
Progress.ProgressDialog->Destroy(); Progress.ProgressDialog->Destroy();
// write index to disk for later use // write index to disk for later use
// ignore write errors for now // 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)) { /*if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) {
wxString temp(FFMSErrMsg, wxConvUTF8); wxString temp(FFMSErrMsg, wxConvUTF8);
MsgString << _T("Failed to write index: ") << temp; 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 Indexer The indexer object representing the source file
/// @param Type The track type to look for /// @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. /// @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; std::map<int,wxString> TrackList;
int NumTracks = FFMS_GetNumTracksI(Indexer); 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); static int FFMS_CC UpdateIndexingProgress(int64_t Current, int64_t Total, void *Private);
FFIndex *DoIndexing(FFIndexer *Indexer, const wxString& Cachename, int Trackmask, bool IgnoreDecodeErrors); FFMS_Index *DoIndexing(FFMS_Indexer *Indexer, const wxString& Cachename, int Trackmask, bool IgnoreDecodeErrors);
std::map<int,wxString> GetTracksOfType(FFIndexer *Indexer, FFMS_TrackType Type); std::map<int,wxString> GetTracksOfType(FFMS_Indexer *Indexer, FFMS_TrackType Type);
int AskForTrackSelection(const std::map<int,wxString>& TrackList, FFMS_TrackType Type); int AskForTrackSelection(const std::map<int,wxString>& TrackList, FFMS_TrackType Type);
wxString GetCacheFilename(const wxString& filename); wxString GetCacheFilename(const wxString& filename);
void SetLogLevel(); void SetLogLevel();

View file

@ -61,8 +61,7 @@
/// @brief Constructor /// @brief Constructor
/// @param filename /// @param filename The filename to open
///
FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) { FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
COMInited = false; COMInited = false;
#ifdef WIN32 #ifdef WIN32
@ -81,7 +80,10 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
VideoSource = NULL; VideoSource = NULL;
KeyFramesLoaded = false; KeyFramesLoaded = false;
FrameNumber = -1; 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: "); ErrorMsg = _T("FFmpegSource video provider: ");
SetLogLevel(); SetLogLevel();
@ -97,7 +99,6 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
/// @brief Destructor /// @brief Destructor
///
FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() { FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() {
Close(); Close();
#ifdef WIN32 #ifdef WIN32
@ -107,20 +108,19 @@ FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() {
} }
/// @brief Open video /// @brief Opens video
/// @param filename /// @param filename The filename to open
///
void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// make sure we don't have anything messy lying around // make sure we don't have anything messy lying around
Close(); Close();
wxString FileNameShort = wxFileName(filename).GetShortPath(); 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) { if (Indexer == NULL) {
// error messages that can possibly contain a filename use this method instead of // error messages that can possibly contain a filename use this method instead of
// wxString::Format because they may contain utf8 characters // 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; throw ErrorMsg;
} }
@ -142,11 +142,11 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
wxString CacheName = GetCacheFilename(filename); wxString CacheName = GetCacheFilename(filename);
// try to read index // try to read index
FFIndex *Index = NULL; FFMS_Index *Index = NULL;
Index = FFMS_ReadIndex(CacheName.utf8_str(), FFMSErrMsg, MsgSize); Index = FFMS_ReadIndex(CacheName.utf8_str(), &ErrInfo);
bool IndexIsValid = false; bool IndexIsValid = false;
if (Index != NULL) { if (Index != NULL) {
if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), FFMSErrMsg, MsgSize)) { if (FFMS_IndexBelongsToFile(Index, FileNameShort.utf8_str(), &ErrInfo)) {
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
Index = NULL; 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, // technically this isn't really needed since all video tracks should always be indexed,
// but a bit of sanity checking never hurt anyone // but a bit of sanity checking never hurt anyone
if (IndexIsValid && TrackNumber >= 0) { if (IndexIsValid && TrackNumber >= 0) {
FFTrack *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber);
if (FFMS_GetNumFrames(TempTrackData) <= 0) { if (FFMS_GetNumFrames(TempTrackData) <= 0) {
IndexIsValid = false; IndexIsValid = false;
FFMS_DestroyIndex(Index); 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 // update access time of index file so it won't get cleaned away
if (!wxFileName(CacheName).Touch()) { wxFileName(CacheName).Touch();
// warn user?
// FIND OUT WHY IT'S POPPING UP ERROR MESSAGES HERE
}
// we have now read the index and may proceed with cleaning the index cache // we have now read the index and may proceed with cleaning the index cache
if (!CleanCache()) { if (!CleanCache()) {
@ -194,11 +191,11 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// track number still not set? // track number still not set?
if (TrackNumber < 0) { if (TrackNumber < 0) {
// just grab the first track // 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) { if (TrackNumber < 0) {
FFMS_DestroyIndex(Index); FFMS_DestroyIndex(Index);
Index = NULL; 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; throw ErrorMsg;
} }
} }
@ -216,31 +213,39 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
else else
SeekMode = FFMS_SEEK_NORMAL; 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); FFMS_DestroyIndex(Index);
Index = NULL; Index = NULL;
if (VideoSource == 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; throw ErrorMsg;
} }
// load video properties // load video properties
VideoInfo = FFMS_GetVideoProperties(VideoSource); VideoInfo = FFMS_GetVideoProperties(VideoSource);
if (FFMS_SetOutputFormatV(VideoSource, 1 << FFMS_GetPixFmt("bgra"), VideoInfo->Width, VideoInfo->Height, FFMS_RESIZER_BICUBIC, FFMSErrMsg, MsgSize)) { const FFMS_Frame *TempFrame = FFMS_GetFrame(VideoSource, 0, &ErrInfo);
ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), FFMSErrMsg)); 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; throw ErrorMsg;
} }
// get frame info data // get frame info data
FFTrack *FrameData = FFMS_GetTrackFromVideo(VideoSource); FFMS_Track *FrameData = FFMS_GetTrackFromVideo(VideoSource);
if (FrameData == NULL) if (FrameData == NULL)
throw _T("FFmpegSource video provider: failed to get frame data"); 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) if (TimeBase == NULL)
throw _T("FFmpegSource video provider: failed to get track time base"); throw _T("FFmpegSource video provider: failed to get track time base");
const FFFrameInfo *CurFrameData; const FFMS_FrameInfo *CurFrameData;
// build list of keyframes and timecodes // build list of keyframes and timecodes
for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) { for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) {
@ -307,24 +312,20 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
// set position // set position
FrameNumber = n; FrameNumber = n;
// these are for convenience
// int w = VideoInfo->Width;
// int h = VideoInfo->Height;
// this is what we'll return eventually // this is what we'll return eventually
AegiVideoFrame &DstFrame = CurFrame; AegiVideoFrame &DstFrame = CurFrame;
// decode frame // decode frame
const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrMsg, MsgSize); const FFMS_Frame *SrcFrame = FFMS_GetFrame(VideoSource, n, &ErrInfo);
if (SrcFrame == NULL) { 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; throw ErrorMsg;
} }
// set some properties // set some properties
DstFrame.format = FORMAT_RGB32; DstFrame.format = FORMAT_RGB32;
DstFrame.w = VideoInfo->Width; DstFrame.w = Width;
DstFrame.h = VideoInfo->Height; DstFrame.h = Height;
DstFrame.flipped = false; DstFrame.flipped = false;
DstFrame.invertChannels = true; DstFrame.invertChannels = true;
@ -345,7 +346,7 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
/// @return /// @return
/// ///
int FFmpegSourceVideoProvider::GetWidth() { int FFmpegSourceVideoProvider::GetWidth() {
return VideoInfo->Width; return Width;
} }
@ -353,7 +354,7 @@ int FFmpegSourceVideoProvider::GetWidth() {
/// @return /// @return
/// ///
int FFmpegSourceVideoProvider::GetHeight() { int FFmpegSourceVideoProvider::GetHeight() {
return VideoInfo->Height; return Height;
} }

View file

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