forked from mia/Aegisub
add vfr handling (broken) and keyframe reading (works) to the ffmpegsource video provider
Originally committed to SVN as r2312.
This commit is contained in:
parent
1ffa0a95a1
commit
98341f62be
2 changed files with 41 additions and 20 deletions
|
@ -35,13 +35,8 @@
|
|||
|
||||
#ifdef WITH_FFMPEGSOURCE
|
||||
|
||||
#ifdef WIN32
|
||||
#define EMULATE_INTTYPES
|
||||
#endif /* WIN32 */
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include "video_provider_ffmpegsource.h"
|
||||
#include <ffms.h>
|
||||
#include "vfr.h"
|
||||
|
@ -121,29 +116,48 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps)
|
|||
VideoInfo = FFMS_GetVideoProperties(VideoSource);
|
||||
|
||||
// get frame info data
|
||||
// disabled until Myrsloik answers some questions
|
||||
#if 0
|
||||
FrameInfoVector FrameData = FFMS_GetTITrackIndex(Index, -1, FFMSErrorMessage, MessageSize);
|
||||
FrameInfoVector *FrameData = FFMS_GetVSTrackIndex(VideoSource, FFMSErrorMessage, MessageSize);
|
||||
if (FrameData == NULL) {
|
||||
ErrorMsg.Printf(_T("FFmpegSource video provider: %s"), FFMSErrorMessage);
|
||||
throw ErrorMsg;
|
||||
}
|
||||
FrameInfo CurFrameData;
|
||||
const TrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData, FFMSErrorMessage, MessageSize);
|
||||
if (TimeBase == NULL) {
|
||||
ErrorMsg.Printf(_T("FFmpegSource video provider: %s"), FFMSErrorMessage);
|
||||
throw ErrorMsg;
|
||||
}
|
||||
|
||||
// build list of keyframes
|
||||
const FrameInfo *CurFrameData;
|
||||
|
||||
// build list of keyframes and timecodes
|
||||
for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) {
|
||||
CurFrameData = FFMS_GetFrameInfo(FrameData, CurFrameNum, FFMSErrorMessage, MessageSize);
|
||||
if (CurFrameData == NULL) {
|
||||
ErrorMsg.Printf(_T("FFmpegSource video provider: %s"), FFMSErrorMessage);
|
||||
throw ErrorMsg;
|
||||
}
|
||||
if (CurFrameData.KeyFrame)
|
||||
|
||||
// keyframe?
|
||||
if (CurFrameData->KeyFrame)
|
||||
KeyFramesList.Add(CurFrameNum);
|
||||
|
||||
// calculate timestamp and add to timecodes vector
|
||||
int64_t Timestamp = (int64_t)((CurFrameData->DTS * TimeBase->Num) / (double)TimeBase->Den);
|
||||
// dumb to cast this to an int but the vfr functions all want it as that
|
||||
TimecodesVector.push_back(int(Timestamp));
|
||||
}
|
||||
KeyFramesLoaded = true;
|
||||
#endif
|
||||
|
||||
// TODO: VFR handling
|
||||
// override already loaded timecodes?
|
||||
Timecodes.SetVFR(TimecodesVector);
|
||||
int OverrideTC = wxYES;
|
||||
if (VFR_Output.IsLoaded()) {
|
||||
OverrideTC = wxMessageBox(_("You already have timecodes loaded. Would you like to replace them with timecodes from the video file?"), _("Replace timecodes?"), wxYES_NO | wxICON_QUESTION);
|
||||
if (OverrideTC == wxYES) {
|
||||
VFR_Input.SetVFR(TimecodesVector);
|
||||
VFR_Output.SetVFR(TimecodesVector);
|
||||
}
|
||||
}
|
||||
|
||||
// we don't need this anymore
|
||||
FFMS_DestroyFrameIndex(Index);
|
||||
|
@ -168,6 +182,7 @@ void FFmpegSourceVideoProvider::Close() {
|
|||
|
||||
KeyFramesLoaded = false;
|
||||
KeyFramesList.clear();
|
||||
TimecodesVector.clear();
|
||||
FrameNumber = -1;
|
||||
}
|
||||
|
||||
|
@ -191,9 +206,10 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int n, int FormatType)
|
|||
PixelFormat DstFormat;
|
||||
|
||||
switch (FormatType) {
|
||||
case FORMAT_RGB32: DstFormat = PIX_FMT_RGB32; break;
|
||||
case FORMAT_RGB24: DstFormat = PIX_FMT_RGB24; break;
|
||||
// TODO: add YV12?
|
||||
case FORMAT_RGB32: DstFormat = PIX_FMT_RGB32; break;
|
||||
case FORMAT_RGB24: DstFormat = PIX_FMT_RGB24; break;
|
||||
case FORMAT_YV12: DstFormat = PIX_FMT_YUV420P; break; // may or may not work
|
||||
case FORMAT_YUY2: DstFormat = PIX_FMT_YUYV422; break;
|
||||
default: throw _T("FFmpegSource video provider: upstream provider requested unknown or unsupported pixel format");
|
||||
}
|
||||
|
||||
|
@ -217,9 +233,12 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int n, int FormatType)
|
|||
// set some properties
|
||||
DstFrame.w = w;
|
||||
DstFrame.h = h;
|
||||
// only rgb supported for now
|
||||
DstFrame.flipped = false;
|
||||
DstFrame.invertChannels = true;
|
||||
if (FormatType == FORMAT_RGB32 || FormatType == FORMAT_RGB24) {
|
||||
DstFrame.invertChannels = true;
|
||||
} else {
|
||||
DstFrame.invertChannels = false;
|
||||
}
|
||||
DstFrame.format = (VideoFrameFormat)FormatType;
|
||||
|
||||
// allocate destination frame
|
||||
|
|
|
@ -63,6 +63,8 @@ private:
|
|||
int FrameNumber;
|
||||
wxArrayInt KeyFramesList;
|
||||
bool KeyFramesLoaded;
|
||||
std::vector<int> TimecodesVector;
|
||||
FrameRate Timecodes;
|
||||
|
||||
AVPicture FrameRGB;
|
||||
bool FrameAllocated;
|
||||
|
@ -91,8 +93,8 @@ public:
|
|||
double GetFPS();
|
||||
bool AreKeyFramesLoaded() { return KeyFramesLoaded; };
|
||||
wxArrayInt GetKeyFrames() { return KeyFramesList; };
|
||||
bool IsVFR() { return false; }; // FIXME: might want to talk to Myrsloik about this
|
||||
FrameRate GetTrueFrameRate() { return FrameRate(); }; // FIXME: try to remember what this actually means
|
||||
bool IsVFR() { return true; };
|
||||
FrameRate GetTrueFrameRate() { return FrameRate(); };
|
||||
Aegisub::String GetDecoderName() { return L"FFmpegSource"; }
|
||||
bool IsNativelyByFrames() { return true; }
|
||||
int GetDesiredCacheSize() { return 8; }
|
||||
|
|
Loading…
Reference in a new issue