mirror of https://github.com/odrling/Aegisub
Updating ffms2 to r221 (2.12), step 3/3: Aegisub interface
Originally committed to SVN as r3576.
This commit is contained in:
parent
6e39199cb4
commit
9d80eb066f
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const wxString &CacheName, int Trackmask, bool IgnoreDecodeErrors) {
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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++) {
|
||||
|
@ -307,24 +312,20 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
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
|
||||
|
||||
/// DOCME
|
||||
const FFVideoProperties *VideoInfo;
|
||||
AegiVideoFrame CurFrame; /// current video frame
|
||||
|
||||
|
||||
/// 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;
|
||||
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); }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue