More vfr fun for everyone

Originally committed to SVN as r150.
This commit is contained in:
Fredrik Mellbin 2006-02-24 16:45:10 +00:00
parent 4a13f7844d
commit a9a4f5bf24
17 changed files with 235 additions and 236 deletions

View file

@ -221,14 +221,14 @@ void AudioDisplay::UpdateImage(bool weak) {
dc.SetPen(wxPen(wxColour(255,0,255),1));
// Get min and max frames to care about
int minFrame = VFR_Output.CorrectFrameAtTime(GetMSAtX(0),true);
int maxFrame = VFR_Output.CorrectFrameAtTime(GetMSAtX(w),true);
int minFrame = VFR_Output.GetFrameAtTime(GetMSAtX(0),true);
int maxFrame = VFR_Output.GetFrameAtTime(GetMSAtX(w),true);
// Scan list
for (int i=0;i<nKeys;i++) {
int cur = video->KeyFrames[i];
if (cur >= minFrame && cur <= maxFrame) {
int x = GetXAtMS(VFR_Output.CorrectTimeAtFrame(cur,true));
int x = GetXAtMS(VFR_Output.GetTimeAtFrame(cur,true));
dc.DrawLine(x,0,x,h);
}
else if (cur > maxFrame) break;

View file

@ -415,8 +415,8 @@ namespace AutomationHelper {
{
int ms = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
if (VFR_Output.loaded) {
lua_pushnumber(L, VFR_Output.CorrectFrameAtTime(ms, true));
if (VFR_Output.IsLoaded()) {
lua_pushnumber(L, VFR_Output.GetFrameAtTime(ms, true));
return 1;
} else {
lua_pushnil(L);
@ -440,8 +440,8 @@ namespace AutomationHelper {
{
int frame = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
if (VFR_Output.loaded) {
lua_pushnumber(L, VFR_Output.CorrectTimeAtFrame(frame, true));
if (VFR_Output.IsLoaded()) {
lua_pushnumber(L, VFR_Output.GetTimeAtFrame(frame, true));
return 1;
} else {
lua_pushnil(L);

View file

@ -417,8 +417,8 @@ void BaseGrid::DrawImage(wxDC &dc) {
strings.Add(wxString::Format(_T("%i"),curRow+1));
strings.Add(wxString::Format(_T("%i"),curDiag->Layer));
if (byFrame) {
strings.Add(wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true)));
strings.Add(wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(curDiag->End.GetMS(),true)));
strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true)));
strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),true)));
}
else {
strings.Add(curDiag->Start.GetASSFormated());
@ -776,9 +776,9 @@ void BaseGrid::SetColumnWidths() {
// Times
if (byFrame) {
int tmp = VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true);
int tmp = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true);
if (tmp > maxStart) maxStart = tmp;
tmp = VFR_Output.CorrectFrameAtTime(curDiag->End.GetMS(),true);
tmp = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),true);
if (tmp > maxEnd) maxEnd = tmp;
}
}
@ -849,8 +849,8 @@ AssDialogue *BaseGrid::GetDialogue(int n) {
// Check if line is being displayed
bool BaseGrid::IsDisplayed(AssDialogue *line) {
if (!video->loaded) return false;
int f1 = VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true);
int f2 = VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false);
int f1 = VFR_Output.GetFrameAtTime(line->Start.GetMS(),true);
int f2 = VFR_Output.GetFrameAtTime(line->End.GetMS(),false);
if (f1 <= video->frame_n && f2 >= video->frame_n) return true;
return false;
}

View file

@ -69,7 +69,7 @@ DialogShiftTimes::DialogShiftTimes (wxWindow *parent,SubtitlesGrid *_grid,VideoD
ShiftTime->SetToolTip(_("Enter time in h:mm:ss.cs notation"));
RadioTime->SetToolTip(_("Shift by time"));
ShiftFrame->Disable();
if (!VFR_Output.loaded) RadioFrames->Disable();
if (!VFR_Output.IsLoaded()) RadioFrames->Disable();
else {
ShiftFrame->SetToolTip(_("Enter number of frames to shift by"));
RadioFrames->SetToolTip(_("Shift by frames"));

View file

@ -200,7 +200,7 @@ void DialogStyling::JumpToLine(int n) {
grid->MakeCellVisible(linen,0);
// Update display
if (PreviewCheck->IsChecked()) grid->video->JumpToFrame(VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true));
if (PreviewCheck->IsChecked()) grid->video->JumpToFrame(VFR_Output.GetFrameAtTime(line->Start.GetMS(),true));
}

View file

@ -173,7 +173,7 @@ void DialogTimingProcessor::UpdateControls() {
adjascentThres->Enable(adjsEnable->IsChecked());
// Keyframes are only available if timecodes are loaded
bool keysAvailable = VFR_Output.loaded;
bool keysAvailable = VFR_Output.IsLoaded();
bool enableKeys = keysEnable->IsChecked() && keysAvailable;
keysThresOver->Enable(enableKeys);
keysThresUnder->Enable(enableKeys);
@ -485,21 +485,21 @@ void DialogTimingProcessor::Process() {
cur = GetSortedDialogue(i);
// Get start/end frames
startF = VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),true);
endF = VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false);
startF = VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true);
endF = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false);
changed = false;
// Get closest for start
closest = GetClosestKeyFrame(startF);
if ((closest > startF && closest-startF <= overThres) || (closest < startF && startF-closest <= underThres)) {
cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(closest,true));
cur->Start.SetMS(VFR_Output.GetTimeAtFrame(closest,true));
changed = true;
}
// Get closest for end
closest = GetClosestKeyFrame(endF)-1;
if ((closest > endF && closest-endF <= overThres) || (closest < endF && endF-closest <= underThres)) {
cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(closest,false));
cur->End.SetMS(VFR_Output.GetTimeAtFrame(closest,false));
changed = true;
}

View file

@ -67,8 +67,8 @@ void AssTransformFramerateFilter::Init() {
// Process
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs) {
// Transform frame rate
if (Input->loaded && Output->loaded) {
if (Output->FrameRateType == VFR || Output->GetAverage() != Input->GetAverage()) {
if (Input->IsLoaded() && Output->IsLoaded()) {
if (Output->GetFrameRateType() == VFR || Output->GetAverage() != Input->GetAverage()) {
TransformFrameRate(subs);
}
}
@ -84,7 +84,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
wxString initialInput;
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
if (VFR_Input.loaded) initialInput = wxString::Format(_T("%2.3f"),VFR_Input.GetAverage());
if (VFR_Input.IsLoaded()) initialInput = wxString::Format(_T("%2.3f"),VFR_Input.GetAverage());
else {
initialInput = _T("23.976");
FromVideo->Enable(false);
@ -106,7 +106,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
// Output bottom line
RadioOutputCFR = new wxRadioButton(base,-1,_("Constant: "));
wxString initialOutput = initialInput;
if (VFR_Output.FrameRateType != VFR) {
if (VFR_Output.GetFrameRateType() != VFR) {
RadioOutputVFR->Enable(false);
RadioOutputCFR->SetValue(true);
}
@ -243,7 +243,7 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
AssDialogue *curDialogue;
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
curEntry = *cur;
curEntry->StartMS = Input->CorrectTimeAtFrame(Output->CorrectFrameAtTime(curEntry->StartMS,true),true);
curEntry->StartMS = Input->GetTimeAtFrame(Output->GetFrameAtTime(curEntry->StartMS,true),true);
curDialogue = AssEntry::GetAsDialogue(curEntry);
// Update dialogue entries
@ -258,8 +258,8 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
// Process stuff
curDialogue->ParseASSTags();
curDialogue->ProcessParameters(TransformTimeTags,&data);
curDialogue->Start.SetMS(Input->CorrectTimeAtFrame(Output->CorrectFrameAtTime(curDialogue->Start.GetMS(),true),true));
curDialogue->End.SetMS(Input->CorrectTimeAtFrame(Output->CorrectFrameAtTime(curDialogue->End.GetMS(),false),false));
curDialogue->Start.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->Start.GetMS(),true),true));
curDialogue->End.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->End.GetMS(),false),false));
curDialogue->UpdateText();
curDialogue->UpdateData();
curDialogue->ClearBlocks();

View file

@ -91,8 +91,8 @@ void FrameMain::OnVideoTrackPoints(wxCommandEvent &event) {
// Allocate temp image
float* FloatImg = new float[ movie->GetWidth()*movie->GetHeight() ];
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
for( int Frame = StartFrame; Frame <= EndFrame; Frame ++ )
{
@ -152,8 +152,8 @@ void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) {
if( !curline->Movement ) return;
// Create split lines
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
AssFile *subs = AssFile::top;
int ResXValue,ResYValue;
@ -174,8 +174,8 @@ void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) {
// f.Pos.x /= videoBox->videoDisplay->GetW
AssDialogue *cur = new AssDialogue( curline->data );
cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,true));
cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,false));
cur->Start.SetMS(VFR_Output.GetTimeAtFrame(Frame,true));
cur->End.SetMS(VFR_Output.GetTimeAtFrame(Frame,false));
cur->Text = wxString::Format( _T("{\\pos(%.0f,%.0f)\\fscx%.2f\\fscy%.2f}"), f.Pos.x*sx, f.Pos.y*sy, f.Scale.x*100, f.Scale.y*100 ) + cur->Text;
cur->UpdateData();

View file

@ -769,7 +769,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
// Check if there is anything to change
int autoLoadMode = Options.AsInt(_T("Autoload linked files"));
bool hasToLoad = false;
if (curSubsAudio != audioBox->audioName || curSubsVFR != VFR_Output.vfrFile || curSubsVideo != videoBox->videoDisplay->videoName) {
if (curSubsAudio != audioBox->audioName || curSubsVFR != VFR_Output.GetFilename() || curSubsVideo != videoBox->videoDisplay->videoName) {
hasToLoad = true;
}
@ -830,7 +830,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
subs->SetScriptInfo(_T("Video Aspect Ratio"),ar);
subs->SetScriptInfo(_T("Video Zoom"),zoom);
subs->SetScriptInfo(_T("Video Position"),seekpos);
subs->SetScriptInfo(_T("VFR File"),MakeRelativePath(VFR_Output.vfrFile,AssFile::top->filename));
subs->SetScriptInfo(_T("VFR File"),MakeRelativePath(VFR_Output.GetFilename(),AssFile::top->filename));
// Create list of Automation scripts
wxString scripts;
@ -857,7 +857,7 @@ void FrameMain::LoadVideo(wxString file,bool autoload) {
if (blockVideoLoad) return;
videoBox->videoDisplay->Stop();
try {
if (videoBox->videoDisplay->loaded && VFR_Output.FrameRateType == VFR && !autoload) {
if (videoBox->videoDisplay->loaded && VFR_Output.GetFrameRateType() == VFR && !autoload) {
int result = wxMessageBox(_("You have timecodes loaded currently. Would you like to unload them?"), _("Unload timecodes?"), wxYES_NO, this);
if (result == wxYES) {
VFR_Output.Unload();
@ -950,8 +950,8 @@ void FrameMain::LoadVFR(wxString filename) {
else {
VFR_Output.Unload();
if (videoBox->videoDisplay->loaded) {
VFR_Output.SetCFR(videoBox->videoDisplay->fps,true);
if (videoBox->videoDisplay->loaded && !VFR_Output.IsLoaded()) {
VFR_Output.SetCFR(videoBox->videoDisplay->fps);
}
}

View file

@ -263,7 +263,7 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
MenuBar->Enable(Menu_Video_AR_Default,state);
MenuBar->Enable(Menu_Video_AR_Full,state);
MenuBar->Enable(Menu_Video_AR_Wide,state);
MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.loaded && VFR_Output.FrameRateType == VFR); //fix me, wrong?
MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.GetFrameRateType() == VFR); //fix me, wrong?
// Set AR radio
if (videoBox->videoDisplay->arType == 0) MenuBar->Check(Menu_Video_AR_Default,true);
@ -834,8 +834,8 @@ void FrameMain::OnSnapToScene (wxCommandEvent &event) {
}
// Get times
int start_ms = VFR_Output.CorrectTimeAtFrame(prev,true);
int end_ms = VFR_Output.CorrectTimeAtFrame(next-1,false);
int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
AssDialogue *cur;
// Update rows
@ -865,7 +865,7 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &event) {
// Get shifting in ms
AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
if (!cur) return;
int shiftBy = VFR_Output.CorrectTimeAtFrame(videoBox->videoDisplay->frame_n,true) - cur->Start.GetMS();
int shiftBy = VFR_Output.GetTimeAtFrame(videoBox->videoDisplay->frame_n,true) - cur->Start.GetMS();
// Update
for (int i=0;i<n;i++) {

View file

@ -278,7 +278,7 @@ void SubsEditBox::SetToLine(int n) {
if (Options.AsBool(_T("Sync video with subs")) == true) {
video->Stop();
AssDialogue *cur = grid->GetDialogue(n);
if (cur) video->JumpToFrame(VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),true));
if (cur) video->JumpToFrame(VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true));
}
}
}
@ -554,7 +554,7 @@ void SubsEditBox::SetControlsState (bool state) {
////////////////////////////////////
// Disables or enables frame timing
void SubsEditBox::UpdateFrameTiming () {
if (VFR_Output.loaded) ByFrame->Enable(enabled);
if (VFR_Output.IsLoaded()) ByFrame->Enable(enabled);
else {
ByFrame->Enable(false);
ByTime->SetValue(true);

View file

@ -134,7 +134,7 @@ void SubtitlesGrid::OnPopupMenu() {
// Duplicate selection
menu.Append(MENU_DUPLICATE,_("&Duplicate"),_T("Duplicate the selected lines"))->Enable(continuous);
menu.Append(MENU_DUPLICATE_NEXT_FRAME,_("&Duplicate and shift by 1 frame"),_T("Duplicate lines and shift by one frame"))->Enable(continuous && VFR_Output.loaded);
menu.Append(MENU_DUPLICATE_NEXT_FRAME,_("&Duplicate and shift by 1 frame"),_T("Duplicate lines and shift by one frame"))->Enable(continuous && VFR_Output.IsLoaded());
// Swaps selection
state = (sels == 2);
@ -243,7 +243,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
}
// Duplicate and shift
if (VFR_Output.loaded) {
if (VFR_Output.IsLoaded()) {
if (Hotkeys.IsPressed(_T("Grid duplicate and shift one frame"))) {
DuplicateLines(n,n2,true);
return;
@ -379,7 +379,7 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
// Create line to add
AssDialogue *def = new AssDialogue;
int video_ms = VFR_Output.CorrectTimeAtFrame(video->frame_n,true);
int video_ms = VFR_Output.GetTimeAtFrame(video->frame_n,true);
def->Start.SetMS(video_ms);
def->End.SetMS(video_ms+5000);
def->Style = GetDialogue(n)->Style;
@ -399,7 +399,7 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
// Create line to add
AssDialogue *def = new AssDialogue;
int video_ms = VFR_Output.CorrectTimeAtFrame(video->frame_n,true);
int video_ms = VFR_Output.GetTimeAtFrame(video->frame_n,true);
def->Start.SetMS(video_ms);
def->End.SetMS(video_ms+5000);
def->Style = GetDialogue(n)->Style;
@ -950,9 +950,9 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
// Shift to next frame
if (nextFrame) {
int posFrame = VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false) + 1;
cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(posFrame,true));
cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(posFrame,false));
int posFrame = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false) + 1;
cur->Start.SetMS(VFR_Output.GetFrameAtTime(posFrame,true));
cur->End.SetMS(VFR_Output.GetFrameAtTime(posFrame,false));
cur->UpdateData();
}
@ -1004,9 +1004,9 @@ void SubtitlesGrid::ShiftLineByFrames(int n,int len,int type) {
AssDialogue *cur = GetDialogue(n);
// Start
if (type != 2) cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(len + VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),true),true));
if (type != 2) cur->Start.SetMS(VFR_Output.GetTimeAtFrame(len + VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true),true));
// End
if (type != 1) cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(len + VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false),false));
if (type != 1) cur->End.SetMS(VFR_Output.GetTimeAtFrame(len + VFR_Output.GetFrameAtTime(cur->End.GetMS(),false),false));
// Update data
cur->UpdateData();
@ -1081,10 +1081,10 @@ void SubtitlesGrid::CommitChanges(bool force) {
// Set start to video pos
void SubtitlesGrid::SetSubsToVideo(bool start) {
// Check if it's OK to do it
if (!VFR_Output.loaded) return;
if (!VFR_Output.IsLoaded()) return;
// Get new time
int ms = VFR_Output.CorrectTimeAtFrame(video->frame_n,start);
int ms = VFR_Output.GetTimeAtFrame(video->frame_n,start);
// Update selection
wxArrayInt sel = GetSelection();
@ -1116,7 +1116,9 @@ void SubtitlesGrid::SetVideoToSubs(bool start) {
if (sel.Count() == 0) return;
AssDialogue *cur = GetDialogue(sel[0]);
if (cur) {
if (start) video->JumpToFrame(VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),start));
else video->JumpToFrame(VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false));
if (start)
video->JumpToFrame(VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true));
else
video->JumpToFrame(VFR_Output.GetFrameAtTime(cur->End.GetMS(),false));
}
}

View file

@ -104,7 +104,7 @@ void TimeEdit::SetByFrame(bool enable) {
// By frames
if (enable) {
if (VFR_Output.loaded) {
if (VFR_Output.IsLoaded()) {
byFrame = true;
UpdateText();
}
@ -123,7 +123,7 @@ void TimeEdit::SetByFrame(bool enable) {
void TimeEdit::UpdateText() {
ready = false;
if (byFrame) {
int frame_n = VFR_Output.CorrectFrameAtTime(time.GetMS(),!isEnd);
int frame_n = VFR_Output.GetFrameAtTime(time.GetMS(),!isEnd);
SetValue(wxString::Format(_T("%i"),frame_n));
}
else SetValue(time.GetASSFormated());
@ -150,7 +150,7 @@ void TimeEdit::Update() {
if (byFrame) {
long temp;
GetValue().ToLong(&temp);
time.SetMS(VFR_Output.CorrectTimeAtFrame(temp,!isEnd));
time.SetMS(VFR_Output.GetTimeAtFrame(temp,!isEnd));
}
// Update modified status

View file

@ -78,19 +78,21 @@ FrameRate::FrameRate() {
//////////////
// Destructor
FrameRate::~FrameRate() {
Clear();
Unload();
}
/////////////////////////////
// Gets frame number at time
int FrameRate::GetFrameAtTime(int ms) {
int FrameRate::PFrameAtTime(int ms) {
//wxASSERT(loaded);
if (!loaded) return -1;
ms = MAX(ms,0); //fix me, unsafe for CorrectFrame... for frame 0?
ms = MAX(ms,0); //fix me, unsafe for GetFrame... for frame 0?
if (FrameRateType == CFR) {
return floor((double(ms)/1000.0) * AverageFrameRate);
return floor(double(ms)/1000.0 * AverageFrameRate);
}
else if (FrameRateType == VFR) {
if (ms < floor(last_time)) {
@ -111,8 +113,8 @@ int FrameRate::GetFrameAtTime(int ms) {
if (largerEqual) end = cur-1;
else start = cur+1;
}
} else if (assumefps != 0) {
return last_frame + floor((ms-last_time) * assumefps / 1000);
} else {
return last_frame + floor((ms-last_time) * AverageFrameRate / 1000);
}
}
return -1;
@ -121,7 +123,9 @@ int FrameRate::GetFrameAtTime(int ms) {
//////////////////////
// Gets time at frame
int FrameRate::GetTimeAtFrame(int frame) {
int FrameRate::PTimeAtFrame(int frame) {
//wxASSERT(loaded);
if (!loaded) return -1;
wxASSERT(frame >= 0);
@ -131,8 +135,8 @@ int FrameRate::GetTimeAtFrame(int frame) {
} else if (FrameRateType == VFR) {
if (frame < last_frame)
return Frame.at(frame);
else if (assumefps != 0)
return floor(last_time + (frame-last_frame+1) / assumefps * 1000);
else
return floor(last_time + double(frame-last_frame) / AverageFrameRate * 1000);
}
return -1;
}
@ -143,6 +147,8 @@ int FrameRate::GetTimeAtFrame(int frame) {
void FrameRate::Load(wxString filename) {
using namespace std;
Unload();
// Check if file exists
wxFileName filetest(filename);
if (!filetest.FileExists()) throw _T("File not found.");
@ -152,136 +158,139 @@ void FrameRate::Load(wxString filename) {
file.open(filename.mb_str(wxConvLocal));
if (!file.is_open()) throw _T("Could not open file.");
//fix me, will b0rk if loading the file fails
Unload();
try {
// Read header
char buffer[65536];
file.getline(buffer,65536);
wxString header(buffer,wxConvUTF8);
// Read header
char buffer[65536];
file.getline(buffer,65536);
wxString header(buffer,wxConvUTF8);
// V1, code converted from avcvfr9
if (header == _T("# timecode format v1")) {
//locate the default fps line
while (!file.eof()) {
file.getline(buffer,65536);
wxString curLine(buffer,wxConvUTF8);
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
//fix me? should be case insensitive comparison
else if (curLine.Left(7) != _T("Assume "))
throw _T("Encountered data before 'Assume <fps>' line");
else {
curLine.Mid(6).ToDouble(&assumefps);
break;
}
}
//read and expand all timecodes to v2
wxString curline;
double currenttime = 0;
int lposition = -1;
long lstart;
long lend;
double lfps;
while (!file.eof()) {
file.getline(buffer,65536);
wxString curLine(buffer,wxConvUTF8);
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
// V1, code converted from avcvfr9
if (header == _T("# timecode format v1")) {
//locate the default fps line
wxString tmp = curLine.AfterFirst(_T(','));
wxString temp = curLine.BeforeFirst(_T(','));
temp.ToLong(&lstart);
temp = tmp.BeforeLast(_T(','));
temp.ToLong(&lend);
temp = tmp.AfterLast(_T(','));
temp.ToDouble(&lfps);
while (!file.eof()) {
file.getline(buffer,65536);
wxString curLine(buffer,wxConvUTF8);
for (int i = 0; i <= lstart - lposition - 2; i++)
AddFrame(floor(currenttime+(i*1000) / assumefps));
currenttime += ((lstart - lposition - 1)*1000) / assumefps;
for (int i = 0; i <= lend - lstart; i++)
AddFrame(floor(currenttime+(i*1000) / lfps));
currenttime += ((lend - lstart + 1)*1000) / lfps;
lposition = lend;
}
last_time = currenttime;
last_frame = Frame.size();
}
// V2
else if (header == _T("# timecode format v2")) {
// Assigns new VFR file
FrameRateType = VFR;
long lftime = -1;
long cftime = 0;
last_frame = 0;
// Reads body
while (!file.eof()) {
file.getline (buffer,65536);
wxString curLine(buffer,wxConvUTF8);
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
wxString tmp = curLine.BeforeFirst(_T('.'));
tmp.ToLong(&cftime);
if (lftime < cftime) {
file.close();
Unload();
throw _T("Out of order timecodes found");
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
//fix me? should be case insensitive comparison
else if (curLine.Left(7) != _T("Assume "))
throw _T("Encountered data before 'Assume <fps>' line");
else {
if (!curLine.Mid(6).ToDouble(&AverageFrameRate) || AverageFrameRate <= 0)
throw _T("Invalid 'Assume <fps>' line");
break;
}
}
AddFrame(cftime);
lftime = cftime;
//read and expand all timecodes to v2
wxString curline;
double currenttime = 0;
int lposition = -1;
long lstart;
long lend;
double lfps;
while (!file.eof()) {
file.getline(buffer,65536);
wxString curLine(buffer,wxConvUTF8);
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
wxString tmp = curLine.AfterFirst(_T(','));
wxString temp = curLine.BeforeFirst(_T(','));
if (!temp.ToLong(&lstart) || lstart < 0)
throw _T("Timecode parsing error, invalid start format found");
temp = tmp.BeforeLast(_T(','));
if (!temp.ToLong(&lend) || lend < 0)
throw _T("Timecode parsing error, invalid end format found");
temp = tmp.AfterLast(_T(','));
if (!temp.ToDouble(&lfps) || lfps <= 0)
throw _T("Timecode parsing error, invalid fps format found");
for (int i = 0; i <= lstart - lposition - 2; i++)
AddFrame(floor(currenttime+(i*1000) / AverageFrameRate));
currenttime += ((lstart - lposition - 1)*1000) / AverageFrameRate;
for (int i = 0; i <= lend - lstart; i++)
AddFrame(floor(currenttime+(i*1000) / lfps));
currenttime += ((lend - lstart + 1)*1000) / lfps;
lposition = lend;
}
last_time = currenttime;
last_frame = Frame.size();
}
last_time = cftime;
last_frame = Frame.size();
// V2
else if (header == _T("# timecode format v2")) {
// Assigns new VFR file
FrameRateType = VFR;
CalcAverage();
long lftime = -1;
long cftime = 0;
last_frame = 0;
}
// Reads body
while (!file.eof()) {
file.getline (buffer,65536);
wxString curLine(buffer,wxConvUTF8);
// Unknown
else {
//skip empty lines and comments
if (curLine == _T("") || curLine.Left(1) == _T("#"))
continue;
wxString tmp = curLine.BeforeFirst(_T('.'));
tmp.ToLong(&cftime);
if (lftime >= cftime)
throw _T("Out of order/too close timecodes found");
AddFrame(cftime);
lftime = cftime;
}
last_time = cftime;
last_frame = Frame.size();
CalcAverage();
}
// Unknown
else
throw _T("Unknown file format.");
// Run test
/*bool doTest = false;
if (doTest) {
int fail = 0;
int res;
for (int i=0;i<1000;i++) {
res = GetFrameAtTime(GetTimeAtFrame(i));
if (res != i) {
wxLogMessage(wxString::Format(_T("Expected %i but got %i (%i)"),i,res,GetTimeAtFrame(i)));
fail++;
}
}
if (fail) wxLogMessage(wxString::Format(_T("Failed %i times"),fail));
else wxLogMessage(_T("VFR passes test"));
}*/
} catch (wchar_t *) {
file.close();
Unload();
throw _T("Unknown file format.");
}
// Run test
bool doTest = false;
if (doTest) {
int fail = 0;
int res;
for (int i=0;i<1000;i++) {
res = GetFrameAtTime(GetTimeAtFrame(i));
if (res != i) {
wxLogMessage(wxString::Format(_T("Expected %i but got %i (%i)"),i,res,GetTimeAtFrame(i)));
fail++;
}
}
if (fail) wxLogMessage(wxString::Format(_T("Failed %i times"),fail));
else wxLogMessage(_T("VFR passes test"));
throw;
}
// Close file
@ -297,7 +306,6 @@ void FrameRate::Load(wxString filename) {
void FrameRate::Unload () {
FrameRateType = NONE;
AverageFrameRate = 0;
assumefps = 0;
last_time = 0;
last_frame = 0;
Clear();
@ -308,9 +316,7 @@ void FrameRate::Unload () {
///////////////
// Sets to CFR
void FrameRate::SetCFR(double fps,bool ifunset) {
if (loaded && ifunset) return;
void FrameRate::SetCFR(double fps) {
Unload();
loaded = true;
FrameRateType = CFR;
@ -339,37 +345,22 @@ void FrameRate::SetVFR(std::vector<int> newTimes) {
// Get correct frame at time
// returns the adjusted time for end frames when start=false
// otherwise for start frames
int FrameRate::CorrectFrameAtTime(int ms,bool start) {
int frame;
// CFR
if (FrameRateType == CFR) {
int delta = 0;
if (start) delta = 1;
frame = GetFrameAtTime(ms-delta)+delta;
int time = GetTimeAtFrame(frame);
if (start && time < ms) frame++;
if (!start && time > ms) frame--;
}
// VFR
else {
frame = GetFrameAtTime(ms);
if (!start) frame--;
}
return frame;
int FrameRate::GetFrameAtTime(int ms,bool start) {
if (start)
return PFrameAtTime(ms) + 1;
else
return PFrameAtTime(ms);
}
/////////////////////////////
// Get correct time at frame
// compensates and returns an end time when start=false
int FrameRate::CorrectTimeAtFrame(int frame,bool start) {
int FrameRate::GetTimeAtFrame(int frame,bool start) {
if (start)
return GetTimeAtFrame(frame);
return PTimeAtFrame(frame);
else
return GetTimeAtFrame(frame+1);
return PTimeAtFrame(frame+1);
}

View file

@ -63,33 +63,37 @@ private:
double last_time;
int last_frame;
std::vector<int> Frame;
double assumefps;
double AverageFrameRate;
// contains the assumed fps for v1 timecodes, average for v2 and actual fps for cfr
double AverageFrameRate;
void AddFrame(int ms);
void Clear();
void CalcAverage();
int PFrameAtTime(int ms);
int PTimeAtFrame(int frame);
ASS_FrameRateType FrameRateType;
bool loaded;
wxString vfrFile;
public:
FrameRate();
~FrameRate();
wxString vfrFile;
bool loaded;
ASS_FrameRateType FrameRateType;
void SetCFR(double fps,bool ifunset=false);
void SetCFR(double fps);
void SetVFR(std::vector<int> times);
// Loading always unloads even on failure
void Load(wxString file);
void Unload();
int GetFrameAtTime(int ms);
int GetTimeAtFrame(int frame);
int CorrectFrameAtTime(int ms,bool start);
int CorrectTimeAtFrame(int frame,bool start);
int GetFrameAtTime(int ms,bool start=true);
int GetTimeAtFrame(int frame,bool start=true);
double GetAverage() { return AverageFrameRate; };
bool IsLoaded() { return loaded; };
ASS_FrameRateType GetFrameRateType() { return FrameRateType; };
wxString GetFilename() { return vfrFile; };
};

View file

@ -143,7 +143,7 @@ void VideoDisplay::SetVideo(const wxString &filename) {
if (filename.IsEmpty()) {
delete provider;
provider = NULL;
if (VFR_Output.FrameRateType == VFR) VFR_Output.Unload();
if (VFR_Output.GetFrameRateType() == VFR) VFR_Output.Unload();
VFR_Input.Unload();
videoName = _T("");
@ -179,7 +179,7 @@ void VideoDisplay::SetVideo(const wxString &filename) {
// Ask to override timecodes
int override = wxYES;
if (VFR_Output.FrameRateType == VFR) override = wxMessageBox(_T("You already have timecodes loaded. Replace them with the timecodes from the Matroska file?"),_T("Replace timecodes?"),wxYES_NO | wxICON_QUESTION);
if (VFR_Output.GetFrameRateType() == VFR) override = wxMessageBox(_T("You already have timecodes loaded. Replace them with the timecodes from the Matroska file?"),_T("Replace timecodes?"),wxYES_NO | wxICON_QUESTION);
if (override == wxYES) mkvwrap.SetToTimecodes(VFR_Output);
// Close mkv
@ -193,7 +193,9 @@ void VideoDisplay::SetVideo(const wxString &filename) {
length = provider->GetFrameCount();
fps = provider->GetFPS();
VFR_Input.SetCFR(fps);
if (!VFR_Output.loaded) VFR_Output.SetCFR(fps,true);
if (!VFR_Output.IsLoaded())
VFR_Output.SetCFR(fps);
// Set range of slider
ControlSlider->SetRange(0,length-1);
@ -286,8 +288,8 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen);
int StartFrame, EndFrame, localframe;
if( curline
&& (StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true)) <= frame_n
&& (EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false)) >= frame_n
&& (StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true)) <= frame_n
&& (EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false)) >= frame_n
)
{
localframe = frame_n - StartFrame;
@ -459,7 +461,7 @@ void VideoDisplay::JumpToFrame(int n) {
////////////////////////////
// Jumps to a specific time
void VideoDisplay::JumpToTime(int ms) {
JumpToFrame(VFR_Output.CorrectFrameAtTime(ms,true));
JumpToFrame(VFR_Output.GetFrameAtTime(ms));
}
@ -637,8 +639,8 @@ void VideoDisplay::DrawTrackingOverlay( wxDC &dc )
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen);
if( !curline ) return;
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
if( frame_n<StartFrame || frame_n>EndFrame ) return;
@ -819,8 +821,8 @@ void VideoDisplay::PlayLine() {
// Set variables
IsPlaying = true;
StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
// Jump to start
PlayNextFrame = StartFrame;

View file

@ -288,8 +288,8 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
// Jump to next sub boundary
if (direction != 0) {
int target1 = VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true);
int target2 = VFR_Output.CorrectFrameAtTime(curDiag->End.GetMS(),false);
int target1 = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true);
int target2 = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),false);
bool drawn = false;
// Forward