mirror of https://github.com/odrling/Aegisub
More vfr fun for everyone
Originally committed to SVN as r150.
This commit is contained in:
parent
4a13f7844d
commit
a9a4f5bf24
|
@ -221,14 +221,14 @@ void AudioDisplay::UpdateImage(bool weak) {
|
||||||
dc.SetPen(wxPen(wxColour(255,0,255),1));
|
dc.SetPen(wxPen(wxColour(255,0,255),1));
|
||||||
|
|
||||||
// Get min and max frames to care about
|
// Get min and max frames to care about
|
||||||
int minFrame = VFR_Output.CorrectFrameAtTime(GetMSAtX(0),true);
|
int minFrame = VFR_Output.GetFrameAtTime(GetMSAtX(0),true);
|
||||||
int maxFrame = VFR_Output.CorrectFrameAtTime(GetMSAtX(w),true);
|
int maxFrame = VFR_Output.GetFrameAtTime(GetMSAtX(w),true);
|
||||||
|
|
||||||
// Scan list
|
// Scan list
|
||||||
for (int i=0;i<nKeys;i++) {
|
for (int i=0;i<nKeys;i++) {
|
||||||
int cur = video->KeyFrames[i];
|
int cur = video->KeyFrames[i];
|
||||||
if (cur >= minFrame && cur <= maxFrame) {
|
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);
|
dc.DrawLine(x,0,x,h);
|
||||||
}
|
}
|
||||||
else if (cur > maxFrame) break;
|
else if (cur > maxFrame) break;
|
||||||
|
|
|
@ -415,8 +415,8 @@ namespace AutomationHelper {
|
||||||
{
|
{
|
||||||
int ms = (int)lua_tonumber(L, -1);
|
int ms = (int)lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (VFR_Output.loaded) {
|
if (VFR_Output.IsLoaded()) {
|
||||||
lua_pushnumber(L, VFR_Output.CorrectFrameAtTime(ms, true));
|
lua_pushnumber(L, VFR_Output.GetFrameAtTime(ms, true));
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
@ -440,8 +440,8 @@ namespace AutomationHelper {
|
||||||
{
|
{
|
||||||
int frame = (int)lua_tonumber(L, -1);
|
int frame = (int)lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (VFR_Output.loaded) {
|
if (VFR_Output.IsLoaded()) {
|
||||||
lua_pushnumber(L, VFR_Output.CorrectTimeAtFrame(frame, true));
|
lua_pushnumber(L, VFR_Output.GetTimeAtFrame(frame, true));
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
|
|
@ -417,8 +417,8 @@ void BaseGrid::DrawImage(wxDC &dc) {
|
||||||
strings.Add(wxString::Format(_T("%i"),curRow+1));
|
strings.Add(wxString::Format(_T("%i"),curRow+1));
|
||||||
strings.Add(wxString::Format(_T("%i"),curDiag->Layer));
|
strings.Add(wxString::Format(_T("%i"),curDiag->Layer));
|
||||||
if (byFrame) {
|
if (byFrame) {
|
||||||
strings.Add(wxString::Format(_T("%i"),VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true)));
|
strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(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->End.GetMS(),true)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strings.Add(curDiag->Start.GetASSFormated());
|
strings.Add(curDiag->Start.GetASSFormated());
|
||||||
|
@ -776,9 +776,9 @@ void BaseGrid::SetColumnWidths() {
|
||||||
|
|
||||||
// Times
|
// Times
|
||||||
if (byFrame) {
|
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;
|
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;
|
if (tmp > maxEnd) maxEnd = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -849,8 +849,8 @@ AssDialogue *BaseGrid::GetDialogue(int n) {
|
||||||
// Check if line is being displayed
|
// Check if line is being displayed
|
||||||
bool BaseGrid::IsDisplayed(AssDialogue *line) {
|
bool BaseGrid::IsDisplayed(AssDialogue *line) {
|
||||||
if (!video->loaded) return false;
|
if (!video->loaded) return false;
|
||||||
int f1 = VFR_Output.CorrectFrameAtTime(line->Start.GetMS(),true);
|
int f1 = VFR_Output.GetFrameAtTime(line->Start.GetMS(),true);
|
||||||
int f2 = VFR_Output.CorrectFrameAtTime(line->End.GetMS(),false);
|
int f2 = VFR_Output.GetFrameAtTime(line->End.GetMS(),false);
|
||||||
if (f1 <= video->frame_n && f2 >= video->frame_n) return true;
|
if (f1 <= video->frame_n && f2 >= video->frame_n) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ DialogShiftTimes::DialogShiftTimes (wxWindow *parent,SubtitlesGrid *_grid,VideoD
|
||||||
ShiftTime->SetToolTip(_("Enter time in h:mm:ss.cs notation"));
|
ShiftTime->SetToolTip(_("Enter time in h:mm:ss.cs notation"));
|
||||||
RadioTime->SetToolTip(_("Shift by time"));
|
RadioTime->SetToolTip(_("Shift by time"));
|
||||||
ShiftFrame->Disable();
|
ShiftFrame->Disable();
|
||||||
if (!VFR_Output.loaded) RadioFrames->Disable();
|
if (!VFR_Output.IsLoaded()) RadioFrames->Disable();
|
||||||
else {
|
else {
|
||||||
ShiftFrame->SetToolTip(_("Enter number of frames to shift by"));
|
ShiftFrame->SetToolTip(_("Enter number of frames to shift by"));
|
||||||
RadioFrames->SetToolTip(_("Shift by frames"));
|
RadioFrames->SetToolTip(_("Shift by frames"));
|
||||||
|
|
|
@ -200,7 +200,7 @@ void DialogStyling::JumpToLine(int n) {
|
||||||
grid->MakeCellVisible(linen,0);
|
grid->MakeCellVisible(linen,0);
|
||||||
|
|
||||||
// Update display
|
// 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ void DialogTimingProcessor::UpdateControls() {
|
||||||
adjascentThres->Enable(adjsEnable->IsChecked());
|
adjascentThres->Enable(adjsEnable->IsChecked());
|
||||||
|
|
||||||
// Keyframes are only available if timecodes are loaded
|
// Keyframes are only available if timecodes are loaded
|
||||||
bool keysAvailable = VFR_Output.loaded;
|
bool keysAvailable = VFR_Output.IsLoaded();
|
||||||
bool enableKeys = keysEnable->IsChecked() && keysAvailable;
|
bool enableKeys = keysEnable->IsChecked() && keysAvailable;
|
||||||
keysThresOver->Enable(enableKeys);
|
keysThresOver->Enable(enableKeys);
|
||||||
keysThresUnder->Enable(enableKeys);
|
keysThresUnder->Enable(enableKeys);
|
||||||
|
@ -485,21 +485,21 @@ void DialogTimingProcessor::Process() {
|
||||||
cur = GetSortedDialogue(i);
|
cur = GetSortedDialogue(i);
|
||||||
|
|
||||||
// Get start/end frames
|
// Get start/end frames
|
||||||
startF = VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),true);
|
startF = VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true);
|
||||||
endF = VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false);
|
endF = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false);
|
||||||
changed = false;
|
changed = false;
|
||||||
|
|
||||||
// Get closest for start
|
// Get closest for start
|
||||||
closest = GetClosestKeyFrame(startF);
|
closest = GetClosestKeyFrame(startF);
|
||||||
if ((closest > startF && closest-startF <= overThres) || (closest < startF && startF-closest <= underThres)) {
|
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;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get closest for end
|
// Get closest for end
|
||||||
closest = GetClosestKeyFrame(endF)-1;
|
closest = GetClosestKeyFrame(endF)-1;
|
||||||
if ((closest > endF && closest-endF <= overThres) || (closest < endF && endF-closest <= underThres)) {
|
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;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,8 @@ void AssTransformFramerateFilter::Init() {
|
||||||
// Process
|
// Process
|
||||||
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs) {
|
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs) {
|
||||||
// Transform frame rate
|
// Transform frame rate
|
||||||
if (Input->loaded && Output->loaded) {
|
if (Input->IsLoaded() && Output->IsLoaded()) {
|
||||||
if (Output->FrameRateType == VFR || Output->GetAverage() != Input->GetAverage()) {
|
if (Output->GetFrameRateType() == VFR || Output->GetAverage() != Input->GetAverage()) {
|
||||||
TransformFrameRate(subs);
|
TransformFrameRate(subs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
|
||||||
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
|
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
wxString initialInput;
|
wxString initialInput;
|
||||||
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
|
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 {
|
else {
|
||||||
initialInput = _T("23.976");
|
initialInput = _T("23.976");
|
||||||
FromVideo->Enable(false);
|
FromVideo->Enable(false);
|
||||||
|
@ -106,7 +106,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
|
||||||
// Output bottom line
|
// Output bottom line
|
||||||
RadioOutputCFR = new wxRadioButton(base,-1,_("Constant: "));
|
RadioOutputCFR = new wxRadioButton(base,-1,_("Constant: "));
|
||||||
wxString initialOutput = initialInput;
|
wxString initialOutput = initialInput;
|
||||||
if (VFR_Output.FrameRateType != VFR) {
|
if (VFR_Output.GetFrameRateType() != VFR) {
|
||||||
RadioOutputVFR->Enable(false);
|
RadioOutputVFR->Enable(false);
|
||||||
RadioOutputCFR->SetValue(true);
|
RadioOutputCFR->SetValue(true);
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
||||||
AssDialogue *curDialogue;
|
AssDialogue *curDialogue;
|
||||||
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
|
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
|
||||||
curEntry = *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);
|
curDialogue = AssEntry::GetAsDialogue(curEntry);
|
||||||
|
|
||||||
// Update dialogue entries
|
// Update dialogue entries
|
||||||
|
@ -258,8 +258,8 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
||||||
// Process stuff
|
// Process stuff
|
||||||
curDialogue->ParseASSTags();
|
curDialogue->ParseASSTags();
|
||||||
curDialogue->ProcessParameters(TransformTimeTags,&data);
|
curDialogue->ProcessParameters(TransformTimeTags,&data);
|
||||||
curDialogue->Start.SetMS(Input->CorrectTimeAtFrame(Output->CorrectFrameAtTime(curDialogue->Start.GetMS(),true),true));
|
curDialogue->Start.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->Start.GetMS(),true),true));
|
||||||
curDialogue->End.SetMS(Input->CorrectTimeAtFrame(Output->CorrectFrameAtTime(curDialogue->End.GetMS(),false),false));
|
curDialogue->End.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->End.GetMS(),false),false));
|
||||||
curDialogue->UpdateText();
|
curDialogue->UpdateText();
|
||||||
curDialogue->UpdateData();
|
curDialogue->UpdateData();
|
||||||
curDialogue->ClearBlocks();
|
curDialogue->ClearBlocks();
|
||||||
|
|
|
@ -91,8 +91,8 @@ void FrameMain::OnVideoTrackPoints(wxCommandEvent &event) {
|
||||||
// Allocate temp image
|
// Allocate temp image
|
||||||
float* FloatImg = new float[ movie->GetWidth()*movie->GetHeight() ];
|
float* FloatImg = new float[ movie->GetWidth()*movie->GetHeight() ];
|
||||||
|
|
||||||
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
|
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
|
||||||
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
|
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
|
||||||
|
|
||||||
for( int Frame = StartFrame; Frame <= EndFrame; Frame ++ )
|
for( int Frame = StartFrame; Frame <= EndFrame; Frame ++ )
|
||||||
{
|
{
|
||||||
|
@ -152,8 +152,8 @@ void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) {
|
||||||
if( !curline->Movement ) return;
|
if( !curline->Movement ) return;
|
||||||
|
|
||||||
// Create split lines
|
// Create split lines
|
||||||
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
|
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
|
||||||
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
|
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
|
||||||
|
|
||||||
AssFile *subs = AssFile::top;
|
AssFile *subs = AssFile::top;
|
||||||
int ResXValue,ResYValue;
|
int ResXValue,ResYValue;
|
||||||
|
@ -174,8 +174,8 @@ void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) {
|
||||||
// f.Pos.x /= videoBox->videoDisplay->GetW
|
// f.Pos.x /= videoBox->videoDisplay->GetW
|
||||||
|
|
||||||
AssDialogue *cur = new AssDialogue( curline->data );
|
AssDialogue *cur = new AssDialogue( curline->data );
|
||||||
cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,true));
|
cur->Start.SetMS(VFR_Output.GetTimeAtFrame(Frame,true));
|
||||||
cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(Frame,false));
|
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->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();
|
cur->UpdateData();
|
||||||
|
|
||||||
|
|
|
@ -769,7 +769,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
|
||||||
// Check if there is anything to change
|
// Check if there is anything to change
|
||||||
int autoLoadMode = Options.AsInt(_T("Autoload linked files"));
|
int autoLoadMode = Options.AsInt(_T("Autoload linked files"));
|
||||||
bool hasToLoad = false;
|
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;
|
hasToLoad = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +830,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
|
||||||
subs->SetScriptInfo(_T("Video Aspect Ratio"),ar);
|
subs->SetScriptInfo(_T("Video Aspect Ratio"),ar);
|
||||||
subs->SetScriptInfo(_T("Video Zoom"),zoom);
|
subs->SetScriptInfo(_T("Video Zoom"),zoom);
|
||||||
subs->SetScriptInfo(_T("Video Position"),seekpos);
|
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
|
// Create list of Automation scripts
|
||||||
wxString scripts;
|
wxString scripts;
|
||||||
|
@ -857,7 +857,7 @@ void FrameMain::LoadVideo(wxString file,bool autoload) {
|
||||||
if (blockVideoLoad) return;
|
if (blockVideoLoad) return;
|
||||||
videoBox->videoDisplay->Stop();
|
videoBox->videoDisplay->Stop();
|
||||||
try {
|
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);
|
int result = wxMessageBox(_("You have timecodes loaded currently. Would you like to unload them?"), _("Unload timecodes?"), wxYES_NO, this);
|
||||||
if (result == wxYES) {
|
if (result == wxYES) {
|
||||||
VFR_Output.Unload();
|
VFR_Output.Unload();
|
||||||
|
@ -950,8 +950,8 @@ void FrameMain::LoadVFR(wxString filename) {
|
||||||
|
|
||||||
else {
|
else {
|
||||||
VFR_Output.Unload();
|
VFR_Output.Unload();
|
||||||
if (videoBox->videoDisplay->loaded) {
|
if (videoBox->videoDisplay->loaded && !VFR_Output.IsLoaded()) {
|
||||||
VFR_Output.SetCFR(videoBox->videoDisplay->fps,true);
|
VFR_Output.SetCFR(videoBox->videoDisplay->fps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
|
||||||
MenuBar->Enable(Menu_Video_AR_Default,state);
|
MenuBar->Enable(Menu_Video_AR_Default,state);
|
||||||
MenuBar->Enable(Menu_Video_AR_Full,state);
|
MenuBar->Enable(Menu_Video_AR_Full,state);
|
||||||
MenuBar->Enable(Menu_Video_AR_Wide,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
|
// Set AR radio
|
||||||
if (videoBox->videoDisplay->arType == 0) MenuBar->Check(Menu_Video_AR_Default,true);
|
if (videoBox->videoDisplay->arType == 0) MenuBar->Check(Menu_Video_AR_Default,true);
|
||||||
|
@ -834,8 +834,8 @@ void FrameMain::OnSnapToScene (wxCommandEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get times
|
// Get times
|
||||||
int start_ms = VFR_Output.CorrectTimeAtFrame(prev,true);
|
int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
|
||||||
int end_ms = VFR_Output.CorrectTimeAtFrame(next-1,false);
|
int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
|
||||||
AssDialogue *cur;
|
AssDialogue *cur;
|
||||||
|
|
||||||
// Update rows
|
// Update rows
|
||||||
|
@ -865,7 +865,7 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &event) {
|
||||||
// Get shifting in ms
|
// Get shifting in ms
|
||||||
AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
|
AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
|
||||||
if (!cur) return;
|
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
|
// Update
|
||||||
for (int i=0;i<n;i++) {
|
for (int i=0;i<n;i++) {
|
||||||
|
|
|
@ -278,7 +278,7 @@ void SubsEditBox::SetToLine(int n) {
|
||||||
if (Options.AsBool(_T("Sync video with subs")) == true) {
|
if (Options.AsBool(_T("Sync video with subs")) == true) {
|
||||||
video->Stop();
|
video->Stop();
|
||||||
AssDialogue *cur = grid->GetDialogue(n);
|
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
|
// Disables or enables frame timing
|
||||||
void SubsEditBox::UpdateFrameTiming () {
|
void SubsEditBox::UpdateFrameTiming () {
|
||||||
if (VFR_Output.loaded) ByFrame->Enable(enabled);
|
if (VFR_Output.IsLoaded()) ByFrame->Enable(enabled);
|
||||||
else {
|
else {
|
||||||
ByFrame->Enable(false);
|
ByFrame->Enable(false);
|
||||||
ByTime->SetValue(true);
|
ByTime->SetValue(true);
|
||||||
|
|
|
@ -134,7 +134,7 @@ void SubtitlesGrid::OnPopupMenu() {
|
||||||
|
|
||||||
// Duplicate selection
|
// Duplicate selection
|
||||||
menu.Append(MENU_DUPLICATE,_("&Duplicate"),_T("Duplicate the selected lines"))->Enable(continuous);
|
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
|
// Swaps selection
|
||||||
state = (sels == 2);
|
state = (sels == 2);
|
||||||
|
@ -243,7 +243,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate and shift
|
// Duplicate and shift
|
||||||
if (VFR_Output.loaded) {
|
if (VFR_Output.IsLoaded()) {
|
||||||
if (Hotkeys.IsPressed(_T("Grid duplicate and shift one frame"))) {
|
if (Hotkeys.IsPressed(_T("Grid duplicate and shift one frame"))) {
|
||||||
DuplicateLines(n,n2,true);
|
DuplicateLines(n,n2,true);
|
||||||
return;
|
return;
|
||||||
|
@ -379,7 +379,7 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
|
||||||
|
|
||||||
// Create line to add
|
// Create line to add
|
||||||
AssDialogue *def = new AssDialogue;
|
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->Start.SetMS(video_ms);
|
||||||
def->End.SetMS(video_ms+5000);
|
def->End.SetMS(video_ms+5000);
|
||||||
def->Style = GetDialogue(n)->Style;
|
def->Style = GetDialogue(n)->Style;
|
||||||
|
@ -399,7 +399,7 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
|
||||||
|
|
||||||
// Create line to add
|
// Create line to add
|
||||||
AssDialogue *def = new AssDialogue;
|
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->Start.SetMS(video_ms);
|
||||||
def->End.SetMS(video_ms+5000);
|
def->End.SetMS(video_ms+5000);
|
||||||
def->Style = GetDialogue(n)->Style;
|
def->Style = GetDialogue(n)->Style;
|
||||||
|
@ -950,9 +950,9 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
|
||||||
|
|
||||||
// Shift to next frame
|
// Shift to next frame
|
||||||
if (nextFrame) {
|
if (nextFrame) {
|
||||||
int posFrame = VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false) + 1;
|
int posFrame = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false) + 1;
|
||||||
cur->Start.SetMS(VFR_Output.CorrectTimeAtFrame(posFrame,true));
|
cur->Start.SetMS(VFR_Output.GetFrameAtTime(posFrame,true));
|
||||||
cur->End.SetMS(VFR_Output.CorrectTimeAtFrame(posFrame,false));
|
cur->End.SetMS(VFR_Output.GetFrameAtTime(posFrame,false));
|
||||||
cur->UpdateData();
|
cur->UpdateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,9 +1004,9 @@ void SubtitlesGrid::ShiftLineByFrames(int n,int len,int type) {
|
||||||
AssDialogue *cur = GetDialogue(n);
|
AssDialogue *cur = GetDialogue(n);
|
||||||
|
|
||||||
// Start
|
// 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
|
// 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
|
// Update data
|
||||||
cur->UpdateData();
|
cur->UpdateData();
|
||||||
|
@ -1081,10 +1081,10 @@ void SubtitlesGrid::CommitChanges(bool force) {
|
||||||
// Set start to video pos
|
// Set start to video pos
|
||||||
void SubtitlesGrid::SetSubsToVideo(bool start) {
|
void SubtitlesGrid::SetSubsToVideo(bool start) {
|
||||||
// Check if it's OK to do it
|
// Check if it's OK to do it
|
||||||
if (!VFR_Output.loaded) return;
|
if (!VFR_Output.IsLoaded()) return;
|
||||||
|
|
||||||
// Get new time
|
// Get new time
|
||||||
int ms = VFR_Output.CorrectTimeAtFrame(video->frame_n,start);
|
int ms = VFR_Output.GetTimeAtFrame(video->frame_n,start);
|
||||||
|
|
||||||
// Update selection
|
// Update selection
|
||||||
wxArrayInt sel = GetSelection();
|
wxArrayInt sel = GetSelection();
|
||||||
|
@ -1116,7 +1116,9 @@ void SubtitlesGrid::SetVideoToSubs(bool start) {
|
||||||
if (sel.Count() == 0) return;
|
if (sel.Count() == 0) return;
|
||||||
AssDialogue *cur = GetDialogue(sel[0]);
|
AssDialogue *cur = GetDialogue(sel[0]);
|
||||||
if (cur) {
|
if (cur) {
|
||||||
if (start) video->JumpToFrame(VFR_Output.CorrectFrameAtTime(cur->Start.GetMS(),start));
|
if (start)
|
||||||
else video->JumpToFrame(VFR_Output.CorrectFrameAtTime(cur->End.GetMS(),false));
|
video->JumpToFrame(VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true));
|
||||||
|
else
|
||||||
|
video->JumpToFrame(VFR_Output.GetFrameAtTime(cur->End.GetMS(),false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ void TimeEdit::SetByFrame(bool enable) {
|
||||||
|
|
||||||
// By frames
|
// By frames
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (VFR_Output.loaded) {
|
if (VFR_Output.IsLoaded()) {
|
||||||
byFrame = true;
|
byFrame = true;
|
||||||
UpdateText();
|
UpdateText();
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ void TimeEdit::SetByFrame(bool enable) {
|
||||||
void TimeEdit::UpdateText() {
|
void TimeEdit::UpdateText() {
|
||||||
ready = false;
|
ready = false;
|
||||||
if (byFrame) {
|
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));
|
SetValue(wxString::Format(_T("%i"),frame_n));
|
||||||
}
|
}
|
||||||
else SetValue(time.GetASSFormated());
|
else SetValue(time.GetASSFormated());
|
||||||
|
@ -150,7 +150,7 @@ void TimeEdit::Update() {
|
||||||
if (byFrame) {
|
if (byFrame) {
|
||||||
long temp;
|
long temp;
|
||||||
GetValue().ToLong(&temp);
|
GetValue().ToLong(&temp);
|
||||||
time.SetMS(VFR_Output.CorrectTimeAtFrame(temp,!isEnd));
|
time.SetMS(VFR_Output.GetTimeAtFrame(temp,!isEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update modified status
|
// Update modified status
|
||||||
|
|
297
core/vfr.cpp
297
core/vfr.cpp
|
@ -78,19 +78,21 @@ FrameRate::FrameRate() {
|
||||||
//////////////
|
//////////////
|
||||||
// Destructor
|
// Destructor
|
||||||
FrameRate::~FrameRate() {
|
FrameRate::~FrameRate() {
|
||||||
Clear();
|
Unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Gets frame number at time
|
// Gets frame number at time
|
||||||
int FrameRate::GetFrameAtTime(int ms) {
|
int FrameRate::PFrameAtTime(int ms) {
|
||||||
|
//wxASSERT(loaded);
|
||||||
|
|
||||||
if (!loaded) return -1;
|
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) {
|
if (FrameRateType == CFR) {
|
||||||
return floor((double(ms)/1000.0) * AverageFrameRate);
|
return floor(double(ms)/1000.0 * AverageFrameRate);
|
||||||
}
|
}
|
||||||
else if (FrameRateType == VFR) {
|
else if (FrameRateType == VFR) {
|
||||||
if (ms < floor(last_time)) {
|
if (ms < floor(last_time)) {
|
||||||
|
@ -111,8 +113,8 @@ int FrameRate::GetFrameAtTime(int ms) {
|
||||||
if (largerEqual) end = cur-1;
|
if (largerEqual) end = cur-1;
|
||||||
else start = cur+1;
|
else start = cur+1;
|
||||||
}
|
}
|
||||||
} else if (assumefps != 0) {
|
} else {
|
||||||
return last_frame + floor((ms-last_time) * assumefps / 1000);
|
return last_frame + floor((ms-last_time) * AverageFrameRate / 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -121,7 +123,9 @@ int FrameRate::GetFrameAtTime(int ms) {
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// Gets time at frame
|
// Gets time at frame
|
||||||
int FrameRate::GetTimeAtFrame(int frame) {
|
int FrameRate::PTimeAtFrame(int frame) {
|
||||||
|
//wxASSERT(loaded);
|
||||||
|
|
||||||
if (!loaded) return -1;
|
if (!loaded) return -1;
|
||||||
|
|
||||||
wxASSERT(frame >= 0);
|
wxASSERT(frame >= 0);
|
||||||
|
@ -131,8 +135,8 @@ int FrameRate::GetTimeAtFrame(int frame) {
|
||||||
} else if (FrameRateType == VFR) {
|
} else if (FrameRateType == VFR) {
|
||||||
if (frame < last_frame)
|
if (frame < last_frame)
|
||||||
return Frame.at(frame);
|
return Frame.at(frame);
|
||||||
else if (assumefps != 0)
|
else
|
||||||
return floor(last_time + (frame-last_frame+1) / assumefps * 1000);
|
return floor(last_time + double(frame-last_frame) / AverageFrameRate * 1000);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +147,8 @@ int FrameRate::GetTimeAtFrame(int frame) {
|
||||||
void FrameRate::Load(wxString filename) {
|
void FrameRate::Load(wxString filename) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
Unload();
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
wxFileName filetest(filename);
|
wxFileName filetest(filename);
|
||||||
if (!filetest.FileExists()) throw _T("File not found.");
|
if (!filetest.FileExists()) throw _T("File not found.");
|
||||||
|
@ -152,136 +158,139 @@ void FrameRate::Load(wxString filename) {
|
||||||
file.open(filename.mb_str(wxConvLocal));
|
file.open(filename.mb_str(wxConvLocal));
|
||||||
if (!file.is_open()) throw _T("Could not open file.");
|
if (!file.is_open()) throw _T("Could not open file.");
|
||||||
|
|
||||||
//fix me, will b0rk if loading the file fails
|
try {
|
||||||
Unload();
|
|
||||||
|
|
||||||
// Read header
|
// Read header
|
||||||
char buffer[65536];
|
char buffer[65536];
|
||||||
file.getline(buffer,65536);
|
file.getline(buffer,65536);
|
||||||
wxString header(buffer,wxConvUTF8);
|
wxString header(buffer,wxConvUTF8);
|
||||||
|
|
||||||
// V1, code converted from avcvfr9
|
// V1, code converted from avcvfr9
|
||||||
if (header == _T("# timecode format v1")) {
|
if (header == _T("# timecode format v1")) {
|
||||||
//locate the default fps line
|
//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;
|
|
||||||
|
|
||||||
wxString tmp = curLine.AfterFirst(_T(','));
|
while (!file.eof()) {
|
||||||
wxString temp = curLine.BeforeFirst(_T(','));
|
file.getline(buffer,65536);
|
||||||
temp.ToLong(&lstart);
|
wxString curLine(buffer,wxConvUTF8);
|
||||||
temp = tmp.BeforeLast(_T(','));
|
|
||||||
temp.ToLong(&lend);
|
|
||||||
temp = tmp.AfterLast(_T(','));
|
|
||||||
temp.ToDouble(&lfps);
|
|
||||||
|
|
||||||
for (int i = 0; i <= lstart - lposition - 2; i++)
|
//skip empty lines and comments
|
||||||
AddFrame(floor(currenttime+(i*1000) / assumefps));
|
if (curLine == _T("") || curLine.Left(1) == _T("#"))
|
||||||
|
continue;
|
||||||
currenttime += ((lstart - lposition - 1)*1000) / assumefps;
|
//fix me? should be case insensitive comparison
|
||||||
|
else if (curLine.Left(7) != _T("Assume "))
|
||||||
for (int i = 0; i <= lend - lstart; i++)
|
throw _T("Encountered data before 'Assume <fps>' line");
|
||||||
AddFrame(floor(currenttime+(i*1000) / lfps));
|
else {
|
||||||
|
if (!curLine.Mid(6).ToDouble(&AverageFrameRate) || AverageFrameRate <= 0)
|
||||||
currenttime += ((lend - lstart + 1)*1000) / lfps;
|
throw _T("Invalid 'Assume <fps>' line");
|
||||||
|
break;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AddFrame(cftime);
|
//read and expand all timecodes to v2
|
||||||
lftime = cftime;
|
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;
|
// V2
|
||||||
last_frame = Frame.size();
|
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
|
//skip empty lines and comments
|
||||||
else {
|
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();
|
file.close();
|
||||||
Unload();
|
Unload();
|
||||||
throw _T("Unknown file format.");
|
throw;
|
||||||
}
|
|
||||||
|
|
||||||
// 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"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close file
|
// Close file
|
||||||
|
@ -297,7 +306,6 @@ void FrameRate::Load(wxString filename) {
|
||||||
void FrameRate::Unload () {
|
void FrameRate::Unload () {
|
||||||
FrameRateType = NONE;
|
FrameRateType = NONE;
|
||||||
AverageFrameRate = 0;
|
AverageFrameRate = 0;
|
||||||
assumefps = 0;
|
|
||||||
last_time = 0;
|
last_time = 0;
|
||||||
last_frame = 0;
|
last_frame = 0;
|
||||||
Clear();
|
Clear();
|
||||||
|
@ -308,9 +316,7 @@ void FrameRate::Unload () {
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Sets to CFR
|
// Sets to CFR
|
||||||
void FrameRate::SetCFR(double fps,bool ifunset) {
|
void FrameRate::SetCFR(double fps) {
|
||||||
if (loaded && ifunset) return;
|
|
||||||
|
|
||||||
Unload();
|
Unload();
|
||||||
loaded = true;
|
loaded = true;
|
||||||
FrameRateType = CFR;
|
FrameRateType = CFR;
|
||||||
|
@ -339,37 +345,22 @@ void FrameRate::SetVFR(std::vector<int> newTimes) {
|
||||||
// Get correct frame at time
|
// Get correct frame at time
|
||||||
// returns the adjusted time for end frames when start=false
|
// returns the adjusted time for end frames when start=false
|
||||||
// otherwise for start frames
|
// otherwise for start frames
|
||||||
int FrameRate::CorrectFrameAtTime(int ms,bool start) {
|
int FrameRate::GetFrameAtTime(int ms,bool start) {
|
||||||
int frame;
|
if (start)
|
||||||
|
return PFrameAtTime(ms) + 1;
|
||||||
// CFR
|
else
|
||||||
if (FrameRateType == CFR) {
|
return PFrameAtTime(ms);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Get correct time at frame
|
// Get correct time at frame
|
||||||
// compensates and returns an end time when start=false
|
// 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)
|
if (start)
|
||||||
return GetTimeAtFrame(frame);
|
return PTimeAtFrame(frame);
|
||||||
else
|
else
|
||||||
return GetTimeAtFrame(frame+1);
|
return PTimeAtFrame(frame+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
26
core/vfr.h
26
core/vfr.h
|
@ -63,33 +63,37 @@ private:
|
||||||
double last_time;
|
double last_time;
|
||||||
int last_frame;
|
int last_frame;
|
||||||
std::vector<int> 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 AddFrame(int ms);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
void CalcAverage();
|
void CalcAverage();
|
||||||
|
int PFrameAtTime(int ms);
|
||||||
|
int PTimeAtFrame(int frame);
|
||||||
|
|
||||||
|
ASS_FrameRateType FrameRateType;
|
||||||
|
bool loaded;
|
||||||
|
wxString vfrFile;
|
||||||
public:
|
public:
|
||||||
FrameRate();
|
FrameRate();
|
||||||
~FrameRate();
|
~FrameRate();
|
||||||
|
|
||||||
wxString vfrFile;
|
void SetCFR(double fps);
|
||||||
bool loaded;
|
|
||||||
ASS_FrameRateType FrameRateType;
|
|
||||||
|
|
||||||
void SetCFR(double fps,bool ifunset=false);
|
|
||||||
void SetVFR(std::vector<int> times);
|
void SetVFR(std::vector<int> times);
|
||||||
|
|
||||||
|
// Loading always unloads even on failure
|
||||||
void Load(wxString file);
|
void Load(wxString file);
|
||||||
void Unload();
|
void Unload();
|
||||||
int GetFrameAtTime(int ms);
|
int GetFrameAtTime(int ms,bool start=true);
|
||||||
int GetTimeAtFrame(int frame);
|
int GetTimeAtFrame(int frame,bool start=true);
|
||||||
int CorrectFrameAtTime(int ms,bool start);
|
|
||||||
int CorrectTimeAtFrame(int frame,bool start);
|
|
||||||
|
|
||||||
double GetAverage() { return AverageFrameRate; };
|
double GetAverage() { return AverageFrameRate; };
|
||||||
|
bool IsLoaded() { return loaded; };
|
||||||
|
ASS_FrameRateType GetFrameRateType() { return FrameRateType; };
|
||||||
|
wxString GetFilename() { return vfrFile; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ void VideoDisplay::SetVideo(const wxString &filename) {
|
||||||
if (filename.IsEmpty()) {
|
if (filename.IsEmpty()) {
|
||||||
delete provider;
|
delete provider;
|
||||||
provider = NULL;
|
provider = NULL;
|
||||||
if (VFR_Output.FrameRateType == VFR) VFR_Output.Unload();
|
if (VFR_Output.GetFrameRateType() == VFR) VFR_Output.Unload();
|
||||||
VFR_Input.Unload();
|
VFR_Input.Unload();
|
||||||
|
|
||||||
videoName = _T("");
|
videoName = _T("");
|
||||||
|
@ -179,7 +179,7 @@ void VideoDisplay::SetVideo(const wxString &filename) {
|
||||||
|
|
||||||
// Ask to override timecodes
|
// Ask to override timecodes
|
||||||
int override = wxYES;
|
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);
|
if (override == wxYES) mkvwrap.SetToTimecodes(VFR_Output);
|
||||||
|
|
||||||
// Close mkv
|
// Close mkv
|
||||||
|
@ -193,7 +193,9 @@ void VideoDisplay::SetVideo(const wxString &filename) {
|
||||||
length = provider->GetFrameCount();
|
length = provider->GetFrameCount();
|
||||||
fps = provider->GetFPS();
|
fps = provider->GetFPS();
|
||||||
VFR_Input.SetCFR(fps);
|
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
|
// Set range of slider
|
||||||
ControlSlider->SetRange(0,length-1);
|
ControlSlider->SetRange(0,length-1);
|
||||||
|
@ -286,8 +288,8 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
|
||||||
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen);
|
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen);
|
||||||
int StartFrame, EndFrame, localframe;
|
int StartFrame, EndFrame, localframe;
|
||||||
if( curline
|
if( curline
|
||||||
&& (StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true)) <= frame_n
|
&& (StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true)) <= frame_n
|
||||||
&& (EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false)) >= frame_n
|
&& (EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false)) >= frame_n
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
localframe = frame_n - StartFrame;
|
localframe = frame_n - StartFrame;
|
||||||
|
@ -459,7 +461,7 @@ void VideoDisplay::JumpToFrame(int n) {
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// Jumps to a specific time
|
// Jumps to a specific time
|
||||||
void VideoDisplay::JumpToTime(int ms) {
|
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);
|
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen);
|
||||||
if( !curline ) return;
|
if( !curline ) return;
|
||||||
|
|
||||||
int StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
|
int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
|
||||||
int EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
|
int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
|
||||||
|
|
||||||
if( frame_n<StartFrame || frame_n>EndFrame ) return;
|
if( frame_n<StartFrame || frame_n>EndFrame ) return;
|
||||||
|
|
||||||
|
@ -819,8 +821,8 @@ void VideoDisplay::PlayLine() {
|
||||||
|
|
||||||
// Set variables
|
// Set variables
|
||||||
IsPlaying = true;
|
IsPlaying = true;
|
||||||
StartFrame = VFR_Output.CorrectFrameAtTime(curline->Start.GetMS(),true);
|
StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
|
||||||
EndFrame = VFR_Output.CorrectFrameAtTime(curline->End.GetMS(),false);
|
EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
|
||||||
|
|
||||||
// Jump to start
|
// Jump to start
|
||||||
PlayNextFrame = StartFrame;
|
PlayNextFrame = StartFrame;
|
||||||
|
|
|
@ -288,8 +288,8 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
|
||||||
|
|
||||||
// Jump to next sub boundary
|
// Jump to next sub boundary
|
||||||
if (direction != 0) {
|
if (direction != 0) {
|
||||||
int target1 = VFR_Output.CorrectFrameAtTime(curDiag->Start.GetMS(),true);
|
int target1 = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true);
|
||||||
int target2 = VFR_Output.CorrectFrameAtTime(curDiag->End.GetMS(),false);
|
int target2 = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),false);
|
||||||
bool drawn = false;
|
bool drawn = false;
|
||||||
|
|
||||||
// Forward
|
// Forward
|
||||||
|
|
Loading…
Reference in New Issue